首页
论坛
课程
招聘
[翻译]CVE-2018-8611 利用 Windows KTM 部分 1/5 – 介绍
2020-5-21 22:05 10633

[翻译]CVE-2018-8611 利用 Windows KTM 部分 1/5 – 介绍

2020-5-21 22:05
10633

概要

在这个由五部分组成的博客文章系列中,我们将讨论Windows内核中的本地特权提升漏洞 CVE-2018-8611的利用。最初,这个漏洞是由卡巴斯基在野外发现 0day 漏洞利用而被披露的。目前尚未发现有关此漏洞的大量公开细节发布,也未公开发布此漏洞的样本。此外,卡巴斯基发现的漏洞利用的哈希值也从未发布过。

 

CVE-2018-8611影响Windows内核的称为内核事务管理器(KTM)的组件,公共的安全社区尚未对此进行过多研究。CVE-2018-8611是一个内核竞争条件漏洞,也是Windows( bochspwn 除外)上讨论得相对较少的一类bug。有趣的是,对KTM的访问不受当前系统调用沙箱过滤器的限制。这不同于通常被沙箱阻止的 win32k组件,例如 Chrome 强制执行的 win32k syscall 过滤器 。这意味着这个漏洞在客户端利用场景中充当了宝贵的沙箱逃逸角色。

 

我们将深入研究 KTM 的内部,展示我们的补丁分析,弄清漏洞的根本原因是什么(借助卡巴斯基相对较少的技术细节),最后讨论了我们开发相当可靠的漏洞利用方法。我们能够开发一种可在x86和x64体系结构上的Windows Vista至Windows 10 1809的所有版本上使用的漏洞利用程序。

 

这项研究由NCC团队漏洞利用开发小组(EDG)的Aaron AdamsCedric Halbronn完成。这项研究首先在 POC2019 上发表,可以在这里找到该演讲的幻灯片。

 

与我们的许多其他公开的 writeup 一样,我们将在进行这项研究时尝试详细解释我们的想法和方法,以帮助刚接触该领域的人们。我们试图突出一些遇到的障碍,错误和死胡同。与往常一样,我们很高兴收到建议,更正和反馈。

入门

已发布的漏洞详细信息

我们最初发现这个漏洞,是阅读了卡巴斯基于2018年12月发布的的 博客。文章指出,2018年10月,卡巴斯基(Kaspersky)一项名为自动漏洞利用防御(AEP)的技术检测到该漏洞的利用,然后将其报告给微软。这导致该漏洞于2018年12月被微软修复。

 

卡巴斯基博客在细节上篇幅讲述较少,但是提供了一些非常有用的提示。老实说,刚开始的时候其中的某些信息感觉没有多大用处,或者只是暂时还没有找到他们之间的关联,但是后来我们加深了对 KTM 和漏洞本身的理解后,他们提供的有关该漏洞利用的信息开始变得越来越有用。

 

卡巴斯基针对漏洞和利用行为的全部公开技术说明均逐字粘贴在以下两段中,当我们描述分析时,我们会不时地提及到它们:

1
2
3
为了滥用这个漏洞,漏洞利用程序首先创建一个命名管道,然后将其打开以用于读和写。然后,它创建一对新的事务管理器对象, 资源管理器对象,事务对象并创建大量登记对象,我们称之为“事务 #2”。登记是一个用于事务和资源管理器之间关联的特殊对象。当事务状态改变时,KTM通知相关的资源管理器。之后,它又创造了一个登记对象,现在才对“事务 #1” 执行操作,并提交事务期间发生的所有更改。
 
在所有的初步工作准备完成后,来到漏洞利用的第二部分——触发漏洞。它创建多个线程并将它们绑定到一个CPU核心。第一个创建的线程在循环中调用 NtQueryInformationResourceManager,而第二个线程试图执行一次NtRecoverResourceManager。但是漏洞本身是在第三个线程中触发。该线程使用 NtQueryInformationThread 的执行技巧获取第二个线程最近一次执行的系统调用信息 NtRecoverResourceManager的成功执行说明已经发生条件竞争情况,并且进一步在先前创建的命名管道上执行WriteFile操作,导致内存崩溃。

这两段中包含很多信息,对于读者来说,其中的大多数现在可能没有多大意义,但是希望您继续阅读。值得注意的是,即使知道如何利用此漏洞,也不是所有的内容都有意义,但可以仅仅表示略有不同的漏洞利用方法。

 

在2019年初利用此漏洞,并随后在2019年10月准备博客和POC演示文稿之后,我们被告知,卡巴斯基于2019年5月在BlueHat Shanghai上提供了有关0day漏洞利用的更多 细节。我们分析了0day漏洞利用的一些技术,并将其与博客系列第5部分中的方法进行了比较。

测试环境

如果您想复现其中的一些工作,我们使用以下工具进行了大部分研究:

  • VMWare Workstation: 虚拟机
  • IDA Pro 使用x86/x64 HexRays 反编译器的IDA Pro反汇编器( 7.3版本中的功能)
  • WinDbg/WinDbg Preview: 同一调试器的两个版本。要在旧系统上进行内核池分析,由于某些错误,您必须使用旧的WinDbg 而不是 WinDbg Preview。在较新的系统上,建议使用WinDbg Preview,因为它速度更快
  • virtualkd: 快速的 Windows VM 内核调试
  • IDArling: 2个人使用的 IDA Pro 合作插件
  • ret-sync: IDA Pro / WinDbg 同步插件以获得更好的开发者体验
  • Diaphora: 用于补丁对比的最佳IDA Pro插件
  • HexRaysPyTools: HexRays 帮助程序插件以递归方式传播(新)类型
  • draw.io: 创建图表

许多在线工具/资源也非常有帮助:

感谢所有开发和维护以上工具和资源的人!

从Windows 7开始

关于从Windows 7上开始,我们进行了一些反复讨论,最后之所以选择它,是因为根据我们在使用 win32k 时的经验,有时会有更多的符号,因此我们认为 KTM 也可能是这种情况-尽管据我们所知最终实际上并没有什么不同。

 

选择 Windows 7 的另一个原因是 IDA 对于包含多个相关文件的项目效果不佳。从Windows 8开始,KTM 从ntoskrnl.exe分离到 tm.sys 中。由于只包含 KTM 函数,因此首先关注tm.sys可能会吸引人。但是,由于KTM使用了ntoskrnl.exe中的许多函数,因此逆向分析实际上会更加繁琐,因此我们将在两个IDA数据库之间进行切换。

 

首先选择 Windows 7 的一个缺点是,我们首先构建了可在Vista和Windows 7上运行的写原语。但是,事实证明它由于Windows 8及更高版本上的 缓解措施而失败,从而迫使我们重新考虑我们的方法。这些决定总是需要权衡的。通常最好不要过度分析并继续下去。

 

鉴于我们的逆向工作主要是在Windows 7上完成的,本文中几乎所有代码段均来自经过反编译的Windows 7 ntoskrnl.exe 二进制文件。如果在其他Windows版本中存在一些值得注意的行为差异,我们会尝试提及,但由于该漏洞相当复杂,我们可能会忽略一些细节。因此,如果您选择复现,请注意当您从 Windows Vista 移植到 Win10 时,您会发现在代码中的结构布局,偏移量方面遇到细微差异。如果存在这些差异,则在移植漏洞利用程序时,有时会需要作特殊处理。

 

还需要注意的是,在Windows 8及更高版本上,通过补丁对比分析 tm.sys 不会导致其他 ntoskrnl.exe 更改或漏洞出现在您的结果中,因此,在Windows 8及更高版本上进行补丁对比分析 KTM 漏洞要更加容易一些。

 

我们专门逆向了 Windows 7 x64 版本的 ntoskrnl.exe(版本号为 6.1.7601.24291)。

了解Windows内核事务管理器(KTM)

文档

在查看了补丁(稍后我们将描述)之后,并没有真正理解我们所看到的内容,我们决定首先需要尽可能多地了解KTM 是什么。我们选择从逆向大多数主要内核API和系统调用实现开始,同时建立我们自己的一组用户层代码示例以探索 API。我们知道最终我们将能够重用许多小样例代码进行利用编写,这使我们能够缓慢地建立起坚实的理解基础。

 

与许多其他MSDN页面不同, MSDN KTM 门户网站上很少有公开的可用的KTM代码示例,因此我们没有很多可重用的代码段。

 

另一个资源是 MSDN 内核模式KTM门户 ,它从内核方面讨论KTM内部。在理解新概念时,它非常有用,但也很麻烦。刚开始不必理解所有内容,但确实值得一读。另外请注意,我们只对内核API感兴趣,以便更好地理解概念,但由于我们本地的特权提升漏洞利用只能调用用户层KTM API,因此我们将无法直接调用它们。

 

因此,我们编写的大部分内容都是通过反复试验或通过逆向KTM组件使用API的方式得出的。即使MSDN上的KTM文档非常详尽,但在没有工作代码段来演示概念之间的相关性的情况下,对所有术语进行整理还是有些令人困惑。

 

我们还找到了有关KTM总体工作原理的很好概述,而官方文档中没有,这是Microsoft在2005年至2007年之间发布的3个视频系列,作为“深入”系列中有关Vista新发行版Windows技术的一部分的视频:

最近发现一些名为 "Proton Bot"的恶意软件使用 KTM 函数试图绕过 API监控/钩子之类的东西。不过,它似乎并没有真正利用KTM的事务性来实现其他任何目的。

什么是内核事务管理器(KTM)?

KTM 是Windows Vista中添加的一种技术,用于引入“事务操作”概念。Windows本身至少在Windows注册表和NTFS文件系统中使用此组件。这个概念特别存在于数据库领域,例如SQL等。想法是,某些给定的操作(称为“事务”)可能需要跨多个资源完成大量相关工作。这样的事务在较高的层次上代表着单个工作,需要有效地实现原子化,如果任何一个部分失败,则整个事务都会失败。

 

这种类型的“事务”对于复杂的多进程操作尤其重要。自动取款机(ATM)试图协调自己的现金和请求者的账户信息,这是一个常见的例子,可能受益于原子交易的概念。安装软件是另一个例子,在中断时,它需要回滚所有更改,因为比如说用户取消安装。

 

这意味着,如果操作的任何部分最终失败,则可以回滚已完成的与该事务相关的所有其他工作,使其看起来好像从未发生过一样。只有当与事务相关的所有工作都成功时,该事务才实际完成。

 

KTM的概念是从某些故障中恢复并回滚某些事务。我们稍后将详细介绍它们,但现在只需注意,如果与事务相关的某个工作失败,系统的设计将通知参与该事务的所有其他工作人员,以确保他们知道某些事情已经失败,或者他们都需要重新同步到某个商定的状态。

 

MSDN KTM 门户 是微软如何提供api以允许用户层客户端软件处理事务的主要参考。

 

我们对KTM中涉及的四个主要组件感兴趣,我们将更详细地描述它们。在整个文档中,我们在下一节中交替使用它们的长格式和短格式名称:

  • 资源管理器 (RM)
  • 事务管理器 (TM)
  • 事务 (Tx)
  • 登记 (En)

事务是什么(Tx)?

上面已经暗示了这一点,但是事务是KTM中其他所有事情的基础。微软文档 提供 了相当全面的高层解释。它们还在 这里提供了较低层次的视图。

 

从我们的角度来看,事务是 _KTRANSACTION 内核结构,与事务管理器有关联,还有一个或多个登记。它有效地代表了一些期望原子化完成的多部分工作。事务用于跟踪即将启动、正在执行或已完成的工作。

 

事务主要可以执行三个操作:创建,提交和回滚。提交事务意味着将部分操作转换为永久更改。回滚事务只是意味着在事务实际完成之前还原到目前为止已发生的所有部分操作。已回滚的事务无法提交,反之亦然。

 

以下是 _KTRANSACTION 结构的代码段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//0x2d8 bytes (sizeof)
struct _KTRANSACTION
{
    struct _KEVENT OutcomeEvent;                                            //0x0
    ULONG cookie;                                                           //0x18
    struct _KMUTANT Mutex;                                                  //0x20
    [...]