浅析Nessus、Nmap针对MS17-010的远程精确扫描方案

作者: saya 分类: 渗透测试 发布时间: 2019-01-14 14:58

Nessus、Nmap为Eternalblue提供了远程精确扫描插件,更确切地说,它们可以远程判断目标系统是否安装了MS17-010补丁。Wireshark抓包,可以看出扫描原理。建立空会话,发送特定的PeekNamedPipe Request,检查响应报文中的NT Status,如果等于STATUS_INSUFF_SERVER_RESOURCES(0xc0000205),报漏洞。由于Nessus、Nmap的插件都是脚本源码,静态看一样可以看出扫描原理。一般来说,外界没有现成资源可供参考的时候,通用办法是通过补丁比较研究精确扫描方案。

OS是32-bits Win7,这个没必要用64-bits,除非漏洞只影响后者。old是6.1.7601.17608版srv.sys,new是取自MS17-010的6.1.7601.23689版srv.sys。用IDA 6.9分别对old、new进行反汇编,然后用BinDiff 4.2进行二进制比较。在”Matched Functions”中寻找SrvPeekNamedPipe(),它是PeekNamedPipe Request对应的函数。我看到的是:

1.00 0.99 ——- 99A34BF6 SrvPeekNamedPipe(x) 9A575A2D SrvPeekNamedPipe(x)

similarity 1.00
confidence 0.99
change ——-

意思是,SrvPeekNamedPipe()在old、new中没有发生变化。在”Matched Functions”中直接看similarity小于1的项,与扫描方案可能相关的有:

0.99 0.99 -I—– 99A484BA SrvRestartPipeWriteAndX(x) 9A589462 SrvRestartPipeWriteAndX(x)
0.98 0.99 GI-JE– 99A36D86 BlockingSessionSetupAndX(x) 9A577BBD BlockingSessionSetupAndX(x)
0.96 0.99 GI—– 99A4EF2A SrvRestartExecuteTransaction(x) 9A59012D SrvRestartExecuteTransaction(x)
0.96 0.99 GI–E– 99A4D23A ExecuteTransaction(x) 9A58E253 ExecuteTransaction(x)
0.96 0.99 GI-JE– 99A4D65C SrvSmbTransaction(x) 9A58E6C8 SrvSmbTransaction(x)
0.95 0.99 GI–E– 99A47846 SrvSmbWriteAndX(x) 9A58872C SrvSmbWriteAndX(x)
0.95 0.99 GI—– 99A4EB3D SrvSmbNtTransactionSecondary(x) 9A58FCDF SrvSmbNtTransactionSecondary(x)
0.94 0.99 GI—– 99A4E0E5 SrvSmbTransactionSecondary(x) 9A58F1B0 SrvSmbTransactionSecondary(x)
0.92 0.98 GI–E– 99A4E488 SrvSmbNtTransaction(x) 9A58F5B4 SrvSmbNtTransaction(x)
0.89 0.98 GI-JE– 99A4CA68 SrvCompleteExecuteTransaction(x,x) 9A58DA55 SrvCompleteExecuteTransaction(x,x)
0.88 0.96 GI-JE– 99A4C5E1 SrvFindTransaction(x,x,x) 9A58D589 SrvFindTransaction(x,x,x)

SrvSmbTransaction
ExecuteTransaction
SrvPeekNamedPipe
SrvVerifyFid2
SrvCompleteExecuteTransaction

SrvPeekNamedPipe()没有变化,但它的主调函数ExecuteTransaction()有变化,同时在它之后被调用的SrvCompleteExecuteTransaction()也有变化。在”Matched Functions”中选中SrvCompleteExecuteTransaction()右键菜单->View Flowgraphs(Ctrl-E)这将打开BinDiff展示old与new中SrvCompleteExecuteTransaction()的对比。在BinDiff中看到old中有一处”比较跳转”在new中被删掉了,对应old中的红色块。由于缺少私有符号信息,不太容易静态分析这处修改的意图所在,决定针对old设断点动态调试。结果发现扫描都完成了,old中的断点并未命中。进而在动态调试中发现,对于old,流程干脆没有进入srv!ExecuteTransaction()。只能在SrvSmbTransaction中找原因了。

0.96 0.99 GI-JE– 99A4D65C SrvSmbTransaction(x) 9A58E6C8 SrvSmbTransaction(x)

change列的J是Jump的意思,表示至少有一处”比较跳转”发生了变化。在BinDiff中检查第一个红块

————————————————————————–
99A4D98C 6A 10 push 10h
99A4D98E 58 pop eax
99A4D98F 39 45 D0 cmp [ebp+maxParameterCount], eax
99A4D992 73 03 jnb short loc_99A4D997
————————————————————————–

在old中查看0x99A4D98C附近代码,实际对应:

————————————————————————–
if ( command == TRANS_PEEK_NMPIPE )
{
maxParameterCount = MAX( maxParameterCount, 4 * sizeof(ULONG) );
}
————————————————————————–

在new中这段代码变成:

————————————————————————–
if ( command == TRANS_PEEK_NMPIPE )
{
maxParameterCount = 4 * sizeof(ULONG);
}
————————————————————————–

围绕此处修改,通过逆向工程可以得出精确扫描原理所在。

MS17-010修改了srv!SrvSmbTransaction()。处理”PeekNamedPipe Request”时,以前会使用来自客户端的maxParameterCount,安装补丁后将maxParameterCount固定成16。这个修改会影响一次内存分配,Nessus插件发出的”PeekNamedPipe Request”在安装补丁前会导致内存分配失败,从而返回STATUS_INSUFF_SERVER_RESOURCES(0xc0000205),安装补丁后内存分配成功,流程到达ExecuteTransaction()、SrvPeekNamedPipe()、SrvVerifyFid2(),由于”PeekNamedPipe Request”中FID是无效的0,从而返回STATUS_INVALID_HANDLE(0xc0000008)。这是Win7补丁带来的变化,Win10类似,修补后返回STATUS_ACCESS_DENIED(0xc0000022)。

Nmap的扫描原理完全同Nessus,细节上有两处微不足道的区别。一是”Session Setup AndX Request”中的”Max Buffer”,Nmap用0xffff,Nessus用0x4400。二是”PeekNamedPipe Request”中的”Transaction Name: \PIPE\”,受Flags2影响,Nmap使用ASCII串,Nessus使用Unicode串。这两处区别无关紧要。Nessus、Nmap的扫描方案不依赖于读超时,针对Win10不会漏报。很多网络运维人员并不关心远程精确扫描方案的技术原理,也不太喜欢用诸如Nessus、Metasploit一类的大型框架,两个字,太重。更多时候他们只是为了熬过这一拨热点或应付上级检查。万一有运行时库方面的问题,自行解决吧。除了下面演示的命令行参数,其他五花八门的命令行参数无需关心,那是历史遗迹。

指定IP范围:

$ MS17-010-Nessus.exe -q -m -b 192.168.0.1 -e 192.168.255.254 -o scan.out

指定目标主机列表(每行一个目标):

$ MS17-010-Nessus.exe -q -m -l hostlist -o scan.out

该漏洞可以通过139/TCP利用,不限于445/TCP:

$ MS17-010-Nessus.exe -q -m -b 192.168.0.1 -e 192.168.255.254 -o scan.out -p 139
$ MS17-010-Nessus.exe -q -m -l hostlist -o scan.out -p 139

如果不指定”-o scan.out”,向stdout输出

-q

只显示vulnerable主机,否则将显示safe、unknown等其他主机

-m

实时显示当前扫描目标,可以不指定

scan.out的输出形如:

xx.xx.xxx.xx safe [Unix|Samba 3.6.25|WORKGROUP][@WORKGROUP]
xx.xx.x.xx vulnerable [Windows 7 Ultimate 7600|Windows 7 Ultimate 6.1|WORKGROUP][APPLE-PC@WORKGROUP]
xxx.xxx.xx.xxx vulnerable [Windows 7 Ultimate 7601 Service Pack 1|Windows 7 Ultimate 6.1|WORKGROUP][USER-20160307TC@WORKGROUP]
xxx.xxx.xx.xxx vulnerable [Windows 10 Pro 10240|Windows 10 Pro 6.3|WORKGROUP][DESKTOP-7DGEL49@WORKGROUP]
xxx.xxx.xx.xxx vulnerable [Windows Server 2008 R2 Enterprise 7601 Service Pack 1|Windows Server 2008 R2 Enterprise 6.1|WORKGROUP][WIN-UV3JAC9UP5A@WORKGROUP]
xx.xx.x.xxx 0xFFFF0002 [OS 1.00|SMB 1.0|WORKGROUP][@]

 

扫描工具下载

 

转载 青衣十三楼

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签云