2019 年 5 月 14 日微软官方发布紧急安全补丁,修复了 DHCP 的 RCE 漏洞(CVE-2019-0725)。微软对CVE-2019-0725的 CVSS 3.0评级的基本评分为8.1,意味着攻击很复杂,比较难造成远程代码执行。该漏洞为竞争条件引起的 UAF ,会造成服务器崩溃,进而导致服务器的dos。
Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
Windows Server 2012
Windows Server 2012 (Server Core installation)
Windows Server 2012 R2
Windows Server 2012 R2 (Server Core installation)
Windows Server 2016
Windows Server 2016 (Server Core installation)
Windows Server 2019 Security Update Remote Code Execution Critical
Windows Server 2019 (Server Core installation)
Windows Server, version 1803 (Server Core Installation)
Windows Server, version 1903 (Server Core installation)
客户端请求 IP 地址,会广播 discover 请求。当有 DHCP 服务器响应该请求时,会广播一个 offer 报文,其中包含将要分配给客户端的 IP /掩码/DNS,等信息。然后客户端发送 request ,确认请求的 IP 。如果服务器接收到该报文,会发送 ACK 确认将该 IP 分配给客户端
补丁前后文件对比,发现变动为离开临界区之前取出[rbx+4ch]数值。
发生变动的函数为 dhcp!ProcessDhcpDiscover ,即,处理客户端发出的 Discover 请求。
经过调试及分析,发现rbx指向的为一个结构体( PendingCtxt )。[rbx+4ch] 为一个 flag (当服务器回复客户端 offer 之后,会将该 flag 置 1)。
PendingCtxt 的结构体前 10h 为 dhcpssvc!Buckets+c0h ,其中 0xc0 是根据客户端的 MAC 地址计算出来的 hash。可以发现,同一个 MAC 地址在 buckets 中的占位是一样的。即,可以找到 PendingCtxt 的指针。PendingCtxt结构存储在堆中,包括客户端硬件地址/租约/续订/重新绑定时间/分配给客户端的IP地址以/是否已为此特定项发送了OFFER的标志,等信息。
000007f9`a6681c10 000007f9a6681c10 dhcpssvc!Buckets+0xb0
000007f9`a6681c18 000007f9a6681c10 dhcpssvc!Buckets+0xb0
000007f9`a6681c20 000000be9e8ee2f0
000007f9`a6681c28 000000be9e8ee2f0
000007f9`a6681c30 000007f9a6681c30 dhcpssvc!Buckets+0xd0
000007f9`a6681c38 000007f9a6681c30 dhcpssvc!Buckets+0xd0
000000be`9e8ee2f0 000007f9a6681c20 dhcpssvc!Buckets+0xc0 --> 根据mac address计算出来的hash为c0
000000be`9e8ee2f8 000007f9a6681c20 dhcpssvc!Buckets+0xc0
000000be`9e8ee300 000007f9a6681b40 dhcpssvc!PendingList
000000be`9e8ee308 000007f9a6681b40 dhcpssvc!PendingList
000000be`9e8ee310 000000be9e8ee340 --> mac address存储地址
000000be`9e8ee318 ac18ab6400000006 --> [rbx+2c]=ac18ab64=172.24.171.100为client分配的地址,6=sizeof(mac address)
000000be`9e8ee320 00054600000a8c00
000000be`9e8ee328 0000000000093a80
000000be`9e8ee330 01d50c81937b1810
000000be`9e8ee338 0000000100000000 --> [rbx+4c]=1 offer flag
服务器如果根据客户端的 MAC地址没有找到 PendingCtxt ,会构造该结构体。
调用流程为: dhcpssvc!ProcessingLoop+0x308 à dhcpssvc!ProcessPacket+0x1a7
-->
dhcpssvc!ProcessMessage+0x4f9
--> dhcpssvc!ProcessDhcpDiscover+0xa97
--> dhcpssvc!DhcpProcessDiscoverForValidatedAddress+0x16c à dhcpssvc!DhcpAddPendingCtxt+0x166
如果存在,则会走到打补丁的函数块,使用之前已经构造好的结构体。
由 diff 可以推断,该漏洞是因为多个进程同时操作PendingCtxt 结构体引起的。因为打补丁之后,为取出 PendingCtxt的offer flag 之后再离开临界区。且,调试发现同时存在两个 dhcpssvc!ProcessingLoop 线程。
因此,触发崩溃的关键点是,如果在离开临界区之后,进入临界区之前的窗口, 释放掉这个结构体。通过趋势科技的分析可知, 客户端发出的 release 请求,可以释放掉PendingCtxt ,如果可以在处理 discover 正处于离开临界区且未进入临界区时,处理一个可以释放该结构体的 release 请求。则可发生访问堆越界。
1. 开启页堆保护:
PS C:\Program Files\Windows Kits\10\Debuggers\x64> .\gflags.exe -i svchost.exe +hpa
Current Registry Settings for svchost.exe executable are: 02000000
hpa - Enable page heap
2. 下断点:
bu dhcpssvc!ProcessDhcpDiscover+0x4a2 "~#;.echo;r rbx;.echo;"
bu dhcpssvc!DhcpAddPendingCtxt+0x166 ".printf\"dhcpssvc!DhcpAddPendingCtxt+0x166\";.echo;~#;.echo;r rdi;.echo;g"
bu dhcpssvc!dhcpdeletependingctxt ".printf\"dhcpssvc!dhcpdeletependingctxt\";.echo;~#;.echo;r rcx;.echo;g"
3. client 发送 discover 请求,两个以上。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-6-1 21:57
被祈寒Alice编辑
,原因: