总结一下:
- 它可能有效,也可能无效,具体取决于服务器如何管理其会话参数缓存。
- RFC 不一致。
- 这不是一个“真正的”漏洞。
TLS会话最初是一种优化,以避免客户端和服务器使用其“重度非对称加密”为每个连接进行完全握手(这种加密的实际成本通常被高估,但这不是重点)。现有的、已部署的客户端和服务器倾向于记住会话一段时间,然后在不方便继续记住时忘记它们(通常,在服务器端,当专用于此类存储的 RAM 缓冲区已满时,旧会话将被逐出)。这个想法仍然是客户端和服务器仍然可以在需要时透明地进行完整的握手;会话恢复是机会主义的。
一些部署的系统依靠会话恢复来更可靠地工作;特别是基于 Web 的应用程序,使用智能卡进行客户端身份验证:使用智能卡意味着使用卡进行签名,这具有较小的计算成本(例如 1 秒)和较高的用户成本(人类用户可能必须输入 PIN 码)。但是,即使在这些情况下,会话参数也仅存储在 RAM 中,因此如果客户端浏览器关闭然后重新打开,则不会恢复会话,并且会发生完整的握手。
RFC 5246在第 7.2.2 节中包含以下段落:
TLS 握手协议中的错误处理非常简单。当检测到错误时,检测方向对方发送消息。在传输或接收到致命警报消息后,双方立即关闭连接。服务器和客户端必须忘记与失败连接相关的任何会话标识符、密钥和秘密。因此,任何以致命警报终止的连接都不得恢复。
这是一个笼统的声明,非正式地,旨在阻止一些尚未指定的暴力攻击,这些攻击依赖于攻击者“尝试”大量会话恢复。关于该处方,必须提出一些启发性的观点:
从历史上看,当连接没有正确关闭(使用显式)时,会话也必须“忘记” close_notify
。然而,现有的 Web 服务器会突然关闭连接,因此 Web 浏览器已经适应了保持会话“活动”,即使它们以 TLS-1.0 不赞成的方式终止。
当使用会话票据时,这种在致命警报时忘记会话的概念在服务器上不起作用,因为根据定义,具有会话票据的服务器不管理自己的内存。在这方面,RFC 5077 和 RFC 5246 是不一致的:使用会话票证的服务器不能强制执行此“不得恢复”。
碰巧大多数 SSL 实现都不愿意为了遵守 RFC 而打破物理定律。
即使不发送警报,攻击者总是可以强制执行“致命条件”:攻击者自己打开连接就足够了,重用与真正客户端使用的连接相同的会话 ID。服务器将尝试恢复会话(ServerHello
, ChangeCipherSpec
, Finished
),然后期待来自客户端的ChangeCipherSpec
then Finished
。由于客户端是攻击者,并且攻击者不知道他声称要恢复的会话的主密钥,因此他的Finished
消息将无法正确解密,从而触发bad_record_mac
来自服务器的 a。如果要遵循第 7.2.2 节,那么服务器应该忘记会话。
需要指出的是,Finished
上一段中表达的“通过失败终止会话”攻击可能比您描述的更容易实现,因为它只涉及观察真正的连接(获取会话 ID),而不是修改该连接。
上面的第三点很重要,因为它表明,在它Finished
从客户端接收到正确加密和 MAC 化的消息之前,服务器没有证据表明它确实在与真实的客户端对话。可以说,在该点之前会话不会“恢复”,因此不应因为在该点之前发生的任何错误情况(无论是来自客户端的明确警报,还是 MAC 故障或其他任何情况)而“无效”。但是,RFC 也不清楚这一点,所以真正发生的事情实际上取决于服务器如何管理其缓存,这取决于服务器实现者的心血来潮。
该漏洞不是“真实的”,因为任何能够摆弄客户端连接的攻击者已经可以通过例如ClientHello
使用合成警报消息或简单的随机垃圾来响应客户端的消息来造成更大的伤害,这将说服客户端客户端没有工作的 SSL / TLS 服务器在另一端 - 比简单地让服务器和客户端花费几毫秒的 CPU 进行完整握手更全面的拒绝服务。