0x01 漏洞原因简介
最近在看看漏洞相关,想尝试下漏洞热补之类的方案,挑了几个漏洞学习研究;
步入正题,smbghost是一个smb v3 远程代码执行漏洞,仅影响部分win 10操作系统,从 Windows 10 Version 1903 到 Windows 10 Version 1909。
漏洞原理为由于SMB 3.1.1协议中处理压缩消息时,对其中数据没有经过安全检查,直接使用可能会导致缓冲区溢出,可能被攻击者利用远程执行任意代码;
更详细的说,是 srv2.sys 驱动程模块中,Srv2!Srv2DecompressData在处理压缩数据时,对COMPRESSION_TRANSFORM_HEADER结构体(压缩数据相关的一个结构体)的OriginalCompressedSegmentSize字段(压缩前的数据大小)和Length字段的和,
没有做溢出校验,并且用这个相加之和,申请了一块内存,导致了缓冲区溢出的可能。
const uint8_t buf[] = { /* NetBIOS Wrapper */ 0x00, 0x00, 0x00, 0x33, /* SMB Header */ 0xFC, 0x53, 0x4D, 0x42, /* protocol id */ 0xFF, 0xFF, 0xFF, 0xFF, /* original decompressed size, trigger arithmetic overflow */ 0x02, 0x00, /* compression algorithm, LZ77 */ 0x00, 0x00, /* flags */ 0x10, 0x00, 0x00, 0x00, /* offset */ }; /* typedef struct _COMPRESSION_TRANSFORM_HEADER { ULONG ProtocolId; ULONG OriginalCompressedSegmentSize; //压缩前的数据大小 USHORT CompressionAlgorithm; USHORT Flags; ULONG Length; //压缩数据的偏移地址(距离该结构体末尾的偏移) }COMPRESSION_TRANSFORM_HEADER, *PCOMPRESSION_TRANSFORM_HEADER; */
srv2漏洞源头:
上图中SrvNetAllocateBuffer函数的第一个参数,就是OriginalCompressedSegmentSize字段(压缩前的数据大小)和Length字段的和;
更详细的说明以及exploit源码,不再赘述,可参见以下两篇文章:
https://paper.seebug.org/1165/
https://xz.aliyun.com/t/7440
0x02 漏洞热补思路
最近刚看了网络过滤相关;直接上WFP网络过滤,在srv2模块解析压缩数据前进行过滤,在FWPM_LAYER_STREAM_V4(同v6)数据流层过滤SMB压缩数据包,也就是在应用层send ,receive数据包的时候过来。
判断一下几个条件即可:
1.端口是否445 端口(smb协议默认端口445);
2.数据包中SMB压缩数据标志0xFC, 'S', 'M', 'B'(SMB Header中的ProtocolId为0x424D53FC也就是0xFC, 'S', 'M', 'B'.):
3.调用RtlUlongAdd函数校验OriginalCompressedSegmentSize字段(压缩前的数据大小)和Length字段的和是否溢出;