iOS内核研究:定位内核gadget符号地址

2019-08-01 约 126 字 预计阅读 1 分钟

声明:本文 【iOS内核研究:定位内核gadget符号地址】 由作者 wooy0ung 于 2019-08-01 09:30:00 首发 先知社区 曾经 浏览数 46 次

感谢 wooy0ung 的辛苦付出!

原文地址:https://medium.com/@cji_/hunting-for-ios-kernel-symbols-e48a446bb00

0x001 前言

上周,Google Project Zero的Ian Beer在Twitter上发文,他将通过task_for_pid_0或tfp0提供对内核内存的读、写访问,以帮助研究人员更深入研究iOS 11内核安全性。

这消息一出,可能人们更多的关注会放在新系统的越狱上面,但我想借此机会再研究一下移动安全。

Ian Beer昨日已将poc代码放在Project Zero的主页上Issue 1417: iOS/MacOS kernel double free due to IOSurfaceRootUserClient not respecting MIG ownership rules,包含有CVE-2016-7612CVE-2016-7633两个漏洞。正当我准备好开始我的工作时,便遇到一个问题。Ian Beer放出来的poc代码中为几个设备添加了内核符号,但这几个设备我手头上并没有。运气比较好,他提供了有关如何找到符号的详细说明。

本文旨在介绍查找iOS符号的过程,因为我没有找到关于如何执行此操作的任何其他文档,因此我想为其他人(以及将来的我自己)记录此过程,希望对你添加对设备的支持也能有所帮助。

0x002 查找内核符号地址

查找符号的第一步是获取目标iOS版本的kernelcache。我是通过访问ipsw.me并下载了我的iPad Mini 2的11.1.2固件,同样也可以下载任何已经在symbols.c中定义了符号的设备。

在解压缩.ipsw文件之后,我下载一份joker工具。这是一个命令行工具,在阅读该工具的帮助页以后,设定好-j和-m选项并处理kernelcache文件,转储所有可用的符号。输出包含我需要的这些符号的地址:

KSYMBOL_OSARRAY_GET_META_CLASS
    KSYMBOL_IOUSERCLIENT_GET_META_CLASS
    KSYMBOL_IOUSERCLIENT_GET_TARGET_AND_TRAP_FOR_INDEX
    KSYMBOL_CSBLOB_GET_CD_HASH
    KSYMBOL_KALLOC_EXTERNAL
    KSYMBOL_KFREE
    KSYMBOL_OSSERIALIZER_SERIALIZE
    KSYMBOL_KPRINTF
    KSYMBOL_UUID_COPY

在用IDA Pro加载kernelcache文件之前,我们还需要解密kernelcache文件。详细的方法可以参考这里:getios10beta1kernelcache.sh

* open kernelcache in a hex editor and look for 0xFFCFFAEDFE, note the offset (435)
* wget -q http://nah6.com/%7Eitsme/cvs-xdadevtools/iphone/tools/lzssdec.cpp
* g++ -o lzssdec lzssdec.cpp
* ./lzssdec -o 435 < kernelcache >kernelcache.dec # 435 is offset byte count to 0xFFCFFAEDFE header

首先,IDA加载解密好的kernelcache文件,kernelcache带有一些已知内核符号,我们可以通过反汇编的结果来大致了解一下iOS内核。

最先找到的是KSYMBOL_RET,跳转到已知符号的地址,这是从_kalloc_external函数返回的RET指令。利用joker转储的符号地址信息很容易在IDA中跳转到对应的地址并且在同一个函数中找到这个RET指令。

接下来是KSYMBOL_CPU_DATA_ENTRIES,其中提示称数据段为0x6000。在IDA中,选择Jump to Segment并转到_data段的开头,将该地址加上0x6000最终得到了我们所需的地址。

接下来的两个地址是KSYMBOL_EL1_HW_BP_INFINITE_LOOPKSYMBOL_SLEH_SYNC_EPILOG,这是ksymbol列表最后两个地址,具体可以看到Ian Beer利用代码里的symbols.h。在IDA中打开了String窗口(Shift + F12)并搜索字符串,双击查看引用。

对于前者,向下阅读代码找到了这段switch case 49语句,并且得到该地址。

对于后者,是字符串引用地址下面几个LDP指令中的第一个。

最后一个就是KSYMBOL_X21_JOP_GADGET,在看到所需的指令是MOV X21,X0后,我在IDA中进行了搜索,以找到我的iPad设备的Gadget。

还剩下的5条内核符号地址是最棘手的,在IDA中搜索并没有找到什么有用的信息,所以我开始查看我找到的地址以及它们与已知地址的比较。再然后,通过对比symbols.h里的符号地址之间的偏移差,我发现几个已经找到的地址之间偏移差基本上都能对应得上。最后,我比较了已知地址与未知地址之间的偏移差,例如,VALID_LINK_REGISTER和X21_JOP_GADGET仅相隔0x28个字节。

接下来,用IDA加载我设备的kernelcache并跳转到KNOWN_ADDRESS + my offset guess,并开始在附近寻找相同的指令。

当找到所有所需内核符号地址,需在poc代码中再添加一个if路径来支持我的设备的。

添加一个prinf()打印出信息,编译运行poc

最后漏洞在我的设备上成功触发。这是复现iOS设备内核漏洞的一般步骤,因为网上贴出来的poc、exp用到的内核符号地址一般与我们手头上的设备不一致,这样往往造成我们无法在本机上触发漏洞。

关键词:[‘安全技术’, ‘二进制安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now