0x00 序
随着苹果对iOS系统多年的研发,iOS上的安全防护机制也是越来越多,越来越复杂。这对于刚接触iOS安全的研究人员来说非常不友好,往往不知从何入手。因此,为了让大家能够更加系统性的了解iOS上的安全机制,我们从三个方面着眼:代码签名(CodeSign)、沙盒机制(SandBox) 和利用缓解(Exploit Mitigation),对iOS的系统安全机制做了一个总结。希望能够给大家的学习以及研究带来一定的帮助。注意,以下内容是以最新版的iOS 9.3.4做为标准进行讲解。
0x01 代码签名(CodeSign)
为了保护开发者的版权以及防止盗版应用,苹果系统拥有非常严格的签名保护机制。想要开发iOS程序,必须先注册开发者账号,并向苹果申请相关的证书,否则程序只能在模拟器上运行,无法在真机上调试,也无法上架App Store。除了传统的签名机制以外,苹果还额外增加了Team ID的安全防护措施,用来增强iOS系统的安全性。
(1). 传统签名机制 - 数字证书
传统的签名机制即iOS系统中使用的数字证书机制。数字证书是一种对数字内容进行校验的方法,它首先对内容使用摘要算法(例如MD5,SHA1)生成一段固定长度的hash值(可以理解为原内容的摘要),然后利用私钥对这个摘要进行加密,得到原内容的数字签名。接受方一并接收到原内容和数字签名,首先用相同的摘要算法生成原内容的摘要,同时用公钥解密数字签名,得到摘要2,然后比较摘要1和摘要2,若相同,则验证原内容有效。我们从苹果MC(Member Center)中获得的数字证书就是被苹果CA签过名的合法的证书。而iOS设备在执行app前,首先要先验证CA的签名是否合法,然后再通过证书中我们的公钥来验证app是否的确是开发者发布的,且中途没有对程序进行过篡改。理论上想要破解或者绕过这个签名机制,需要能够获取到苹果的私钥,或者能够找到签名校验过程中的漏洞。
(2). 签名校验的实现
iOS在运行代码前,都会对即将运行的代码进行签名校验。签名的校验机制是运行在内核里的。因此想要关闭这个校验的话,需要对系统进行越狱才行。内核在vm_fault_enter中规定了绝大部分情况下,具有执行位的页需要进行签名有效性检查,如果检查到该页签名无效会为进程设置kill flag。签名校验分两种情况;如果binary是platform binary,系统会直接校验binary的哈希值是否存在于trustcache中。如果binary是第三方应用程序,会先在内核在检查执行页对应hash值,而页hash对应的签名由用户态进程amfid校验其正确性。

