标题: 浅析Nessus、Nmap针对MS17-010的远程精确扫描方案 创建: 2017-06-22 15:21 更新: 链接: https://scz.617.cn/windows/201706221521.txt 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一类的大型框架,两个字,太重。更多时候他们只是为了熬过这一拨热点 或应付上级检查。此处提供一个采用Nessus扫描方案的Windows版单扫工具: https://scz.617.cn/windows/MS17-010-Nessus.exe 万一有运行时库方面的问题,自行解决吧。除了下面演示的命令行参数,其他五花八 门的命令行参数无需关心,那是历史遗迹。 指定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][@]