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 中间人攻击面分成三个维度。下面的图可以帮你快速建立全景认识。
这三层不是孤立的。比如协议降级(协议层)之后,攻击者可以更轻松地伪造证书(证书层),或者利用实现漏洞(实现层)直接窃取私钥。
4.6 实战审计中的速查清单
嗯,最后我给一份自己经常用的审计速查表,你拿去查漏补缺很实用。
- 确认服务端只支持 TLS 1.2 / 1.3,禁用 SSL 2/3 和 TLS 1.0/1.1。
- 检查证书链是否完整,并验证证书撤销状态(OCSP Stapling 或 CRL)。
- 确认客户端(App、SDK、脚本)是否开启了主机名验证和证书链验证。
- 扫描密码套件,确保排除了 RC4、EXPORT、NULL、CBC 模式(除非万不得已且知道风险)。
- 检查是否启用了不必要的扩展:Session Tickets、Renegotiation、Beast 缓解等。
- 针对开源 TLS 库(OpenSSL、GnuTLS、MbedTLS)确认版本是否修补了已知 CVE。
小工具推荐: 用
sslyze 或 testssl.sh 可以自动化大部分检查。我每次审计都会跑一遍 testssl.sh --full 目标IP,输出报告直接能看出协议、密码套件、证书的漏洞。
总结一句话:TLS 安全不是配完证书就完了。协议、配置、实现,每一层都可能成为中间人的突破口。你想想看,如果这三层都掌握好了,攻击者能下手的地方就少得多了。