Nie*_* B. 2 c sockets tcp heartbleed-bug
首先,我不是C程序员,OpenSSL代码库是巨大的,所以请原谅我提出一个我可以找到答案的问题,因为我有时间和技巧来挖掘代码.
从我所知道的,TLS在TCP上运行.TCP是面向流的,因此无法知道消息何时被传递.您必须事先知道传入消息应该有多长或者要有扫描的分隔符.
考虑到这一点,OpenSSL如何在收到完整的有效载荷之前处理心跳请求?
如果OpenSSL刚刚开始处理在收到有效负载长度后从TCP套接字读取的第一个数据块,那么OpenSSL似乎不仅不安全,而且在正常操作下会中断.由于TCP的最大段大小为536字节,因此任何大于该值的有效负载将跨越多个TCP段,因此可能跨越多个套接字读取.
所以问题是:OpenSSL如何/为什么开始处理尚未交付的消息?
这是心跳包的定义.
struct {
HeartbeatMessageType type;
uint16 payload_length;
opaque payload[HeartbeatMessage.payload_length];
opaque padding[padding_length];
} HeartbeatMessage;
Run Code Online (Sandbox Code Playgroud)
错误的payload_length
字段处理是造成心脏病的原因.
但是,整个数据包本身都封装在另一个具有自己的有效负载长度的记录中,大致如下所示:
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
Run Code Online (Sandbox Code Playgroud)
结构HeartbeatMessage放在上面fragment
.
因此,当根据length
此处的字段的数据到达时,可以处理一个完整的TLS"数据包" ,但是在内部Heartbeat消息中,openssl无法验证它payload_length
.
以下是数据包捕获的屏幕截图,其中您可以看到外部长度为3指定"数据包"的长度,内部(错误)有效负载长度为16384是导致漏洞利用的原因,因为openssl未能对此进行验证数据包的实际接收长度.
当然,在处理length
这个外部记录的字段时必须小心谨慎,你真的想确保length
在开始处理/解析数据包内容之前确实已经接收过数据.
另请注意,套接字读取和TCP段之间没有特定的相关性,1个套接字读取可以读取许多段,或者只是段的一部分.对于应用程序,TCP只是一个字节流,一个套接字读取只能读取一个TLSPlaintext数据包的长度字段的一半,或者它可以读取几个完整的TLSPlaintext数据包.
归档时间: |
|
查看次数: |
957 次 |
最近记录: |