收藏 [登录/注册] 欢迎
榕基门户网及子站
联系我们
  • 福建榕基软件股份有限公司
  • 电话:0591-87860988
  • 传真:0591-87869595
  • 地址:福建省福州市鼓楼区
  •    软件大道89号
  •    A区15座
  • 邮编:350003
您的当前位置:首页 > 技术支持 > 安全公告

CVE-2018-8476: Windows服务器部署服务漏洞

简介

许多企业都使用Windows Deployment Services(WDS,Windows部署服务在网络中的新机器上安装定制的操作系统。WDS其实可以由任意通过LAN端口链接的用户访问,并提供相关的软件。

那会不会有攻击者黑掉服务器,修改相关内容来控制每个新计算机的内容,并安装恶意软件呢?本文就对WDS基础设施以及相关的漏洞利用进行分析。

Windows Deployment Services

WDS是微软提供的基于网络的Windows操作系统安装解决方案。WDS使用的是磁盘镜像,主要是Windows Imaging Format (WIM)格式。Windows Server从2008年开始就将该服务包含在32位和64位版本中。WDS是个很复杂的系统,本文介绍WDS新安装的预认证协调过程及潜在攻击方式。

在分发完整的Windows镜像前,WDS必须提供完整的网络启动策略,因此使用了PXE (Preboot eXecution Environment,预启动执行环境)服务器。PXE是Intel创建的一个标准,工作于Client/Server的网络模式,支持工作站通过网络从远端服务器下载映像,并由此支持通过网络启动操作系统,在启动过程中,终端要求服务器分配IP地址,再用TFTP(trivial file transfer protocol)或MTFTP(multicast trivial file transfer protocol)协议下载一个启动软件包到本机内存中执行,由这个启动软件包完成终端(客户端)基本软件设置,从而引导预先安装在服务器中的终端操作系统。

模糊测试

研究人员首先用Boofuzz创建了一个TFTP dumb fuzzer。

Tftp.py 定义了要进行模糊测试时的协议语义和域。因为fuzzer是通用的,因此代码可以用来测试所有的TFTP实现和应用。在运行fuzzer时,研究人员手动逆向了wdstftp.dll中应用的服务器。

wdstftp.dll

研究人员逆向该dll时,首先检查了CTftp::ParseRequest应用的文件读取机制。CTftpPacket::ParseRequest中会处理TFTP Read Requests (RRQ)。在验证了PXE base目录中是否存在请求的文件后,就会被读入CTptReadFile::CacheBlock结构。

CVE-2018-8476: Windows服务器部署服务漏洞

图1: CacheBlock Struct

这些CacheBlocks是在一个链接的列表中操作和管理的。

服务器会用分配做回调函数的CTptReadFile::_IOCompletionCallback异步执行ReadFiles 。

CVE-2018-8476: Windows服务器部署服务漏洞

图2: ReadFile回调

然后研究人员发现一个非常奇怪的行为,就是CacheBlocks链接的列表的大小也是有限制的,最大是2。

CVE-2018-8476: Windows服务器部署服务漏洞

图3: maxCacheBlocks = 2

如下图所示,当cache block的数量大于2时,位于尾部的就会被删除。

CVE-2018-8476: Windows服务器部署服务漏洞

图4: free tail

根据对TFTP协议的了解以及blksize 和windowsize选项的使用,研究人员可以伪造一个请求来在接收ack包之前增加超过2个cache block。如果一切顺利,且计数正确,会有一个cache block在回调函数CTptReadFile::_IOCompletionCallback使用前被释放。

然后设置(page heap on)。

CVE-2018-8476: Windows服务器部署服务漏洞

图5: windbg奔溃

可以看出RAX现在指向了释放的内存,这也说明Windows Deployment Services中存在UAF(Use-After-Free)漏洞。

这个bug看似很简单,为什么fuzzer没有发现呢?原因很简单,就是Sulley框架一次只测试一个域,研究人员测试中的请求读操作无法持续那么久。因此,未来在进行模糊时既要考虑包的有效性,也不能太有效。

利用方法 

因为这是一个远程触发的、非认证的、高权限的Windows服务器漏洞,研究人员将其标记为高危(critical)漏洞。

在利用UAF漏洞时,研究人员一般会分配不同的对象或分配不同状态的相似对象,这会导致他们之间产生有些混淆。

在寻找允许研究人员分配与释放的区域匹配的对象的分配原语(allocation primitives)时,研究人员检查了进程heap。

事实证明,WDS其实使用了多个heap,研究人员发现的这个heap是wdstftp.dll, wdssrv.dll 和wdsmc.dll共享的。

虽然wdstftp.dll考虑了一些比较灵活的分配方式,比如TFTP错误包中就是被转换为Unicode编码的ASCII码。

CVE-2018-8476: Windows服务器部署服务漏洞

图6: Unicode POC

对PoC来说这是一个很好的原语(primitiv),但是构造一个功能payload有点复杂。

下一个分配原语机制是wdssrv.dll。它暴露了一个WDS服务器提供的远程调用服务的RPC接口。

在寻找攻击者可以控制的分配时,研究人员发现了CRpcHandler::OnRecvRequest。该RPC handler在将自己插入到要处理的队列之前负责做一些RPC请求的初步语义分析。为了使用那些释放的内存,研究人员需要使用相同的Heap bucket (size 0x5c-0x78)。在handler中唯一可以控制大小的分配就是CMemoryBuffer::Initialize。

CVE-2018-8476: Windows服务器部署服务漏洞

图7: RPC分配原语

下面的脚本可以执行与模板bucket匹配的分配。

CVE-2018-8476: Windows服务器部署服务漏洞

图8: RPC POC

但是大多数的结构和CacheBlocks callbackCtx指针都没有接触到。

CVE-2018-8476: Windows服务器部署服务漏洞

图9: 使用RPC POC的内存布局

如果修改RPC payload,因为CMemoryBuffer::Initialize执行的大小计算,就会被分配一个错误的bucket。

下一个想法是是否可以修改CacheBlocks域来进行权限提升。

研究人员逆向发现CTftpReader并不能使用它们。因此研究人员使用一种不同的方式来利用该漏洞,即尝试利用来bug来获取服务器的关键信息泄露。在标准场景下,IOCompletionCallback会在与文件内容匹配的CacheBlock上调用,然后发送内容给研究人员。

通过混淆服务器并植入新的没有文件内容的CacheBlock,研究人员希望该服务器可以发送新CacheBlock的未初始化的内存,造成关键信息泄露。在进行多次尝试后,研究人员接收到的不是未初始化的内存而是部分文件内容。研究人员怀疑要处理大量文件读写请求的繁忙的服务器在读取TFTP图片时会更慢,这也就增加了赢取竞争条件的可能性。

结论

WDS是一个用于镜像安装的被广泛使用的Windows服务器服务。其底层的PXE服务器有一个高危的远程释放UAF bug,可能会被未认证的攻击者所利用引发远程代码执行。研究人员将该漏洞报告给了微软,被分配的CVE编号为CVE-2018-8476,影响Windows server 2008 SP2之后版本。

由于时间关系,研究人员没有进一步寻找关于该漏洞的利用方法,但Check Point和微软研究人员都确认该漏洞是可以被利用的。