CVE-2020-1967: OpenSSL SSL_check_chain 拒绝服务漏洞分析
0x00 漏洞背景与详情
- 漏洞名称:OpenSSL SSL_check_chain 函数空指针解引用漏洞
- CVE 编号:CVE-2020-1967
- 影响组件:OpenSSL (libssl)
- 影响版本:OpenSSL 1.1.1d, 1.1.1e, 1.1.1f
- 漏洞等级:高危 (CVSS 3.1 评分: 7.5)
- 核心风险:远程拒绝服务 (DoS)
在 OpenSSL 1.1.1d/e/f 版本中,SSL_check_chain 函数在处理特定的 TLS 扩展时存在逻辑缺陷。如果攻击者在 TLS 握手过程中发送了精心构造的扩展数据,会导致 OpenSSL 进程触发内存段错误(SIGSEGV)并立刻崩溃。
0x01 漏洞原理分析
- 触发位置:漏洞位于
ssl/t1_lib.c源代码文件中的SSL_check_chain函数内。该函数主要用于在 TLS 握手期间检查对端发送的证书链是否与本地支持的签名算法兼容。 - 核心缺陷:
- 在 TLS 1.3 规范中引入了两个相关的扩展:
signature_algorithms和signature_algorithms_cert。 - 当
SSL_check_chain被调用时,它会查找对端支持的签名算法。 - 逻辑错误:如果对端(客户端或服务端)在 Hello 包中发送了
signature_algorithms_cert扩展,但没有发送signature_algorithms扩展,OpenSSL 的内部处理逻辑会错误地认为某些数据结构已完成初始化。 - 随后,代码在尝试解引用一个预期的“签名算法列表”指针时,由于该指针实际上为
NULL,直接导致 NULL Pointer Dereference (空指针解引用),从而触发操作系统的SIGSEGV信号导致进程异常终止。
- 在 TLS 1.3 规范中引入了两个相关的扩展:
0x02 漏洞 POC 与利用场景
POC 逻辑示意
触发该漏洞不需要复杂的溢出或内存布局控制,只需满足 TLS 握手的特定扩展组合:
- 构造包:在
ClientHello或ServerHello阶段,构造一个包含signature_algorithms_cert扩展但缺少signature_algorithms扩展的数据包。 - 触发点:当受害目标调用
SSL_check_chain(通常在验证对端证书链时自动触发)时,进程立即崩溃。
利用案例
- 恶意客户端攻击 Web 服务器:攻击者向支持客户端证书认证(Mutual TLS)的 Web 服务器发起请求,发送畸形握手包,导致处理该请求的服务器 Worker 进程或主进程崩溃。
- 恶意服务端反向攻击:如果一个自动化爬虫、Curl 脚本或集成客户端连接到恶意服务端,服务端下发特制握手包,可直接导致客户端程序异常退出。
0x03 高级利用姿势 (DoS 场景)
虽然该漏洞无法直接实现远程代码执行(RCE),但在复杂的网络对抗环境中,其 DoS 效果极佳且隐蔽:
- 单兵武器化 (Point-of-Crash): 攻击者只需发送一个约 200 字节的 TLS 握手数据包,即可令目标服务进程瞬间下线。这种非对称的攻击成本使得其非常适合作为 DDoS 攻击的一部分。
- 多进程/线程模型下的稳定性破坏:
- 多进程模型 (如 Nginx/Apache):虽然单个 Worker 进程崩溃后 master 进程会自动重启它,但攻击者可以通过持续的高并发攻击(Spray),耗尽服务器的进程创建资源,造成持续的业务瘫痪 (502/504 错误)。
- 单线程异步模型 (如 Node.js):如果服务端底层依赖受影响的 OpenSSL,一旦触发,整个 Node 服务直接停摆,且可能导致未持久化的数据丢失。
- 绕过 WAF/IDS: 由于该漏洞发生在 TLS 握手的加密协商阶段,传统的应用层 WAF(通常只能检测解密后的 HTTP 报文)无法感知恶意扩展包的内容,具有极强的网络隐蔽性。
0x04 应急排查与修复建议
1. 环境排查
- 版本检查:在服务器上执行命令
openssl version。- 受影响:
1.1.1d,1.1.1e,1.1.1f。 - 不受影响:
1.1.1之前的版本(如 1.0.2)、1.1.1至1.1.1c,以及1.1.1g之后版本。
- 受影响:
- 二进制定位:检查系统中所有动态链接到
libssl.so.1.1的核心组件(如 Nginx, Python, HAProxy)。
2. 日志痕迹分析
- 内核日志:由于是段错误,应用日志中往往没有记录,需搜索系统日志
dmesg或/var/log/syslog。 - Core Dump:如果系统开启了 core dump,提取 dump 文件使用
gdb查看堆栈,确认崩溃点是否在SSL_check_chain。
3. 修复建议
- 升级版本(推荐):将 OpenSSL 升级到官方修复版本 1.1.1g 或更高版本。各大 Linux 发行版均已在 2020 年 4 月推送了针对此漏洞的安全更新,可通过
apt upgrade openssl或yum update openssl进行修复。