0x00 概述
在2020年9月的Windows补丁日,修复了几个漏洞,这些漏洞允许实现内核特权提升。到目前为止,还没有关于这些漏洞的细节或分析文章。
在这篇文章中,我将介绍我对于CVE-2020-1034漏洞的研究。
0x01 补丁差异分析
受影响的模块是ntoskrnl.exe。我下载了该模块的修复后版本和未修复版本,并在Windows 10 1903 x64版本上进行了分析。
修复前后的版本号分别是18362.1049和18362.1082,我们将其进行比较,得到结果如下。
很明显,其中的EtwpNotifyGuid已经进行修改。我仔细查看了该函数,发现了一个明显的变化。
我决定进行进一步研究。
0x02 漏洞分析
首先,我研究了NtTraceControl,这个函数直接通往EtwpNotifyGuid。下面是对于NtTraceControl的描述。
导致调用EtwpNotifyGuid的FunctionCode为0x11。如下图所示,在实际调用之前,还需要满足一些检查条件。
随后,我分析了存在问题的函数。如果仔细分析EtwpNotifyGuid,我们可以发现一些值得关注的地方。这里,需要特别关注修复后的相应位置。
rdi寄存器包含输入缓冲区的地址。在这里,地址rdi + 0Ch位置的字节决定是否创建UmReplyObject。
让我们看看r12b寄存器的值是来源于哪里。
r12b的初始值为4。但是,它将被重置为1。因此,当字节ptr [rdi+0Ch]的值等于1时,rdi+18h位置的qword将设置为新创建的UmReplyObject的地址。
否则,qword将保持不变。这可能会导致危险的后果,因为输入是永远不可信的。
在这里,我们还需要详细确认事实是否就是如此。我将rdi + 18h位置的qword设置为任意值,果然出现了BSOD蓝屏。
在兴奋的同时,我们继续进一步的分析。
输入缓冲区将传递到EtwpSendDataBlock和EtwpQueueNotification。
查看EtwpQueueNotification,我们发现UmReplyObject被引用。
bl的值为0。如果rbp + 0Ch处的字节不为0,则将rbp + 18h处的qword读取为指向对象的指针。并且在这里,增加了对象的引用。
这样一来,就知道了漏洞的根本原因,实际上是rbp + 0C位置的字节比较不一致。
在EtwpNotifyGuid中进行的比较,是将该值与1进行比较,以确定是否创建新的UmReplyObject。
但是在最后一次比较过程中,将该值与0进行了比较。
前面的一次比较,可能类似于C语言代码中的以下内容。
if (*(bool*)(rdi+0x0C) == true)
但后面的一次比较,类似于:
if (*(bool*)(rbp+0x0C))
我们可以看到其中的差别。如果该值不是1或0,那么该怎么办呢?会将任意值作为对象地址。
然后,会调用ObfReferenceObject,这意味着将执行qword ptr [[InputBuffer + 0x18] - 0x30] ++操作。因此,就实现了任意地址的递增。
下面是概念验证代码。
0x03 漏洞利用
该漏洞的利用方式非常简单直接。
在Windows 10 RS3或更低版本的内核,我们可以利用两个相邻的调色板技术。
在Windows 10 RS4或更高版本的内核,我们可以操纵进程Token的Privilege字段。
0x04 总结
如果对布尔指针的值进行显式布尔测试,这种行为是非常危险的。
在此过程中,我花费了大量时间来重现该漏洞,最终证明这是一个非常简单且可靠的漏洞。
Windows内核中包含这种漏洞,无疑是非常令人惊讶的。
在这里,我将不会透露完整的漏洞利用代码,以防范被恶意攻击者利用。
0x05 演示视频
https://blog.br0vvnn.io/upload/demo-cve-2020-1034.mp4
本文翻译自:https://blog.br0vvnn.io/pages/blogpost.aspx?id=2如若转载,请注明原文地址