gpt4 book ai didi

c - 心脏出血错误 : Why is it even possible to process the heartbeat request before the payload is delivered?

转载 作者:可可西里 更新时间:2023-11-01 02:35:39 25 4
gpt4 key购买 nike

首先,我不是 C 程序员,而且 OpenSSL 代码库很大,所以请原谅我问了一个我可能会找到答案的问题,因为我有时间和技能来深入研究代码。

据我所知,TLS 在 TCP 上运行。 TCP 是面向流的,因此无法知道消息何时已交付。您必须事先知道传入的消息应该有多长,或者有一个要扫描的分隔符。

考虑到这一点,OpenSSL 如何在收到完整有效负载之前处理心跳请求?

如果 OpenSSL 在收到有效负载长度后才开始处理它从 TCP 套接字读取的第一 block 数据,那么 OpenSSL 不仅不安全,而且在正常操作下会损坏。由于 TCP 的最大段大小为 536 字节,任何大于该大小的有效负载都将跨越多个 TCP 段,因此可能跨越多个套接字读取。

所以问题是:OpenSSL 如何/为什么可以开始处理尚未传送的消息?

最佳答案

This是心跳包的定义。

struct {
HeartbeatMessageType type;
uint16 payload_length;
opaque payload[HeartbeatMessage.payload_length];
opaque padding[padding_length];
} HeartbeatMessage;

payload_length 字段的不正确处理是导致 heartbleed 错误的原因。

然而,整个数据包本身都封装在 another record 中它有自己的有效载荷长度,大致如下所示:

 struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;

结构体 HeartbeatMessage 放在上面的 fragment 中。

因此,当根据此处的length字段的数据到达时,可以处理一个完整的TLS“数据包”,但在内部Heartbeat消息中,openssl未能验证其payload_length.

这是一个数据包捕获的屏幕截图,其中您可以看到外部长度 3 指定了“数据包”的长度,而内部(错误的)负载长度 16384 是导致漏洞利用的原因,因为 openssl 未能根据数据包的实际接收长度验证这一点。

wireshark screenshot of heartbeat packet

当然,在处理这个外层记录的length字段时也必须要小心,在开始处理之前你真的要确保你确实收到了length数据/解析数据包的内容。

另请注意,套接字读取和 TCP 段之间没有特定的相关性,1 个套接字读取可以读取多个段,或者只是一个段的一部分。对于应用程序来说,TCP 只是一个字节流,一次套接字读取最多只能读取一个 TLSPlaintext 数据包长度字段的一半,或者它可以读取几个完整的 TLSPlaintext 数据包。

关于c - 心脏出血错误 : Why is it even possible to process the heartbeat request before the payload is delivered?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23159622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com