基于击落其他用户会话的 TLS 协议中的新拒绝服务漏洞?

信息安全 tls 拒绝服务 可用性
2021-08-09 12:14:04

我认为我对 TLS 进行了新的拒绝服务攻击,我希望您检查这是否是一个真正的漏洞。

我最近了解了删除经过身份验证的客户端会话的正确方法(请参阅此问题)。根据RFC 5246RFC 5077,这是通过发送致命警报来完成的。但是对于这种丢弃是否真的需要完整的会话恢复没有任何说明,这意味着实际上任何客户端都可以清除任何其他客户端的经过身份验证的会话,只知道 sessionID。

步骤是:

  • 连接到服务器并发送带有目标 sessionID 的 client_hello
  • 等待服务器应答,其中将包括 server_hello、change_cipher_spec 和完成
  • 发送任何值的 UNENCRYPTED 致命警报

RFC 5246说(§7.2.2):

在传输或接收到致命警报消息后,双方立即关闭连接。服务器和客户端必须忘记与失败连接相关的任何会话标识符、密钥和秘密。因此,任何以致命警报终止的连接都不得恢复。

这在任何连接和密码状态下都非常有效,包括 NULL。

我刚刚检查了实际的 OpenSSL 实现。存在漏洞(如果它是漏洞)。社区会怎么说?我是将这个问题作为真正的漏洞来推动,还是它只是它应该的方式并且没有什么可担心的?

3个回答

总结一下:

  • 它可能有效,也可能无效,具体取决于服务器如何管理其会话参数缓存。
  • RFC 不一致。
  • 这不是一个“真正的”漏洞。

TLS会话最初是一种优化,以避免客户端和服务器使用其“重度非对称加密”为每个连接进行完全握手(这种加密的实际成本通常被高估,但这不是重点)。现有的、已部署的客户端和服务器倾向于记住会话一段时间,然后在不方便继续记住时忘记它们(通常,在服务器端,当专用于此类存储的 RAM 缓冲区已满时,旧会话将被逐出)。这个想法仍然是客户端和服务器仍然可以在需要时透明地进行完整的握手;会话恢复是机会主义的。

一些部署的系统依靠会话恢复来更可靠地工作;特别是基于 Web 的应用程序,使用智能卡进行客户端身份验证:使用智能卡意味着使用卡进行签名,这具有较小的计算成本(例如 1 秒)和较高的用户成本(人类用户可能必须输入 PIN 码)。但是,即使在这些情况下,会话参数也仅存储在 RAM 中,因此如果客户端浏览器关闭然后重新打开,则不会恢复会话,并且会发生完整的握手。

RFC 5246第 7.2.2 节中包含以下段落:

TLS 握手协议中的错误处理非常简单。当检测到错误时,检测方向对方发送消息。在传输或接收到致命警报消息后,双方立即关闭连接。服务器和客户端必须忘记与失败连接相关的任何会话标识符、密钥和秘密。因此,任何以致命警报终止的连接都不得恢复。

这是一个笼统的声明,非正式地,旨在阻止一些尚未指定的暴力攻击,这些攻击依赖于攻击者“尝试”大量会话恢复。关于该处方,必须提出一些启发性的观点:

  1. 从历史上看,当连接没有正确关闭(使用显式)时,会话也必须“忘记” close_notify然而,现有的 Web 服务器会突然关闭连接,因此 Web 浏览器已经适应了保持会话“活动”,即使它们以 TLS-1.0 不赞成的方式终止。

  2. 当使用会话票据时,这种在致命警报时忘记会话的概念在服务器上不起作用,因为根据定义,具有会话票据的服务器不管理自己的内存。在这方面,RFC 5077 和 RFC 5246 是不一致的:使用会话票证的服务器不能强制执行此“不得恢复”。

    碰巧大多数 SSL 实现都不愿意为了遵守 RFC 而打破物理定律。

  3. 即使不发送警报,攻击者总是可以强制执行“致命条件”:攻击者自己打开连接就足够了,重用与真正客户端使用的连接相同的会话 ID。服务器将尝试恢复会话(ServerHello, ChangeCipherSpec, Finished),然后期待来自客户端的ChangeCipherSpecthen Finished由于客户端是攻击者,并且攻击者不知道他声称要恢复的会话的主密钥,因此他的Finished消息将无法正确解密,从而触发bad_record_mac来自服务器的 a。如果要遵循第 7.2.2 节,那么服务器应该忘记会话。

需要指出的是,Finished上一段中表达的“通过失败终止会话”攻击可能比您描述的更容易实现,因为它只涉及观察真正的连接(获取会话 ID),而不是修改该连接。

上面的第三点很重要,因为它表明,在它Finished从客户端接收到正确加密和 MAC 化的消息之前,服务器没有证据表明它确实在与真实的客户端对话。可以说,在该点之前会话不会“恢复”,因此不应因为在该点之前发生的任何错误情况(无论是来自客户端的明确警报,还是 MAC 故障或其他任何情况)而“无效”。但是,RFC 也不清楚这一点,所以真正发生的事情实际上取决于服务器如何管理其缓存,这取决于服务器实现者的心血来潮。

该漏洞不是“真实的”,因为任何能够摆弄客户端连接的攻击者已经可以通过例如ClientHello使用合成警报消息或简单的随机垃圾来响应客户端的消息来造成更大的伤害,这将说服客户端客户端没有工作的 SSL / TLS 服务器在另一端 - 比简单地让服务器和客户端花费几毫秒的 CPU 进行完整握手更全面的拒绝服务。

如果您已凭经验验证它的功能符合建议*,那么您应该通知 OpenSSL 安全团队

此错误的影响可能会出现在拒绝服务范围内;基本上,您可以强制客户端/服务器对每次都执行完整的协商,这会占用更多的服务器资源(......这就是为什么首先存在恢复)。而且,在可用性规模上,这可能并不大 - 它只是将性能降低到不使用恢复时预期的基本水平,这是公认的最坏情况**。

我目前没有看到对机密性或完整性的威胁(尽管历史上充斥着次要问题 X 和次要问题 Y 组合成主要问题 Z 的例子)。

如前所述,这可能是一个实现问题,也可能是一个协议问题。正如您所说,“[在 RFC 中] 没有提到这种丢弃是否真的需要完整的会话恢复。” 因此,各种 SSL 实现可能会以不同的方式处理这种情况。由于您已经在研究 OpenSSL,我将继续沿用这些思路,当您拥有概念验证代码时,您可以测试其他 SSL 实现以了解它们如何处理它。

如果它确实是一个更广泛的协议问题,并且您已经在与 OpenSSL 安全团队合作,那么我会就如何扩大咨询范围征求他们的建议。


* 我建议您在升级之前设计一个概念验证***。首先,您将确保您确实有问题!其次,如果您有一个漏洞利用代码使他们能够重现该问题,您的问题将得到更好的关注。不清楚您所说的“刚刚检查了实际的 OpenSSL 实现”是什么意思,所以我假设您此时刚刚完成了代码审查。

** 这个错误的严重性相当低;也许“服务退化”比“拒绝服务”更好。出于这个原因,我不会担心公开披露这个问题……它的影响力不足以要求保密或通过“道德披露”的谨慎步骤。(这并不是要最小化问题;它似乎是一个令人着迷的地方,标准语言中的一些歧义允许不良行为潜入。)

*** @Trueblacker 创建了一个概念验证并为 OpenSSL 团队打开了一个问题- 在这里记录,因为评论是短暂的。

不,这不是一个真正的漏洞。你的攻击计划中的差距是:你打算如何学习其他用户使用的会话 ID?

会话 ID 很难猜测,因此您不能仅仅预测或猜测其他用户将使用的会话 ID。在不知道会话 ID 的情况下,您无法进行攻击。因此,目前尚不清楚攻击者如何在实践中实际执行这种攻击。

特别是,路径外的攻击者看不到会话 ID 也无法猜测,因此可能无法执行此攻击。如果您正在考虑中间人攻击或窃听,如果对手有能力这样做,那么可能会出现更糟糕的可用性攻击——所以这种情况不是很有趣;这种攻击很可能被认为是微不足道的。