标题 | 简介 | 类型 | 公开时间 | ||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||
详情 | |||||||||||||||||||||||||||||||||||||||
[SAFE-ID: JIWO-2024-3197] 作者: 闲云野鸡 发表于: [2022-10-27] [2022-10-27]被用户:WEB 修改过
本文共 [458] 位读者顶过
1. 漏洞概述
2. 基础知识2.1 IPv6 fragment如果发送的数据包大小超过了最大传输单元(MTU),IPv6 源节点会将数据包分割成多个分片,在前面添加 fragment header ,作为单独的数据包进行传送,然后由目的节点对数据包进行重组。 Fragment header 结构如下:
在分割时,数据包会被分为 不可分片部分 和 可分片部分:
假设原始数据包组成如下:
根据数据包的大小,它会被源节点分成多个分片:
当上面的数据包都到达目的节点后,会重组成为原始数据包:
除此之外需要修改两个位置的数值:
2.2 IPSecInternet Protocal Security(IPsec) 是一个安全网络协议组,可以对数据包进行验证和数据加密,从而为位于 IP 网络中的两台计算机提供安全的加密通信。IPsec 用于 virtual private networks(VPNs)。 IPsec 使用以下的协议实现不同的功能:
其中 ESP 结构如下:
3. 漏洞分析漏洞发生时的函数调用栈如下:
根据以上信息可以确定,tcpip.sys 使用 IppReceiveHeaderBatch 函数处理接收到的数据包,对 next header 的数值进行判断并调用相应函数处理对应头部,漏洞就发生在处理 fragment header 的时候。 tcpip.sys 会调用 Ipv6pReceiveFragmentList 函数对 fragment header 进行处理,在对分片进行重组的时候:
缓冲区 data 的大小为 HeaderAndOptionsLength,next header 的偏移值为 Reassembly->nh_offset。发生越界写的原因就是 Reassembly->nh_offset 的数值大于 HeaderAndOptionsLength。 接下来通过调试确定这两个数值的来源,测试用数据包组成如下:
由于 ESP header 在 Routing header 之后,系统会先处理 ESP header。tcpip.sys 会调用 IppReceiveEspList 函数处理该头部,具体功能位于 IppReceiveEspNbl 函数中,该函数会对 ESP 中的加密数据进行解密,解密结果为:
可以看到 next header 字段的数值为 0x2c,即 Fragment Header for IPv6,系统处理完 ESP 后会继续处理 fragment header。 整理调试过程中,Reassembly->nh_offset 和 HeaderAndOptionsLength 的数据来源变化情况:
由此可以看出,系统在处理 ESP header 时,因为 next header 位于数据包的尾部, 因此 nh_offset 的计算考虑了 payload 的长度;但是在处理 fragment header 的时候,系统认为 next_header 位于 ExtensionHeader 中。即:
实际上,根据 RFC8200 ,在进行分片的时候,ESP header 是不能放在 fragment header 的前面的:
其中的 Ext & Upper-Layer Headers 可能包括 TCP、UDP、IPv4、IPv6、ICMPv6、ESP 等。 4. 补丁对比Ipv6pReassembleDatagram 新增代码段
IppReceiveEsp 新增代码段
可以看到经过补丁修复之后,系统对 ESP header 的 next header 字段进行了判断,不再允许小于等于 0x2c 的头部,同时在进行分片重组时,对 Reassembly->nh_offset 和 HeaderAndOptionsLength 的数值进行了判断。 5. 参考资料 |