安全播报

防御吧作为15年知名老牌域名服务商,CNNIC和CANN双认证域名注册商,已经
持续为500多万个域名提供服务,包括智能DNS/自由转移/隐私保护等服务!
Windows TCP/IP远程执行代码漏洞分析
2020-10-23 14:02:30 【

报告编号:B6-2020-101901

报告来源:360-CERT

报告作者:360-CERT

更新日期:2020-10-19

0x01 前言

1.1 环境搭建

(1)攻击机环境:Ubuntu 20.04

安装scapy

sudoapt install python-pip3sudopip3 install scapy

(2)受害机环境:Windows 10 1909 x64

tcpip.sys 驱动版本:10.0.18362.476

(3)双机调试Windows 驱动:

https://blog.csdn.net/qq_21000273/article/details/52027708

断点:

bptcpip!Ipv6pUpdateRDNSSbptcpip!Ipv6pHandleRouterAdvertisementbptcpip!

Ipv6pHandleRouterAdvertisement+0xae4ccbptcpip!Ipv6pHandleRouterAdvertisement+0xae4dbbptcpip!Ipv6pUpdateRDNSS+0x99bptcpip!Ipv6pUpdateRDNSS+0xca

1.2 背景知识

涉及的包类型:

type:24   Route Information Optiontype:25  

Recursive DNS Server Optiontype:134  IMCPv6 Router Advertisement

涉及的结构:

_MDL结构

typedef __struct_bcount (Size ) struct _MDL {    struct _MDL *Next ;  

CSHORT Size ;    CSHORT MdlFlags ;    struct _EPROCESS *Process ;    PVOID MappedSystemVa ;    PVOID StartVa ;    ULONG ByteCount ;    ULONG ByteOffset ;} MDL , *PMDL ;

_NET_BUFFER 结构

typedefstruct _NET_BUFFER {union{struct{PNET_BUFFERNext;

PMDLCurrentMdl;ULONGCurrentMdlOffset;union{ULONGDataLength;SIZE_TstDataLength;};PMDLMdlChain;ULONGDataOffset;};SLIST_HEADERLink;NET_BUFFER_HEADERNetBufferHeader;};USHORTChecksumBias;USHORTReserved;NDIS_HANDLENdisPoolHandle;PVOIDNdisReserved[2];PVOIDProtocolReserved[6];PVOIDMiniportReserved[4];NDIS_PHYSICAL_ADDRESSDataPhysicalAddress;union{PNET_BUFFER_SHARED_MEMORYSharedMemoryInfo;PSCATTER_GATHER_LISTScatterGatherList;};}NET_BUFFER, *PNET_BUFFER;

相关函数:

NdisGetDataBuffer 函数

PVOIDNdisGetDataBuffer(PNET_BUFFERNetBuffer,ULONGBytesNeeded,

PVOIDStorage,UINTAlignMultiple,UINTAlignOffset);

NetBuffer:指向NET_BUFFER 结构的指针

BytesNeeded:请求的连续数据的字节数

Storage:指向缓冲区的指针,如果调用者未提供缓冲区,则为NULL。缓冲区的大小必须大于或等于BytesNeeded中指定的字节数。如果此值为非NULL,并且请求的数据不连续,则NDIS将请求的数据将复制到Storage指向的地址。

Windows通过Ipv6pHandleRouterAdvertisement 函数处理 IPv6 路由器通告数据,在该函数中调用 NdisGetDataBuffer 函数从 NET_BUFFER 结构中访问连续或不连续的数据,通过 NET_BUFFER ->CurrentMdlOffset 字段来记录要访问数据起始地址相对于_MDL->MappedSystemVa 的偏移。

0x02 漏洞分析

2.1 漏洞背景

2020年10月14日,360CERT监测发现 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包进行解析,造成栈溢出,从而导致系统崩溃。

RDNSS Option 数据包格式如下:


Type: 占8-bit,RDNSS 的类型为25

Length:8-bit无符号整数,单位长度为8个字节,所以Type, Length, Reserved, Lifetime一共占8个字节,一个单位长度,而一个IPv6地址占16个字节,两个单位长度,所以Length的最小值为3,且为奇数。

Reserved:保留字段

Lifetime:32-bit无符号整数,存活周期。

Addresses of IPv6 Recursive DNS Servers:保存RNDSS的IPv6地址,每个占16个字节,地址的数量会影响Length字段,number=(Length - 1) / 2。每增加一个地址,Length加2。

漏洞点存在于tcpip.sys -> Ipv6pHandleRouterAdvertisement 函数

漏洞调用链为:Icmpv6ReceiveDatagrams -> Ipv6pHandleRouterAdvertisement -> Ipv6pUpdateRDNSS

Ipv6pHandleRouterAdvertisement 函数存在两个循环,第一个循环遍历所有headers,做一些基本的验证,如length的大小,第二个循环用于处理包,并且该阶段不再验证,两个循环的伪代码如下:

//循环1while(1){……v28=(KIRQL*)NdisGetDataBuffer(v9,2u,v182,1u,0);

v27=v9->DataLength;actual_length_bytes=8*v28[1];……switch(v25){case 0x18u://case0x18(ICMPv6NDOptRouteInfo)……if(actual_length_bytes>0x18u||(v144=*((_BYTE*)NdisGetDataBuffer(v9,actual_length_bytes,v220,1u,0)+2),v144>0x80u)||v144>0x40u&&actual_length_bytes<0x18u//<-----【1】验证实际字节数,不能大于0x18||v144&&actual_length_bytes<0x10u){*a3=24;gotoLABEL_275;}break;case 0x19u://case0x19(ICMPv6NDOptRDNSS)//<-----【2】if((*(_BYTE*)(v11+404)&0x40)!=0&&actual_length_bytes<0x18u)*a3=25;break;}……if(actual_length_bytes){v31=actual_length_bytes+v9->CurrentMdlOffset;if(v31>=*(_DWORD*)(v9->Link.Region+0x28)){NdisAdvanceNetBufferDataStart(v9,actual_length_bytes,0,0i64);//<---actual_length_bytes=4*8=0x20}else{v9->DataOffset+=actual_length_bytes;v9->DataLength-=actual_length_bytes;v9->CurrentMdlOffset=v31;//更新CurrentMdlOffset}}v21+=actual_length_bytes;}……//循环2while(1){……if(*v75==0x18)//case0x18(ICMPv6NDOptRouteInfo){……v153=(unsigned__int8*)NdisGetDataBuffer(NetBuffer_1,actual_option,Storage_1,1u,0);//<---【3】v225=_mm_load_si128((const__m128i*)&_xmm);v174=v225.m128i_u32[((unsigned__int64)v153[3]>>3)&3];……}if(*v75==0x19)//xffffeaeaBUFFER41414141字节


】【打印关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇SQL注入(Web漏洞及防御) 下一篇数据安全视角下的数据库审计技术..

立足首都,辐射全球,防御吧专注云防御及云计算服务15年!

联系我们

服务热线:010-56157787 ,010-56159998
企业QQ:4000043998
技术支持:010-56159998
E-Mail:800@fangyuba.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解决防御与加速) 版权所有 增值许可:京B2-20140042号
售前咨询
公司总机:4000043998 01056155355
24小时电话:010-56159998
投诉电话:18910191973
值班售后/技术支持
售后服务/财务
备案专员
紧急电话:18610088800