降级攻击 (Downgrade Attack)
定义
降级攻击是指攻击者迫使客户端和服务器协商出比双方实际支持的更旧的协议版本或更弱的算法,从而利用其中的弱点。
降级攻击中,中间人篡改协商过程,让双方退而求其次:用 SSL 3.0 而不是 TLS 1.2,用出口级(export-grade)弱密钥而不是强密钥,甚至干脆不用 TLS。著名的例子有利用浏览器回退到 SSL 3.0 的 POODLE,以及强迫使用出口级 RSA、DH 密钥的 FREAK 和 Logjam。SSL 剥离和 STARTTLS 剥离则是从加密连接降级到明文连接。
为什么重要
为了兼容而保留旧协议,安全与否取决于能否防止被“逼”到旧协议上。现在已有多层防护:握手在 Finished 消息中对整个过程做认证,只要协商出的算法够强,篡改就会被发现;TLS_FALLBACK_SCSV(RFC 7507)阻止了攻击者利用浏览器“失败后用旧版本重试”的行为;TLS 1.3 服务器在协商 TLS 1.2 及以下版本时,会在 ServerHello.random 末尾写入固定标记,支持 TLS 1.3 的客户端据此识别被强制回退。最可靠的办法仍然是关掉用不到的东西:SSL 3.0(RFC 7568)、TLS 1.0 和 1.1(RFC 8996),以及出口级等弱密码套件。漏洞扫描和渗透测试报告中常见的“支持不安全的 TLS 版本”问题,修复思路也是如此。
例子
# 加固后的服务器会拒绝(新版 OpenSSL 本地也可能直接拒绝 TLS 1.1)
openssl s_client -connect example.com:443 -servername example.com -tls1_1 </dev/null
# 列出服务器提供的所有协议版本和密码套件
nmap --script ssl-enum-ciphers -p 443 example.com
常见误区
- 客户端总会选最高版本,保留旧版本无害。 这只在降级防护有效时成立,而 DROWN 这类跨协议攻击根本不需要客户端降级。
- 支持 TLS 1.3 就能杜绝降级。 回退检测标记只对同样实现了 TLS 1.3 的客户端有用。
- 降级只涉及协议版本。 密码套件、密钥长度,甚至“加密还是明文”都可能被降级。