Paul Stone和Alex Chapman在Blackhat2015提出了一个关于Windows Server Update Service (WSUS) 的漏洞。攻击者可以用中间人(Man In The Middle, MITM)攻击利用该漏洞,让用户下载并且安装伪造的更新。
众所周知,微软通过Windows更新服务 (update service)给用户提供更新。客户端周期性的运行wuauctl.exe与更新服务器通信, 以检查目前是否有新的更新。如果有,便下载安装这些更新。在企业环境下,成千上万的客户端重复下载相同的更新无疑会对带宽造成极大的浪费。而且管理员也很难对更新安装进行有效的控制。
Windows Server Update Service (WSUS) 很好的解决了这个问题。WSUS可以说是一个更新代理服务器:WSUS 服务器从Internet下载了更新并且将其缓存在本地, 并对网络里的其他windows计算机提供更新服务。这样一来,网络里的其他windows计算机就要从这个WSUS服务器下载更新,而不是从Internet。
1. 客户端上WSUS的连接设置
在注册表中, 检查HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU中UseWUServer的值是否为1 (1 为启用,0为禁用)。
WSUS的具体连接设置保存在HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\WUServer例如,http://wsus-server.com:8530,http是下层连接协议,wsus-server.com是WSUS服务器的域名,8530是端口号。
当然,如果WSUS服务器支持的话,我们也可以用https来取代http。但是微软的默认设置是http。而且大多数企业也不愿意负担高额的证书费用来支持https。
2. WSUS 协议
WSUS 用封装在HTTP里的SOAP XML消息来通讯。客户端首先告诉更新服务器自己已经安装了哪些更新(SyncUpdates)。更新服务器则返回一个结果(SyncUpdatesResult),说明服务器上还有哪些新的更新可以提供给客户端。客户端进一步询问新的更新的具体信息(GetExtendedUpdateInfo)。最后更新服务器把具体信息告知客户端(GetExtendedUpdateInfoResult)。如图所示,注意SyncUpdates 发了两遍,第一次是为软件更新,第二次是为硬件驱动更新。
根据上图,给个直观的例子吧:
下载后,客户端会检查一下该更新的哈希值和签名,如果一切正常,客户端会自动安装该更新或者提醒用户手动安装。
3. 风险
WSUS服务器默认只支持http。我们知道http本身并不安全,无法保证消息的机密性,完整性, 也无法让客户端对服务器进行认证。所以攻击者可以用中间人(Man In The Middle, MITM)来劫持WSUS通信,插入伪造的更新信息来欺骗客户端。很多方法可以进行中间人攻击,比如利用arp欺骗,这里不进行深入讨论。本文侧重于如何伪造WSUS消息。
攻击者可以在SyncUpdatesResult插入伪造的更新ID,然后在GetExtendedUpdateInfoResult 中继续提供伪造的URL等,欺骗客户端下载并安装,如下图所示
一个攻击的例子如下:
在这种情况下,客户端就会从http://wsus.evil.com/update/ 下载evil.exe。请注意,这里还有一层保护机制: 所有下载的软件更新都必须有微软签名。如果签名验证不成功,那么该下载的更新会被立即删除。我们知道微软的签名还是很难伪造的,那是不是就没有办法了呢?
其实我们没有必要伪造签名,想想那些已经被微软签名的软件,特别是sysinternals的工具,很多都可以用来做坏事的,比如说psexec 和bginfo,都是有微软签名的程序。(第一个想到的是cmd.exe,但是cmd.exe其实并没有被微软签名)
这样,攻击者就可以把psexec或者bginfo伪装成更新,配以构造的安装脚本,推送到客户端得以安装运行。
4. Proof Of Concept (POC)
Paul Stone和Alex Chapman提供的POC似乎有一些bug,至少我没有测试成功。在这里我提供一个本人修改过的POC。这个POC的目的是把bginfo伪装成一个更新,推送给客户端,使其下载安装。
我在本地用burp suite劫持并修改WSUS消息:
1.把以下消息插入到第一个SyncUpdatesResult 消息中,<Truncated>false</Truncated> 的前面;
2.第二个SyncUpdatesResult 消息是关于硬件驱动的,不用修改,直接放过;
3.删除GetExtendedUpdateInfo 消息中的<int>19999992</int> <int>19999993</int>,然后放过;
4.在GetExtendedUpdateInfoResult 消息中的<Updates>…</Updates>中加上;
Url 标签中的yoururl 填你自己的主机名。
打完收工,发现伪造的更新信息已经被客户端接受了。
查看一下这个更新的具体信息。
发现bginfo.exe已经被下载到了本地。
试着安装一下,成功!
*FreeBuf特约作者:nickchang ,未经许可禁止转载