微信号:frontshow

介绍:InfoQ大前端技术社群:囊括前端、移动、Node全栈一线技术,紧跟业界发展步伐。

阿里是如何让iOS 12越狱成功的?

2018-09-19 17:27 耀刺 & 黑雪
作者|耀刺 & 黑雪
编辑|覃云

本文由阿里安全潘多拉实验室授权首发。

每年 iOS 系统大版本升级,对于安全研究人员都是一次新的挑战。在大版本中,除了修补一些未经公开的漏洞外,苹果还会增加新的缓解机制,大大提高了整个越狱的难度。这不仅要求安全研究人员能够挖掘出可以独立提权的漏洞,还要能够攻破签名绕过和根目录读写这两道关卡。在 iOS 12 中,业界公开的解决方案都已经被苹果封堵。
签名绕过(CodeSign Bypass)

在 iOS 中有非常严格的签名校验机制,所有发布的 App 均需要通过苹果颁发的证书进行签名之后才能上架。由于存在 TeamID 机制,即第三方动态库与宿主进程使用同一个证书签名,纵使通过漏洞利用完成提权后,依然无法运行未签名的 binary,也无法注入代码到其他进程,因此需要绕过苹果的签名校验。在 iOS11 中,业界有两种公开的解决方案:

  劫持签名校验进程 amfid(hijack amfid @i41nbeer)

iOS 系统中通过 AMFI 的 Mach Message 调用用户态进程 amfid 进行签名校验,其中 MISValidateSignatureAndCopyInfo 函数返回签名校验结果和 CDHash(Code Dictionary Hash)到内核。

在 iOS 10 以前,MISValidateSignature 可以通过简单地返回一个布尔值完成绕过。iOS 10 以后,MISValidateSignature* 函数的返回值为字典。Google Project Zero 的安全研究人员 Ian Beer 提出的解决方案是通过劫持 amfid 的 exception handler,并把 MISValidateSignatureAndCopyInfo 函数指向一个无效地址,从而使得每次进行签名校验时 amfid 都会发生 exception,最终回调到劫持的 exception handler。从回调函数中获取到 binary 信息并正确返回 CDHash,通过整个校验逻辑。如图 1 所示:

图 1 劫持 amfid 绕过签名简易流程图

在 iOS12 中,内核增加了 CMS(Cryptographic Message Syntax)校验,而业界常用的自签名工具 ldid 以及 jtool 中 CMS 都是为空的,导致上述解决方案失效。同时内核增加了 CoreTrust 模块用于对抗 hardcoded 证书,因此要伪造签名并通过苹果校验的难度大大提高。

  伪造签名授信缓存(fake trust cache @Xerub)

内核中 AMFI 使用 trust cache 快速校验 ad-hoc 的 binary,它是一个链表式的数据结构,并且存放的位置不受限于 KPP/AMCC 的保护,提权完成之后可以在内核中找到这个结构体,插入自签名 binary 的 CDHash 绕过签名校验。

在 iOS12 中,已经无法从 AMFI 中找到 trust cache chain 了,他被存放在内核的 const data 段中,这意味着无法对他进行修改。系统通过调用 pmap_lookup_in_static_trust_cache 进行校验。

然而当我们仔细研究 AMFI 中的签名校验逻辑时发现,内核中有 2 个 trust cache chain,校验时分别对这两个 trust cache 进行检索匹配,只要通过其中一个校验即可,虽然上述 static trust cache chain 无法修改,但是另外一个依然可以修改!并且 binary 通过 trust cache 的校验后,无需再进行 CMS 校验!苹果虽然尝试封堵这种绕过方式,但依然存在漏洞,导致新增加的缓解机制被轻松绕过。

根目录读写(Root Filesystem Read / Write)
在 iOS 中为了保障手机文件安全,即使进程拥有 Root 权限,依然无法修改 Root Filesystem 的内容。iOS 11.3 对 Root Filesystem 有过加强,从而令重新挂载 Root Filesystem 后,修改 Root Filesystem 会触发内核 panic。在 iOS 11.3 后根目录读写的解决方案有两种:
  伪造有效的 mnt_data(Xiaolong Bai and Min (Spark) Zheng @ Alibaba Security Lab)

在 iOS 11.3 中,即使把 RDONLY 的标志去掉使 Root Filesystem 能被挂载为可读写,但由于挂载的是一个只读的 snapshot,并且 snapshot 中的 mnt_data 不包含有效的 extent 结构,因此修改 Root Filesystem 会触发内核 panic。那解决的方案自然是将 snapshot remount 的 mnt_data 替换为一个有效的 mnt_data。苹果在 iOS 12 的 APFS 中进一步加强了对 mnt_data 合法性的校验,用上述方法直接替换会触发内核 OOM Panic。

  删除 /dev/disk0s1s1 snapshot (cererdlong and eakerqiu @ Alibaba Pandora Lab)

对于 snapshot 的另一种解决方案是直接删除。通过删除 /dev/disk0s1s1 的 snapshot,使得 reboot 时系统无法加载对应的 snapshot,最终被迫系统使用真实的 /dev/disk0s1s1 进行 mount。

虽然苹果在内核有对 fs_snapshot_delete 进行校验,无法将正在使用的 snapshot 直接删除,但却没有对 fs_snapshot_rename 进行校验。因此可以对正在使用的 snapshot 改名!通过这个漏洞将 snapshot 改名后,reboot 时系统找不到原本注册的 snapshot,被迫使用真实的 /dev/disk0s1s1 进行 mount。重启完成后,不仅可以直接将改名的 snapshot 删除,而且可以通过简单修改 mount 的 mnt_flag 直接 mount update 根目录为可读写。

苹果在 iOS 12 的 APFS 对这个漏洞也进行修补,使得正在使用的 snapshot 无法被 rename。尽管如此,依然有新的思路和方法可以挂载根目录为可读写。

 结 论 

苹果在 iOS 12 中修复了很多未公开的漏洞,增加了新的缓解机制,但在 iOS 12 正式版发布的数小时内,潘多拉实验室完成了 iOS 12 的完美越狱,如图 2 所示。从技术的角度来看,完美越狱和非完美越狱的主要区别在于重启过程中是否能自动执行越狱代码,在手机重启完成前完成越狱。

图 2 iOS 12 控制内核 PC 完成越狱并安装 Cydia
iOS 12 完美越狱视频演示

  参考文献
  1. MacOS and *OS Internals http://newosxbook.com/

  2. Mach portal https://bugs.chromium.org/p/project-zero/issues/detail?id=965

  3. extra_recipe https://github.com/xerub/extra_recipe

  4. iOS jailbreak internals (1): Remount rootfs after iOS 11.3 https://media.w

  活动推荐

前端新趋势,可以关注 QCon 全球软件开发大会,从实践中积累的前端架构经验,典型的前端框架应用经验,新型框架与设计思路三个方面探索前端研发之路。大会9 折报名中,立减 680 元。有任何问题欢迎咨询票务经理 Ring,电话:010-84782011,微信:qcon-0410

 
前端之巅 更多文章 多端统一开发框架 Taro 1.0 正式发布,全面支持小程序 15行代码让苹果设备崩溃,最新的iOS 12也无法幸免 选择JavaScript开源库时,你需要考虑这些问题 styled-components v4测试版发布:原生支持 ref,性能提升25% 最好的JavaScript数据可视化库都在这里了
猜您喜欢 解密未来数据库设计:MongoDB新存储引擎WiredTiger实现(事务篇) 【专家专栏】系统测试环境“多路复用”解决方案 Ruby 2.4 的一些新特性 开奖 | 现在是见证奇迹的时刻 骇客交锋