细数iOS上的那些安全防御

0x00 序

随着苹果对iOS系统多年的研发,iOS上的安全防御机制也是愈来愈多,愈来愈复杂。这对于刚接触iOS安全的研究人员来讲很是不友好,每每不知从何入手。所以,为了让你们可以更加系统性的了解iOS上的安全机制,咱们从三个方面着眼:代码签名(CodeSign)、沙盒机制(SandBox) 和利用缓解(Exploit Mitigation),对iOS的系统安全机制作了一个总结。但愿可以给你们的学习以及研究带来必定的帮助。注意,如下内容是以最新版的iOS 9.3.4作为标准进行讲解。html

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校验其正确性。架构

(3). Team ID

Team ID 最先在iOS 8中被提出,在iOS 9中获得了进一步的增强。Team ID的出现主要是为了阻止攻击者将本身的动态库加载到不属于本身的executable中,常见例子:越狱过程当中将动态库加载到系统进程,得到沙箱外的任意代码执行能力;恶意应用经过沙箱逃逸将本身的动态库加载到别人的app运行环境,盗取帐号密码等有价值的信息。因此Team ID的具体的校验逻辑就是根据这个原则来设计。除了特殊状况,系统的进程只能加载系统的动态库。第三方app根据本身的Team ID来决定哪些具备相同Team ID的dylib能被加载。app

0x02 沙盒机制(SandBox)

不少系统都有沙盒机制,可是像iOS这么复杂的却不多。iOS从UID/GID permission,MAC和entitlement三个维度实现了整个系统的沙盒机制:框架

(1). UID/GID permission

通常状况下,iOS会将进程的权限分为root和mobile,一些特殊的模块(好比基带)会有本身的用户组。须要注意的是,全部第三方的app都是运行在mobile权限下的。dom

(2). iOS Mandatory Access Control

iOS的MAC在TrustedBSD Mac Framework基础上实现,在内核具体接口、具体位置插入权限hook check(mac_** call),在发生调用时检查当前进程是否知足调用的MAC police。
而进程的MAC police主要是经过sandbox profile。Sandbox profile是苹果为每一个系统进程或app预设的,例如:哪些文件可读可写,哪些不能;哪些system call能够调用,哪些不能等等。布局

对于系统进程,通常状况下苹果会为不一样的系统进程配备不一样的sandbox profile,既知足业务需求,又遵循权限最小化原则。学习

对于第三方app,则是统一配备名为 Container 的sandbox profile,这个profile里面的内容限制可达数千条。限制很是严格,以至于只有不多数的syscall能在第三方app内访问。一些安卓中很是普通的调用,例如fork,exec等建立子进程的系统调用,在第三方app内都是没法生效的。咱们常说的沙盒逃逸,其实目的就是跳出container的sandbox profile。加密

(3). Entitlement

Entitlement的出现主要是为了上面两个维度都没法解决的权限检查问题。

假设有这样的场景:
进程 A 是 service 、进程 B 是 client,二者经过IPC通信。
进程A提供的服务接口分别有:a1 , a2 ,其中只但愿接口a1能被B访问。

由于检查发生在用户态,不能直接使用TrustedBSD Mac Framework,同时须要有更简单的查询方式,这样就须要在a2接口的代码中加入权限校验。基于entitlement的校验框架就是在这个需求背景下被提出来的。业务进程只须要关注entitlement的内容,而entitlement的正确性由签名保证。好比想要访问提供了能删除app的接口的”com.apple.mobile.installd”服务就必须拥有对应的”com.apple.private.mobileinstall.allowedSPI” entitlement才行。而lockdownd这个service是用于和iTunes交互来进行安装、升级、删除应用的,因此这个服务为了能与installd服务通信,进行删除app操做,就须要拥有”com.apple.private.mobileinstall.allowedSPI” 这个entitlement:

0x03利用缓解(Exploit Mitigation)

除了常见的Stack Canaries、 ASLR和DEP等利用缓解技术以外,iOS还有不少高级的或者独有的利用缓解技术:

(1).栈金丝雀保护 (Stack Canaries)

栈金丝雀保护是已知的放置在缓冲器和控制数据之间的一个随机值。当缓冲器溢出时,最早被破坏一般是金丝雀值。所以当金丝雀的数据的验证失败的时候,就表示出现了缓冲区溢出,从而触发保护机制,并使程序中止运行。

(2).地址随机化 (ASLR/KASLR)

为了增长攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,用户态进程在每次启动时的执行文件基址都是随机生成的。而且,在每次手机重启后,内核kernel mach-o的基址也是随机的。

(3).数据执行保护 (DEP)

DEP是为了防止数据页执行代码。一般状况下,默认不从堆和栈执行代码。DEP会检测从这些位置运行的代码,并在发现执行状况时引起异常。在mprotect对应的内核实现中,不容许page被同时赋予执行和写这两种权限。当page的权限发生变化或一个新的page mmap到内存中的时候,vm_fault_enter会检查这个页是否有执行位,若是有执行位,会对这个页作签名检查。

(4). 堆释放元素保护 (Heap Free Element Protection)

在iOS中,若是修改一个zone中已释放的free element,当内存管理器再次分配内存到这个free element的时候会发生随机panic。具体的逻辑是,当element被释放后,内核会根据重启时建立的token生成一些内容填充在element中。这样一方面用户态没法得知填充的内容是什么,另外一方面内核在分配内存的时候能够根据token知道这个element有没有被修改,若是被修改就产生panic。

(5).堆元素地址随机化 (Random Heap Element Address)

iOS系统在释放内存块的过程当中,会对内存释放后在free队列中的顺序进行随机化处理,这个安全措施主要是使用攻击者没法根据堆喷接口调用的时序来预测对应元素在内核的布局。

(6).内核补丁保护 (Kernel Patch Protection)

ARMv8-A架构定义了四个例外层级,分别为EL0到EL3,其中数字越大表明特权(privilege)越大:

EL0: 无特权模式(unprivileged)

EL1: 操做系统内核模式(OS kernel mode)

EL2: 虚拟机监视器模式(Hypervisor mode)

EL3: TrustZone monitor mode

KPP就是运行在Application Process 的 EL3中,目的是用来保证:只读的页不可修改、page table 不可修改、执行页不可修改。

0x04 总结

虽然iOS有众多的安全机制和缓解措施,但这并不表明iOS系统牢不可破。有时候一些不起眼的小错误就可能致使蝴蝶效应,最终形成整个安全系统的崩盘。经过对最新的iOS 9.3.4研究,咱们团队依然找到了iOS系统上的一些安全问题,甚至能够致使整个系统被控制。以下视频就演示了在最新的iOS 9.3.4上获取系统最高权限并安装cydia的过程:

视频:http://v.youku.com/v_show/id_...

更多技术交流和进展,欢迎你们继续关注阿里移动安全。

0x05 参考资料

  1. Hacking from iOS 8 to iOS 9, POC 2015.

  2. ARMv8 wiki

  3. To Sign and Protect – COPS in OS X and iOS, RSA 2015

  4. 漫谈iOS程序的证书和签名机制


做者:龙磊、黑雪、蒸米@阿里巴巴移动安全,更多安全类技术文章,请访问阿里聚安全博客

相关文章
相关标签/搜索