12.10 远程使用WMI https://scz.617.cn/windows/201106281108.txt Q: 我想通过WMI远程获取目标主机所有IP地址。 在MSDN中搜索"WMI Tasks for Scripts and Applications",发现如下vbs脚本: -------------------------------------------------------------------------- strcomputer = "." set objwmiservice = getobject( "winmgmts:\\" & strcomputer & "\root\cimv2" ) set ipconfigset = objwmiservice.execquery( "select ipaddress from win32_networkadapterconfiguration" ) for each ipconfig in ipconfigset if not isnull( ipconfig.ipaddress ) then for i = lbound(ipconfig.ipaddress) to ubound(ipconfig.ipaddress) wscript.echo ipconfig.ipaddress( i ) next end if next -------------------------------------------------------------------------- cscript.exe //nologo getlocalip.vbs wscript.exe //nologo getlocalip.vbs 在本机执行上述脚本可以成功得到本机所有IP。然后,我strcomputer换成目标IP 地址,试图远程获取目标主机所有IP地址,这次失败了。 >cscript.exe //nologo getremoteip.vbs getremoteip.vbs(2, 1) Microsoft VBScript 运行时错误: 没有权限: 'getobject' >wscript.exe //nologo getremoteip.vbs 错误代码: 800A0046 A: scz@nsfocus 2011-06-28 11:08 远程使用WMI有很多麻烦之处,尤其当client、server两端均做过安全加固时。下面 以探索、记录的方式介绍其中的细节,结论不见得普适,读者请发挥主观能动性,重 在领会精神。 看到错误代码800A0046,第一反应是远程使用WMI需要认证,改写getremoteip.vbs如 下: -------------------------------------------------------------------------- strcomputer = "10.17.2.74" set objswbemlocator = createobject( "wbemscripting.swbemlocator" ) set objwmiservice = objswbemlocator.connectserver _ ( _ strcomputer, _ "root\cimv2", _ "\test", _ "test" _ ) set ipconfigset = objwmiservice.execquery( "select ipaddress from win32_networkadapterconfiguration" ) for each ipconfig in ipconfigset if not isnull( ipconfig.ipaddress ) then for i = lbound(ipconfig.ipaddress) to ubound(ipconfig.ipaddress) wscript.echo ipconfig.ipaddress( i ) next end if next -------------------------------------------------------------------------- 在MSDN中搜索"Connecting to WMI on a Remote Computer"了解更多细节。这次使用 了SWbemLocator,就是为了指定user/pass。蹊跷的是,仍失败了: >cscript.exe //nologo getremoteip.vbs getremoteip.vbs(3, 1) SWbemLocator: 拒绝访问。 >wscript.exe //nologo getremoteip.vbs 错误代码: 80070005 放狗搜"GetObject 800A0046"、"SWbemLocator 80070005",那叫一个群魔乱舞。觉 悟了,还得自己用Wireshark抓包。 参RemoteWMI_0.cap,只向目标137/UDP发了一个nbtstat的包,得到响应之后再无其 它报文出现。这完全不像是服务端权限检查失败,更像是客户端什么配置出问题了。 中间测试过程不说了,就说结论吧,我曾在客户端动用dcomcnfg禁用了DCOM,以前以 为这只会影响DCOM Server的行为,没想到这同时影响了DCOM Client的行为。为了远 程使用WMI,需要启用DCOM: dcomcnfg.exe 控制台根节点 组件服务 计算机 我的电脑、右键属性 默认属性 在此计算机上启用分布式COM(默认是勾中的) 确保该页上默认身份验证级别是连接,默认模拟级别是标识。 dcomcnfg.exe 控制台根节点 组件服务 计算机 我的电脑、右键属性 默认协议 面向连接的TCP/IP 我当时把这里的协议都删光了,至少要将"面向连接的TCP/IP"增加回来。做完上述修 改后必须重启OS使之生效,如果不重启,情况还是发生变化了,只是部分生效,仍有 问题: >cscript.exe //nologo getremoteip.vbs getremoteip.vbs(3, 1) SWbemLocator: RPC 服务器不可用。 >wscript.exe //nologo getremoteip.vbs 错误代码: 800706BA 放狗搜"SWbemLocator 800706BA"会把你带到沟里去,那些解答都集中在DCOM Server 端,而这次我们的问题仍在DCOM Client端,通过Wireshark抓包发现通信情况完全同 RemoteWMI_0.cap。这告诉我们,错误提示并不总能引领我们前往正确的方向,真正 靠谱的还是抓包观察通信过程。假设已经重启过DCOM Client所在OS,如果还碰上问 题,再关心DCOM Server端的设置。 客户端会通过MS/DCE RPC调用IOXIDResolver接口的ServerAlive2 (5)远程过程,以 此判断服务端是否禁用了DCOM,这个接口的UUID如下: 99fcfec4-5260-101b-bbcb-00aa0021347a 0.0 假设服务端禁用了DCOM,一般情况下远程使用WMI对应的通信过程参RemoteWMI_1.cap 的7号报文。客户端得到的错误代码仍是"SWbemLocator 800706BA"。需要注意的是, 假设服务端干脆没有侦听135/TCP,又或者沿线防火墙一类的设备禁止访问服务端的 135/TCP口,客户端同样得到"SWbemLocator 800706BA"。这再次提醒我们,错误提示 仅供参考,真要了解深层次原因并彻底解决问题,还得抓包观察。 假设服务端已经启用了DCOM,有一个Users组的帐号test,远程使用WMI对应的通信过 程参RemoteWMI_2.cap: >cscript.exe //nologo getremoteip.vbs getremoteip.vbs(3, 1) SWbemLocator: Access is denied. >wscript.exe //nologo getremoteip.vbs 错误代码: 80070005 抓包可以看出身份认证失败。如果身份认证通过,应该看到RemoteWMI_3.cap: >cscript.exe //nologo getremoteip.vbs getremoteip.vbs(3, 1) SWbemLocator: Access denied // 与前面那个有细微区别 >wscript.exe //nologo getremoteip.vbs 错误代码: 80041003 这应该是最常见的情形,因为服务端默认启用DCOM,写vbs时一般会提供有效帐号、 口令,但远程使用WMI仍然失败。单就getremoteip.vbs而言,需要在服务端做如下操 作: wmimgmt.msc WMI Control (Local)、右键属性 安全 Root CIMV2 安全设置 在这里增加test帐号,赋予且只赋予"远程启用"权限,重启OS使之生效。再次执行 getremoteip.vbs,成功,抓包见RemoteWMI_4.cap。如果ConnectServer()中指定管 理员帐号,就不必在服务端执行wmimgmt.msc进行权限设置。 远程使用WMI时,最终会访问"Windows Management Instrumentation"服务侦听的动 态TCP端口,如果沿线防火墙一类的设备禁止访问这些动态TCP端口,同样会失败,而 错误提示不会让你明白问题真正所在,必须抓包。 D: scz@nsfocus 微软提供了WMIDiag.exe,可以在XP、2003上运行,但不支持Win7。 The WMI Diagnosis Utility Version 2.0 http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=7684 http://download.microsoft.com/download/5/d/a/5da164b9-95ef-4886-bf7c-04459cb6857a/WMIDiag.exe Windows自带"Windows Management Instrumentation 测试器",wbemtest.exe,可能 你以前从未用过,有兴趣了可以试试,至少可以配合Wireshark抓包以排查问题。在 Connect处默认可能是"root\default",你可以试"\\10.17.2.74\root\cimv2"。 在前述测试过程中,test帐号只隶属于Users组,没有额外赋予其它特权,比如没有" 管理审核和安全日志"特权。 dcomcnfg.exe 控制台根节点 组件服务 计算机 我的电脑 DCOM配置 Windows Management and Instrumentation、右键属性 安全 这里的权限设置也会影响远程使用WMI,默认设置一般没问题,排查时可以看看。 secpol.msc 本地策略 安全选项 Network access: Let Everyone permissions apply to anonymous users (Disabled) 有些人解决远程使用WMI所碰到的问题时,启用了这个设置,这也属于邪门外道,不 展开解释了,提出来仅为专业读者备忘。 我这里介绍的重点是排查过程,不是结论本身,最关键的启发是,抓包。 D: scz@nsfocus 下面讨论的内容同样有可能影响远程使用WMI,不抓包几乎不可能排查到这些地方。 2003 SP1对RPC接口提供了额外的安全检查。 一个RPC接口可以调用RpcServerRegisterIf()注册一个回调函数,通过该函数进行访 问控制。 RestrictRemoteClients对所有RPC接口提供了额外的安全检查,即使某接口没有注册 前述回调函数。 -------------------------------------------------------------------------- Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc] "RestrictRemoteClients"=dword:00000001 -------------------------------------------------------------------------- 0 RPC_RESTRICT_REMOTE_CLIENT_NONE 不提供额外的安全检查。接口欲加强安全,只能注册自己的回调函数。 1 RPC_RESTRICT_REMOTE_CLIENT_DEFAULT 除非使用ncacn_np协议序列,否则所有匿名RPC请求被拒绝,这是由RPC运行时库 确保的。 接口注册回调函数时如果指定RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH标志,则 前述限制不作用于该接口。 2 RPC_RESTRICT_REMOTE_CLIENT_HIGH 所有匿名RPC请求被拒绝。 -------------------------------------------------------------------------- 当RestrictRemoteClients不存在时,对于2003 SP1缺省是0,对于XP SP2缺省是1。 使用ncadq_ip_udp、ncadg_ipx被认为是不安全的,当RestrictRemoteClients大于等 于1时,无法使用这两种协议序列访问RPC接口。为了使用这两种协议序列,确保 RestrictRemoteClients等于0。 RPC Endpoint Mapper本身也是一个RPC接口,比如可以通过135/TCP匿名访问它,但 RestrictRemoteClients大于等于1之后,就不能匿名访问了。如果启用了 EnableAuthEpResolution,RPC Client将使用NTLM认证机制去访问EPM接口。 -------------------------------------------------------------------------- Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Rpc] "EnableAuthEpResolution"=dword:00000001 -------------------------------------------------------------------------- 0 禁用 1 启用 -------------------------------------------------------------------------- 这两处注册表设置均可通过组策略实施: gpedit.msc 计算机配置 管理模板 系统 远程过程调用 用于未验证的RPC客户端的限制 RPC终点映射程序客户端验证 考虑到向后兼容性问题,使用ncacn_np协议序列访问RPC接口时,本小节所提及的所 有安全机制不适用。就是说,通过SMB访问RPC时,前述安全机制无效。