4. 常见TLS漏洞与攻击面归纳总结

说实话,做了这么多年安全审计,我最大的感受是:TLS 并不是一把万能锁。它可能配置得很严,也可能在某个细节上出岔子。今天我就把那些常见的坑、经典的漏洞和攻击面好好捋一捋。

4.1 协议层面的老毛病

先看协议本身。早期的 SSL 和 TLS 1.0/1.1 已经明确被废弃了,为什么还有人在用?有时候是兼容性妥协,有时候是觉得「关了就出问题」。

  • POODLE (CVE-2014-3566) — 针对 SSL 3.0 的填充 Oracle 攻击。我曾经在一个银行系统的内网审计里发现某个旧负载均衡器仍开着 SSL 3.0,当时吓得赶紧让他们下线。
  • FREAK (CVE-2015-0204) — 利用 EXPORT 级密码套件降级至 512 位 RSA。说白了就是中间人强迫客户端和服务器用弱密钥。
  • Logjam (CVE-2015-4000) — 将 Diffie-Hellman 密钥交换降级到 512 位。
注意: 客户端和服务端都维护着「可接受的协议版本列表」。审计时一定要确认双方都已禁用 TLS 1.0/1.1,并且不支持 SSL 3.0 及以下版本。

4.2 证书验证的踩坑点

证书验证是 TLS 安全的核心,但也是出错最多的地方。我多少次见过客户端代码里写 VERIFY_NONE 或者干脆不验证主机名。

问题典型表现常见场景
自签名证书未加入信任锚,浏览器弹出警告内部开发环境、测试应用
签名算法太弱使用 SHA-1 或 MD5 签名的证书老旧 CA 签发的证书、过期证书
主机名不匹配证书 CN/SAN 与访问域名不一致多租户场景、配置错误
证书链不完整服务器未发送中间证书Nginx/Apache 配置缺失

你想想看,中间人要伪造证书最常利用哪个?就是主机名验证缺失。我曾经审计过一个物联网设备,它的 TLS 库直接跳过了域名检查,结果任何合法签名的证书都能冒充它的服务器。

避坑指南: 我曾经在审计移动端 SDK 时发现客户端只校验了证书的 issuer,却没校验 subject。攻击者只要弄到一个从任何受信 CA 签发的证书就能发起中间人攻击。所以一定要做全链路验证:信任锚 + 证书链 + 主机名 + 有效期 + 撤销状态。

4.3 密码套件那些事

配置密码套件就像搭积木——选错了块,整个结构就垮了。

  • RC4 — 早就被证实在密钥流中有偏差,多个攻击(如 RC4 NOMORE)可以直接算出明文。
  • CBC 模式 — BEAST、Lucky13,都是针对 CBC 模式的时序旁路攻击。我建议非必要别碰 CBC,优先 GCM 或 ChaCha20-Poly1305。
  • NULL 或 EXPORT 级套件 — 没有任何加密强度,明文传输。
# 以 OpenSSL 1.1.1 为例,推荐的高安全性密码套件配置
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

注意,上面没有 TLSv1.2 以下的任何套件。你也可以通过 openssl ciphers -V 查看当前支持的列表。

4.4 实现层面的经典漏洞

协议和配置没问题,但实现代码也可能出大问题。最有代表性的就是 Heartbleed (CVE-2014-0160)——OpenSSL 心跳扩展的缓冲区越界读取,直接泄露服务器的内存数据,包括私钥。那次事件之后我意识到,就算你配置再对,底层库有洞也白搭。

其他需要留意的实现漏洞:

  • ROBOT (CVE-2017-17381) — 用于 RSA 密钥交换的 Oracle 攻击,某些服务器还存在私钥复用问题。
  • 混乱中间人(DROWN) — 如果服务器同时支持 SSLv2(其实早该禁了),攻击者可利用 SSLv2 的弱加密强度来破解 TLS 连接。
  • 会话 Tickets 泄露 — 某些实现把 Session Ticket 加密密钥硬编码或弱随机化,导致会话劫持。

4.5 攻击面三维模型

为了更系统地看问题,我习惯把 TLS 中间人攻击面分成三个维度。下面的图可以帮你快速建立全景认识。

TLS中间人攻击面三维模型 协议层 POODLE / FREAK / Logjam 版本回退 / 密码套件降级 证书层 自签名 / 弱签名 / 主机名不匹配 证书链不完整 / 撤销检查缺失 实现层 Heartbleed / ROBOT / 混乱代理 Session Ticket泄露 / 随机数重用 攻击可跨层叠加

这三层不是孤立的。比如协议降级(协议层)之后,攻击者可以更轻松地伪造证书(证书层),或者利用实现漏洞(实现层)直接窃取私钥。

4.6 实战审计中的速查清单

嗯,最后我给一份自己经常用的审计速查表,你拿去查漏补缺很实用。

  1. 确认服务端只支持 TLS 1.2 / 1.3,禁用 SSL 2/3 和 TLS 1.0/1.1。
  2. 检查证书链是否完整,并验证证书撤销状态(OCSP Stapling 或 CRL)。
  3. 确认客户端(App、SDK、脚本)是否开启了主机名验证和证书链验证。
  4. 扫描密码套件,确保排除了 RC4、EXPORT、NULL、CBC 模式(除非万不得已且知道风险)。
  5. 检查是否启用了不必要的扩展:Session Tickets、Renegotiation、Beast 缓解等。
  6. 针对开源 TLS 库(OpenSSL、GnuTLS、MbedTLS)确认版本是否修补了已知 CVE。
小工具推荐: 用 sslyze 或 testssl.sh 可以自动化大部分检查。我每次审计都会跑一遍 testssl.sh --full 目标IP,输出报告直接能看出协议、密码套件、证书的漏洞。

总结一句话:TLS 安全不是配完证书就完了。协议、配置、实现,每一层都可能成为中间人的突破口。你想想看,如果这三层都掌握好了,攻击者能下手的地方就少得多了。