DROWN攻击的全称是Decrypting RSA with Obsolete and Weakened eNcryption,它并不是直接对RSA私钥做素因子分解,而是将废弃的SSLv2协议当作解密辅助工具。攻击者通过跨协议方式,把目标TLS会话中的RSA加密预主密钥密文,投递给一台支持SSLv2且共享同一证书的服务器,再利用服务器对畸形密文的差异化响应,逐步恢复预主密钥。因为TLS会话密钥由预主密钥和随机数共同派生,一旦预主密钥被还原,整个加密流量就可以被解密。

这种攻击的隐蔽之处在于,目标服务器本身可以完全禁用SSLv2,仍然无法阻止攻击。只要同一张RSA证书被部署在其他开启SSLv2的老旧系统上,攻击者就能选择那台旧主机作为解密预言机。证书复用、退役系统未及时清理、边缘服务保留旧协议,都会形成跨协议攻击面。
SSLv2是如何变成解密预言机的
SSLv2在设计上使用RSA加密预主密钥,密文遵循RSA PKCS#1 v1.5填充格式。解密后的数据前两个字节必须是0x00和0x02,随后至少8个非零随机填充字节,再以0x00作为分隔符,最后才是真正的预主密钥。服务器在收到客户端RSA密文后,会解密并检查填充格式。如果格式不对,不同实现可能返回不同的错误码或终止连接,这种差异为Bleichenbacher类型的攻击提供了条件。
Bleichenbacher攻击的核心思路是:攻击者选取一个密文,乘以某个精心构造的整数的e次方并取模后发给服务器,观察响应是否表示填充合法。通过大量这样的试探,能够以远低于暴力破解的复杂度恢复出RSA明文。DROWN将这一方法应用到SSLv2上,并且利用SSLv2导出密码套件的弱点进一步加速。SSLv2的出口级密码只使用40位对称密钥,攻击者可以先暴力破解这段弱密钥,再把它转换成RSA oracle,从而实现快速解密。
跨协议的特殊性体现在密文转化阶段。目标TLS会话中的RSA密文并不能直接作为SSLv2报文发送,但攻击者可以构造一个与目标密文存在数学关系的SSLv2密文,让共享私钥的服务器解密后产生关于目标明文的泄露信息。多轮查询后,目标预主密钥被还原。
攻击流程与利用条件
实际利用DROWN需要几个条件同时成立。第一,被攻击的TLS会话必须采用基于RSA的密钥交换,而不是临时Diffie-Hellman等具备前向保密的套件。第二,服务器证书的私钥必须与一台支持SSLv2的主机共享。第三,攻击者能够访问这台支持SSLv2的主机,并持续发送构造的SSLv2握手请求。第四,攻击者已经捕获目标TLS握手报文。
攻击流程可以概括为:首先从捕获的流量中提取加密的预主密钥;接着将目标密文转换为一组适合SSLv2服务器处理的探测密文;然后向SSLv2服务器批量发送这些探测报文,根据响应判断填充是否有效;最后利用Bleichenbacher算法恢复预主密钥,再结合握手过程中的随机数计算出主密钥和会话密钥。全程不需要拿到服务器私钥文件。
检测某个主机是否支持SSLv2可以用OpenSSL命令完成。下面的命令尝试以SSLv2协议连接目标,如果能建立连接,说明该主机可能成为DROWN攻击的利用点。
openssl s_client -connect ipipp.com:443 -ssl2
更完整的端口扫描可以借助Nmap的ssl-enum-ciphers脚本,它会列出服务端支持的协议版本和密码套件,便于发现遗留的SSLv2和出口级套件。
防御措施与配置实践
最直接的防御方法是彻底禁用SSLv2以及所有导出密码套件。现代Web服务器和负载均衡设备基本都支持通过配置关闭旧协议。对于Nginx,可以在server块中明确指定允许的TLS版本,并只保留具备前向保密的密码套件。
server {
listen 443 ssl;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
}
Apache环境中同样可以通过SSLProtocol和SSLCipherSuite指令收紧协议范围。下面配置表示拒绝SSLv2、SSLv3以及较老的TLS版本,只允许TLSv1.2以上。
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
仅在一台服务器上禁用SSLv2还不够。由于DROWN是跨协议攻击,必须审计所有使用同一张RSA证书的服务器。如果某个旧邮件系统、测试环境或内部管理平台仍然支持SSLv2,攻击者依然可以利用它来解密其他主机的流量。企业应建立证书使用清单,避免在不同安全等级的系统间复用同一私钥。
更长远的策略是优先采用前向保密密钥交换算法,例如ECDHE。即使私钥在未来泄露,历史会话仍无法被解密。对于必须使用RSA证书的场景,可以配置密钥轮换策略,缩短证书有效期,并监控异常SSLv2握手请求。
检测与审计方法
安全团队可以通过主动扫描和被动流量分析两种方式识别DROWN风险。主动扫描使用Nmap脚本可以直接枚举目标主机的协议支持情况。
nmap --script ssl-enum-ciphers -p 443 ipipp.com
如果输出中出现SSLv2字样,或者列出EXPORT密码套件,就需要立即处理。被动流量分析则可以记录网络中出现的大量SSLv2握手失败记录,这些失败可能源于攻击者的探测行为。若发现某个源IP在短时间内向同一端口发送大量SSLv2请求,应结合入侵检测系统告警。
在Windows环境中,OpenSSL安装目录可能为C:\Program Files\OpenSSL\bin,运行openssl version可以确认命令行工具是否可用。证书复用审计同样关键。可以使用脚本定期收集各网段开放443、25、993等端口的服务证书指纹,比较同一证书是否出现在多个主机上。如果同一证书同时出现在支持TLSv1.3的服务器和支持SSLv2的旧设备上,就要优先迁移旧设备或更换证书私钥。
DROWN攻击说明遗留协议不是只影响旧系统本身,而是可能成为整个证书生态的薄弱环节。关闭旧协议、启用前向保密、减少证书复用,这三项措施可以显著缩小这类跨协议攻击的暴露面。