
2024 年 8 月 13 日,MSTC(微软安全响应中心)披露了 CVE-2024-38063,这是 Windows TCP/IP 协议栈中的一个关键漏洞,可被利用来破坏操作系统中的重要网络功能。在此,OPSWAT 研究生奖学金项目的参与者将对该漏洞的技术细节和潜在影响进行深入研究,并推荐针对该漏洞的缓解策略。
OPSWAT 研究金计划参与者:Pham Ngoc Thien - 胡志明信息技术大学
概述
CVE-2024-38063 是一个 Windows TCP/IP 堆栈关键漏洞,CVSS 得分为 9.8,影响 IPv6 数据包的处理。远程攻击者可在处理 IPv6 扩展报头时利用整数下溢利用此漏洞执行恶意代码或导致 DoS(拒绝服务)。
由于大多数现代系统都默认启用了 IPv6,因此这个零点击漏洞带来了巨大风险。因此,所有未打补丁的启用了 IPv6 的 Windows 10、Windows 11 和 WindowsServer 2008、2012、2016、2019 和 2022 版本都容易受到此 CVE 的攻击。
关键概念
Windows TCP/IP 协议栈
Windows TCP/IP 协议栈是操作系统的基础组件,负责通过传输控制协议/互联网协议(TCP/IP)套件进行网络通信。它处理所有网络交互,促进本地和全球网络设备之间的通信。
IPv6 和扩展标头
IPv6 的开发是为了解决 IPv4 的局限性。它引入了各种增强功能,如通过扩展报头实现模块化和灵活性。扩展报头位于 IPv6 报头和有效载荷之间,支持可选数据和高级功能。
关键的 IPv6 扩展标头包括
- 逐跳选项(下一报文头 = 0)
- 路由标头(下一标头 = 43)
- 片段标头(下一标头 = 44)
- 目的地选项标头(下一标头 = 60)
- 验证标头 (AH)(下一标头 = 51)
- 封装安全有效载荷 (ESP)(下一报头 = 50)
每个扩展报文头通过下一个报文头字段指向下一个报文头,形成一个顺序链。这种模块化给数据包处理过程带来了复杂性和潜在的利用载体。
整数下溢
当计算产生的值小于数据类型的最小可表示值时,就会出现整数下溢。例如,将一个较大的值减去一个较小的无符号整数,会导致结果变成一个非常大的正值。
当数值超过数据类型的最大限制并 "溢出 "回最小可表示值(如 0-10 范围内的 0)时,就会发生整数溢出。这两种情况的发生都是由于算术运算中边界条件处理不当,导致软件系统出现严重漏洞。
脆弱性分析
处理 IPv6 的工作流程
收到 IPv6 数据包后,Windows 会首先解析 IPv6 报头。然后,IppReceiveHeaderBatch 函数检查 "下一个报头"(Next Header)字段的值,为后续报头选择适当的处理程序。对于链中的每个扩展报头,IppReceiveHeaderBatch 都会调用相应的例程来处理该特定报头。
尽管这种机制设计灵活、模块化,但它引入了一个潜在的攻击载体。在 IPv6 中,碎片数据包通常在目的地重新组装,而碎片重新组装过程和报头处理存在漏洞。
攻击者可通过发送大量带有经过处理的扩展头的畸形数据包,诱发内存管理不善和缓冲区溢出。这允许过量数据覆盖意外内存区域,从而可能允许执行任意代码。此漏洞被认定为 CVE-2024-38063。
Windows TCP/IP 协议栈中的严重漏洞
安全研究员马库斯-哈钦斯(Marcus Hutchins)对微软针对 CVE-2024-38063 漏洞发布的补丁进行了深入研究。他在自己的技术博客中详细介绍了该漏洞的根源。在他的研究成果的基础上,我们的研究员进一步探索了这个问题,以获得对漏洞的透彻理解。
补丁分析
补丁包括对 tcpip.sys 文件的更新,包括对 Ipv6pProcessOptions 函数的修改。单行修改将 IppSendErrorList() 的调用替换为 IppSendError() 的调用,表明 IppSendErrorList() 可能导致了 CVE。
数据包大小为零
仔细研究 IppSendErrorList() 函数后发现,它通过调用 IppSendError() 函数处理每个数据包的链接列表。IppSendError() 函数为有缺陷的数据包分配 STATUS_DATA_NOT_ACCEPTED 状态。然后,它会创建一条包含问题数据包相关信息的 ICMP 错误消息,并将其发送回去。然而,当在多个数据包上以 always_send_icmp = true 的方式调用 IppSendErrorList() 时,它会将每个数据包的 packet_size 字段设置为零。
Ipv6pProcessOptions 函数用于处理包含选项值字段的扩展报头,包括逐跳选项和目的地选项报头。通过将选项类型设置为任何大于 0x80 的值,攻击者可以在选项报头处理过程中触发特定错误,迫使 always_send_icmp 设置为 true,从而导致数据包大小被设置为零。
虽然零大小数据包通常会被丢弃,但攻击者可以操纵原始 IPv6 数据包中的 "下一报头 "字段。通过这种操作,攻击者可以控制数据包在后续处理阶段的解释,避免被立即拒绝,从而创造利用机会。
片段处理中的整数下溢
通过将 "下一个报文头"(Next Header)字段设置为 44(表示片段报文头),数据包将由 IPv6 片段或重新组装例程处理。当数据包到达片段解析器 Ipv6pReceiveFragment() 时,它指定:
- 数据包大小为零。
- 片段标头表示还有其他数据需要处理。
在 Ipv6pReceiveFragment() 函数中,fragment_size 的分配大小是通过从数据包大小减去 0x30(数据包头长度)计算得出的,没有经过任何验证。如果数据包大小为零,该减法就会产生低溢出,从而产生一个较大的 16 位值(约 0xFFD0 或 65488),导致解析器处理数据包有效边界之外的过多内存,并导致内存损坏。
从下溢到溢出与分配不匹配
Ipv6pReassemblyTimeout() 函数使用 16 位算术确定缓冲区大小和复制操作,负责在指定时间后清理不完整的 IPv6 片段。由于上一步的数据包长度(packet_length)或片段大小(fragment_size)变为 0xFFD0,分配过程中会出现溢出。
计算结果导致寄存器重置为零,从而只分配了 48 字节内存。然而,由于复制的数据量(65,488 字节,来自重新组装->支付负载)与分配的内存不符,内核池中出现了可控的缓冲区溢出。
这一差异为攻击者利用 IPv6 处理中的漏洞,通过特制数据包执行恶意代码打开了方便之门。
CVE-2024-38963 概念验证
为了重现 CVE-2024-38963 漏洞,我们的研究人员制作了一系列旨在利用该漏洞的畸形数据包。他们遵循的流程是
1.伪造畸形 IPv6 数据包
在基本 IPv6 标头后插入 IPv6 目的地选项扩展标头(类型 60),然后嵌入一个无效选项(如选项类型 0x81)。
这种操作会强制 Windows 内核 (tcpip.sys) 设置 always_send_icmp = true,从而通过 IppSendErrorList() 例程触发 ICMPv6 错误生成。
2.强制处理净缓冲区列表(NBL)
用这些畸形数据包的快速突发淹没目标,增加了内核将多个数据包分组到单个网络缓冲区列表(NBL)中的机会。当两个或更多数据包被分组时,易受攻击的 IppSendErrorList() 循环会被激活,从而错误地重置后续片段中的 DataLength 和 Offset 元数据(数据包大小现在为零)。
3.注入碎片化 IPv6 数据包
在传输畸形数据包后,会发送包含片段扩展头的碎片 IPv6 数据包。这些碎片将使用已损坏的 DataLength 值进行处理。
4.利用重组超时
内核会保留片段 60 秒(由 Ipv6pReassemblyTimeout 管理),以便重新组装数据包。在超时期间,损坏的 DataLength 值会触发 Ipv6pReceiveFragment 中的整数下溢,导致计算错误(过大)的片段大小。
5.触发堆缓冲区溢出
内核根据下溢值分配堆缓冲区。在重新组装过程中会进行两种不同的计算:一种是确定内存分配大小(由于 16 位溢出,该大小变得过小),另一种是使用大的下溢值计算拷贝长度。
这种不匹配会导致越界写入,造成基于堆的缓冲区溢出,可被利用来触发拒绝服务(DoS)或远程代码执行。
用于重现此 CVE 的拒绝服务攻击源代码:
当该漏洞被攻击者利用时,受害者的系统可能会立即崩溃,导致蓝屏死机:
补救措施
忽视定期更新操作系统会使您的设备面临安全威胁,包括与 CVE(常见漏洞和暴露)相关的威胁。为了降低这些风险,MetaDefender Endpoint™通过检测操作系统版本和检查漏洞(包括已知的 CVE,如 CVE-2024-38063)来提供强大的保护。
MetaDefender Endpoint 旨在保护关键 IT/OT 网络中的设备免受外设和可移动媒体威胁。它能确保操作系统和安装的应用程序是最新的,标记任何过时或易受攻击的版本,并列出存在已知漏洞和 CVE 的应用程序以及建议的修复程序。它还能阻止USB 驱动器的访问,直到使用多个反恶意软件引擎扫描并发现其已清除,同时对 180 多种文件类型执行Deep CDR™,从而帮助设备防范可移动媒体风险。
现在就联系我们的专家,了解MetaDefender Endpoint 如何利用行业领先的智能技术改变您的安全状况。