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 漏洞原理分析

  1. 触发位置:漏洞位于 ssl/t1_lib.c 源代码文件中的 SSL_check_chain 函数内。该函数主要用于在 TLS 握手期间检查对端发送的证书链是否与本地支持的签名算法兼容。
  2. 核心缺陷
    • 在 TLS 1.3 规范中引入了两个相关的扩展:signature_algorithmssignature_algorithms_cert
    • SSL_check_chain 被调用时,它会查找对端支持的签名算法。
    • 逻辑错误:如果对端(客户端或服务端)在 Hello 包中发送了 signature_algorithms_cert 扩展,但没有发送 signature_algorithms 扩展,OpenSSL 的内部处理逻辑会错误地认为某些数据结构已完成初始化。
    • 随后,代码在尝试解引用一个预期的“签名算法列表”指针时,由于该指针实际上为 NULL,直接导致 NULL Pointer Dereference (空指针解引用),从而触发操作系统的 SIGSEGV 信号导致进程异常终止。

0x02 漏洞 POC 与利用场景

POC 逻辑示意

触发该漏洞不需要复杂的溢出或内存布局控制,只需满足 TLS 握手的特定扩展组合:

  1. 构造包:在 ClientHelloServerHello 阶段,构造一个包含 signature_algorithms_cert 扩展但缺少 signature_algorithms 扩展的数据包。
  2. 触发点:当受害目标调用 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.11.1.1c,以及 1.1.1g 之后版本。
  • 二进制定位:检查系统中所有动态链接到 libssl.so.1.1 的核心组件(如 Nginx, Python, HAProxy)。

2. 日志痕迹分析

  • 内核日志:由于是段错误,应用日志中往往没有记录,需搜索系统日志 dmesg/var/log/syslog
    # 典型痕迹
    nginx[1234]: segfault at 0 ip 00007f... sp 00007f... error 4 in libssl.so.1.1
  • Core Dump:如果系统开启了 core dump,提取 dump 文件使用 gdb 查看堆栈,确认崩溃点是否在 SSL_check_chain

3. 修复建议

  • 升级版本(推荐):将 OpenSSL 升级到官方修复版本 1.1.1g 或更高版本。各大 Linux 发行版均已在 2020 年 4 月推送了针对此漏洞的安全更新,可通过 apt upgrade opensslyum update openssl 进行修复。

0x05 参考资料