Skip to content

Latest commit

 

History

History
112 lines (56 loc) · 6.82 KB

CVE-2020-1034:Windows 内核提权漏洞分析.md

File metadata and controls

112 lines (56 loc) · 6.82 KB

> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [mp.weixin.qq.com](https://mp.weixin.qq.com/s/5zgHHclTC0VhgvK8p1d0\_g)

漏洞概述

Windows 内核在处理内存中对象的时候,存在一个提权漏洞。攻击者将能够利用该漏洞实现提权,并在目标设备上实现代码执行。为了利用该漏洞,经过了身份认证的本地攻击者可以在目标主机上运行一个专门设计的应用程序。在这篇文章中,我们将对这个漏洞 CVE-2020-1034 进行深入分析。

补丁对比

受影响的模块为 ntoskrnl.exe,我下载了该模块的已修复版本和未修复版本,并在 Windows 10 1903 x64 系统上对其进行了分析比对。

下面给出的是版本 18362.1049 和 18362.1082 之间的源码对比结果:

很明显,EtwpNotifyGuid 发生了变化,因此我对该函数源码进行了简单分析,并发现了一个重大改变:

因此,我决定对其进行深入分析。

漏洞分析

首先,我研究了一下 EtwpNotifyGuid 的网关,也就是 NtTraceControl。

调用 EtwpNotifyGuid 的 FunctionCode 为 0x11,而且在调用之前还需要进行一些条件检测,具体如下图所示:

在对 EtwpNotifyGuid 的分析过程中,我们还发现了下面这些有意思的修复点:

rdi 寄存器包含收入缓冲区的地址,图表中的数据表明地址 rdi+0Ch 的字节数据决定了是否去创建一个 UmReplyObject 对象。

接下来,我们看看 r12b 寄存器的值是从哪里来的:

r12b 的初始值为 4,但是这里被设置成了 1。因此,当 byte ptr [rdi+0Ch] 的值为 1 时,rdi+18h 的 qword 会被设置为新创建的 UmReplyObject 的地址。否则,qword 将保持原样。这将引起非常严重的后果,因为输入数据永远不可信。

我将 rdi+18h 的 qword 设置为了一个任意值,正如我们所料,设备蓝屏了:

这就非常棒了,我们继续。

这里的输入缓冲区被传递给了 EtwpSendDataBlock 和 EtwpQueueNotification:

查看 EtwpQueueNotification,我发现了引用 UmReplyObject 的地方:

这里的 bl 值为 0,如果 rbp+0Ch 的字节值不为 0,那么 rbp+18h 的 qword 会被读取为一个指向对象的指针,然后对象的引用将会增加。

我们知道了漏洞的根源,罪魁祸首就是代码对 rbp+0C 字节数据的不一致对比。对比操作是在 EtwpNotifyGuid 中进行的,代码会比较值是否为 1 来判断是否需要创建一个新的 UmReplyObject 对象。但在最后一次比较中,将该值与零进行了比较。

第一次比较在 C 代码中的形式如下:

if(\*(bool\*)(rdi+0x0C)==  true)

第二次比较的代码形式如下:

if (\*(bool\*)(rbp+0x0C))

如果值不是 1 或者 0 的话,任何输入的值都将被视作对象地址。接下来,ObfReferenceObject 将会调用该地址,这也就意味着 qword ptr [[InputBuffer + 0x18] - 0x30] ++ 运算将会被执行,这样将导致任意地址增加。

漏洞利用代码

漏洞演示视频

交易担保 FreeBuf+ FreeBuf + 小程序:把安全装进口袋 小程序

精彩推荐