SMBv3远程拒绝服务(BSOD)漏洞分析,这个SMBv3漏洞是由lgandx爆出的一个未被微软修复的漏洞(暂未发布补丁),漏洞出来后我进行了一定的分析,花了很多时间,这个漏洞有一些意思,但是对于SMB的整个协议通信过程非常庞大,所以没有进行非常细致的跟踪,包括一些不透明的结构体让我感到晕头转向,但到最后还是有了一些结果。
这个SMB漏洞可以看作是被动的,需要用户主动去访问445端口才可以触发,而不像ms08067一样主动攻击别人,所以需要运行漏洞脚本在操作系统上。
终于赶在元宵节这天完成了这个任务,也在这里,祝大家元宵节快乐!
这个漏洞在twitter爆出来之后,很多老外也在微博下面问是否可以RCE,包括国内的预警中也有人问到。
那么很多人看到PoC中的关键部分,就会想:有填充数据,会不会是缓冲区溢出!
## Tree Connect
if data[16:18] == "\x03\x00":head = SMBv2Header(Cmd="\x03\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", TID="\x01\x00\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x00\x00\x00\x00", SessionID=GrabSessionID(data))
t = SMB2TreeData(Data="C"*1500)#//BUG
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
print "[*]Triggering Bug; Tree Connect SMBv2 packet sent."self.request.send(buffer1)
data = self.request.recv(1024)
答案是否定的,至少在我看来,大量的数据目的并非是为了填充缓冲区,而是为了绕过tcpip.sys的某处判断,从而进入漏洞出发的函数调用逻辑。
问题出现在smbv2后的一个特性Tree Connect,用来处理共享服务的特性,opcode:0x03,而整个问题,确是多个地方导致的。下面我们就一起来进入今天的旅程吧!
Github地址:https://github.com/lgandx/PoC/tree/master/SMBv3%20Tree%20Connect
漏洞复现
首先,网上关于这个漏洞的触发方法有很多,比较通用的是twitter中某老外提到的Powershell的方法,最为简单,首先我们调试的环境是:windows 10 x64 build 1607
接下来我们在kali2.0里运行漏洞脚本。
随后执行"dir \ip\PATH",漏洞触发,通过windbg双机联调,此时捕捉到了BSOD。
可以看到提示此时问题出现在mrxsmb20.sys中,问题函数是Smb2ValidateNegotiateInfo,来看一下触发位置的代码。
kd> p
mrxsmb20!Smb2ValidateNegotiateInfo+0x17:
fffff803`1869c7d7 66394114 cmp word ptr [rcx+14h],axkd> r rcx
rcx=0x00000000`00000000
此时rcx的值为0x0,是一处无效地址,因此这是由于空指针引用导致的BSOD,接下来继续执行可以看到Windows 10引发蓝屏。
回溯及数据包分析(important!)
我们来看一下mrxsmb20.sys关于Tree Connect特性的一些内容,代码逻辑相对简单。
可以看到执行到Smb2ValidateNegotiateInfo函数有两条逻辑调用,一个是Smb2TreeConnect_CopyData,一个是Smb2TreeConnect_Receive,这里我就把我回溯的结果和大家分享一下,首先,通过Smb2TreeConnect_Receive来接收smb的Tree Connect数据,这个是通过opcode来决定的。
正常情况下不会进入Smb2TreeConnect_CopyData,但一旦由不正常(后面会提到)数据包执行,则会在Receive之后进入CopyData函数的处理逻辑,从而引发漏洞。
这里数据包分析很关键,因为在漏洞触发过程中,就是由于数据包的问题导致的。