导语:本演讲将围绕如何对苹果内核设备驱动进行安全分析和漏洞挖掘而展开。
本演讲将围绕如何对苹果内核设备驱动进行安全分析和漏洞挖掘而展开。
0x01 新的漏洞
首先,解释几项我们最新发现的苹果内核设备驱动中的安全漏洞。这几个安全漏洞概述如下,
1)发生在IOAcceleratorFamily2驱动中的“释放后使用”(UAF)漏洞。该漏洞发生在IOAccelDisplayPipeUserClient2::s_transaction_end函数中。其主要产生原因在于驱动在释放某一对象时没有将其他对象对该对象的引用清空。
2)发生在IOFirewireFamily中的内核信息泄露漏洞。该漏洞发生在IOFireWireUserClient::isochChannel_Create函数中,其主要产生原因是使用了未初始化的栈上变量。
3)发生在IOFirewireFamily中的“释放后使用”(UAF)漏洞。该漏洞发生在IOFireWireUserClient::userAsyncCommand_Submit函数中,其主要产生原因是在驱动使用成员变量时没有进行加锁或串行化操作。
除了阐述这几项漏洞的产生原因,本演讲还将介绍如何利用这些漏洞实现提权攻击,攻击主要依赖于“内核堆喷”(Heap Spray)和“面向返回编程”(ROP)的攻击技术,其基本流程如下图所示。
在ROP过程当中,我们使用到的ROP chain如下,
利用这些攻击手段,我们可以在macOS 10.13,10.13.2,10.13.3上实现了从用户态应用程序进行提权操作的攻击(如下图所示)
0x02 苹果内核设备驱动安全分析静态工具——Ryuk
除了解释几项新发现的漏洞,更重要的是,本演讲将阐述我们使用什么样的方法发现这些漏洞。由于苹果内核设备驱动的闭源本质和基于C++所产生的面向对象的不确定性,以及符号信息的缺失,都给设备驱动分析带来了很多困难。包括IDA pro在内的逆向工具都难以对驱动中的函数进行正确的反编译和解析,例如下图所示为IDA pro所产生的驱动函数反编译代码。
这样的代码使得对驱动进行安全性分析具有很大的难度。本演讲将提出一种新的苹果内核设备驱动安全分析静态工具,称之为Ryuk。经过Ryuk的处理,驱动函数的反编译代码将如下图所示,像源代码一样容易分析,
为了达到这样的分析效果,Ryuk针对苹果内核设备驱动,实现了以下几项功能:
1. 类及虚表结构识别:识别驱动中所定义的C++类的结构及其虚表结构。其主要实现方式是分析如下的初始化函数,获取类的名称、大小和虚表地址等重要的结构信息。
2. 函数名称恢复:针对iOS设备驱动,利用类的继承关系恢复出函数的名称。如下图所示,其主要实现方式是通过比对子类与父类的虚表来恢复出子类虚表中无名称函数的名称。
3. 变量类型解析:在反编译代码中,使用数据流分析技术分析每个对象的具体类型。
4. 构造函数调用关系图:梳理函数之间的调用关系,构造如下图所示的函数调用关系图
5. 在反编译工具中增加交互操作支持:为了方便研究人员更好的逆向分析驱动代码,在反编译代码中增加了更多交互操作的支持
借助于这些功能,Ryuk可以恢复出如下图所示的类似源代码的反编译代码
0x03 静态分析与动态分析的结合——Ryuk–Fuzz
除了辅助逆行和静态分析,Ryuk还可用于辅助动态分析技术,例如Fuzz技术。我们在现有的macOS设备驱动Fuzz框架PassiveFuzzFrameworkOSX的基础上,结合Ryuk的静态分析功能,实现了Ryuk-Fuzz。
Ryuk-Fuzz首先使用静态分析技术解析驱动中的函数对用户态输入数据的限制和要求,进而利用解析出的用户输入规范(如下图所示)来指导对驱动的Fuzz过程,从而提高代码覆盖率和Fuzz效率。
0x04 总结
本演讲围绕苹果内核设备驱动安全分析和漏洞挖掘,首先展现了我们最新发现的几项苹果内核设备驱动中的安全漏洞以及通过这些漏洞所进行的提权攻击的基本原理。其次详述了我们如何发现这些漏洞,包括提出了一款新的设备驱动静态分析工具Ryuk,以及基于Ryuk所实现的Ryuk-Fuzz。