2020年10月13日,微软宣布了Windows IPv6栈中的一个严重漏洞,攻击者可发送特制数据包,导致最新版本的Windows 10和Windows Server 2019立即蓝屏死机(BSOD)。虽然该漏洞似乎无法让攻击者执行代码,但它可用于对存在漏洞的Windows版本进行大规模拒绝服务攻击。更具影响力的RCE版本漏洞的检测逻辑可在CVE-2020-16898:"Bad Neighbor"中找到。
本文档由McAfee高级威胁研究团队编写,旨在为网络管理员和安全人员提供有价值的见解,帮助他们进一步了解该漏洞并防御利用。此处提供的签名应在暂存环境中经过全面考虑和验证,再投入生产使用,并可能需要根据目标部署进行特定调整。
此处提供的信息如有变更,恕不另行通知,按"原样"提供,包含所有缺陷,不保证或担保信息对任何特定情况或环境的准确性或适用性,您需自行承担使用风险。此外,我们无法保证任何签名的性能或有效性基准。
该漏洞是由于Windows IPv6栈在处理包含一个或多个DNSSL选项记录(选项类型=31)的ICMPv6路由器通告(类型=134)数据包时,可能发生越界读取所致。DNSSL记录的目的是提供DNS名称后缀的搜索列表,该列表包含在其最后一个字段中。由于此搜索列表可连续包含多个以空字符结尾的DNS名称,因此该字段(以及整个记录)的大小变化范围很大。为适应此情况,DNSSL选项记录包含自身的长度字段。然而,由于长度以8字节为单位计数,搜索列表中的至少一个域名可能具有额外的空字节填充以保持记录8字节对齐。正是对这些空字节的处理导致了漏洞。
对于搜索列表中的每个域名,Windows IPv6栈会分配一个256字节的缓冲区。由于RFC 1035将域名限制为255字节,这通常足以容纳域名及其空终止符。然而,负责消耗每个域名末尾空字节的代码的上限等于选项中剩余的字节数,这可能超过256字节。结果,空字节消耗代码可能错误地消耗比缓冲区分配更多的字节,导致越界读取。当缓冲区位于内存页末尾时,此越界读取可能导致蓝屏死机。
此漏洞的Suricata签名位于cve-2020-16899.rules中,包含以下逻辑:
alert icmp any any -> any any (msg:"Potential CVE-2020-16899 Exploit"; lua:cve-2020-16899.lua; sid:202016899; rev:1;)
相应的Lua脚本可在cve-2020-16899.lua中找到。它包含正确解析ICMPv6层并识别潜在CVE-2020-16899利用所需的逻辑,具体如下:
一旦定位到ICMPv6层的起始位置,我们检查该层的第一个字节,确保它是ICMPv6路由器通告数据包——如果不是,则退出。
由于Suricata原语尚未更新以解析ICMPv6选项,我们直接跳转到ICMPv6层的第17个字节,因为如果存在选项,则选项应从该位置开始(前16个字节是固定长度字段,依据RFC 4443)。从那里,我们循环遍历每个选项,直到数据包中的字节用完。对于每个选项,我们首先检查第一个字节,即选项类型字段。我们忽略所有非DNSSL的选项,对于选项类型=31(DNSSL),我们检查长度(选项的第二个字节)是否大于或等于35(触发漏洞所需的最小长度):