什么是iOS的安全模式
作为iOS开发,作品App肯定需要提交到App Store审核。平心而论,App Store确实成功地将许多恶意软件拒之门外。但是,对开发者而言,应用程序的审核流程是令人沮丧的黑箱操作。
当然,什么是恶意程序是由Apple来定义。因为App Store的存在,所以,如果想要实现某些特定的功能,唯一的手段就是将设备越狱或者骗过App Store的审查。
官方的App审查永远无法抓到那些钻空子的恶意程序,所以需要另外一套高效的机制,来阻止恶意程序破坏整个操作系统的安全。
安全启动
当启动一台iOS设备时,系统首先会从只读的引导ROM中读取初始化指令,即系统引导程序。这个引导ROM包含Apple官方权威认证的公钥,它会验证底层启动加载器(LLB)的签名,一旦通过验证就启动它。
然后验证第二级引导程序iBoot,iBoot启动后设备就可以进入恢复模式或启动内核。在iBoot验证完成内核签名的合法性之后,整个启动程序开始步入正轨:加载驱动程序、检测设备、启动系统守护进程。
这个信任链确保所有的系统组件都由Apple写入、签名、分发,不能来自第三方机构,特别是那些恶意的攻击者以及企图越狱设备的黑客。App启动时也会用信任链去审查签名。所有的App都必须直接或间接由Apple签名。
越狱工作的原理正是攻击这一信任链。越狱工具的作者需要找到这一信任链条上的漏洞,从而禁掉链条中负责验证的组件。破解引导ROM通常是最可取的方法,因为该组件不会因Apple今后的软件更新而改变。
有关更多签名知识可以参看:
沙盒机制
App的沙盒机制是一种基于FreeBSD系统TrustedBSD框架的强制访问控制(MAC)机制,它采用一种类似于Lisp的配置语言来描述哪些资源系统可以访问,哪些禁止访问。这些资源主要包括文件、系统服务、网络连接、内存资源等。
MAC机制不同于传统的访问控制机制(比如自主访问控制(DAC)),它不允许主体(比如用户进程)操作对象(文件、套接字等)。DAC最常见的形式就是UNIX系统上的用户、组和其它权限,所有这些都可以被授予读、写或执行的权限。在DAC系统中,用户如果拥有一个对象的所有权,也就拥有该对象的修改权限。
MAC在沙盒中意味着App被关进了一个虚拟的容器。该容器遵循一系列的特定规则,即哪些系统资源可以访问。
在文件访问方面,一般只能访问App的包目录;App可以读写存储在该位置的文件。
Android的访问控制机制与MAC不同。Android实现了一个更加传统的DAC模型,App都有自己的用户ID和属于该ID的文件夹,其权限管理严格按照传统的UNIX文件权限管理运作。虽然这两项机制工作起来都没有问题,但MAC的扩展性总体来说还是更强一些。比如,除了App目录隔离,MAC机制还可以限制网络访问或系统守护进程的操作。
数据保护和全盘加密
数据保护和全盘加密两机制可以实现远程抹除设备数据,在设备丢失的情况下保护用户数据免于泄漏。
文件系统加密并不能防止从一个正在运行的设备上窃取数据的行为。如果一个App可以从磁盘中读取一个文件,那文件系统加密并没有任何用武之处,因为内核对于任何尝试读取这些文件的进程都是透明解密的。换句话说,相比那些读取文件的调用行为,文件系统加密工作都是更底层。一旦攻破者攻破了系统验证,那就能无障碍地读取任意文件。
全盘加密对于以下两个安全特性是必要的:安全删除文件、远程设备擦出。iOS中使用的加密密钥是分层级的,只需要简单丢弃一个加密密钥就能彻底销毁整层的数据,甚至是销毁整个文件系统。
加密密钥的层级
iOS文件系统中用于数据加密的密钥是分等级的,即用密钥来加密其它密钥,这样Apple就能更精确的控制数据什么时候可用。
文件密钥(File Key)针对每个文件独立生成,存储在文件的元数据中。
层级密钥(Class Key)为数据提供不同级别的保护。
文件系统密钥(Filesystem Key)是一种全局加密密钥,当元数据被层级密钥加密后,使用文件系统密钥来加密涉及文件安全的元数据。
设备密钥(Device Key)通常被称为UID密钥,每台设备唯一,只能通过硬件的AES引擎访问,操作系统无法直接获取。它是系统的主密钥,用来加密文件系统密钥和层级密钥。
用户密码(User Passcode),可与设备密钥结合起来加密层级密钥。
一旦设置密码,这个密钥等级也允许开发者自己决定本地存储的数据该如何保护,包括在设备锁定时是否能被访问、数据能否备份到其它设备等。
ASLR和XN及其它机制
iOS用两套标准机制来预防代码执行攻击:地址空间结构随机化(ASLR)和XN bit(eXecute Never,标记该段内存区域不包含可执行代码)。
每次执行程序时,ASLR都会随机分配程序、数据、堆和栈的内存位置。而共享库的内存地址只在每次系统重启时随机设置,因为共享库需要在多个进程中使用。ALSR机制可以预防缓存区移除攻击(return-to-libc),因为函数和库的内存地址随机,而这种攻击依赖于基本库和函数的已知地址。
XN bit,一般对应非ARM平台的NX(No-eXecute)bit,允许操作系统将某段内存标记为不可执行,这由CPU来控制。在iOS中,这个机制默认应用在程序的栈和堆上。
每个程序都有一段可写可执行的内存,但是它必须是经过Apple官方签名授权系统的签名。Safari浏览器中的JavaScript即时(JIT, Just-in-time)编译器会用到这段内存。而WebView并不具备JIT功能,这样虽然可以避免代码执行攻击,但是也使得iOS平台上的Chrome无法做到像Safari那样好用。
越狱检测
越狱的本质就是通过一系列步骤来禁掉签名机制,从而允许设备运行未经Apple官方审核的应用。黑箱测试应用程序是越狱的重要能力。
其实,越狱不一定要禁掉iOS的沙盒机制,它只是允许你在沙盒外安装App。安装在移动用户主目录下的App(即通过App Store安装)仍然受到沙盒限制。第三方的App需要安装在越狱设备中权限更高的/Applications
目录下,与Apple股票应用安装在一起。
动态修复
一般来说,如果一段原生代码没有经过Apple发布的密钥签名认证,App则无法运行它。如果Apple的签名验证逻辑中存在bug或漏洞,可能会允许下载和执行原生代码。
iOS有一个特性,可以让程序分配一段没有NX保护的内存区块(该内存区块可读、可写,甚至可执行),里面运行的代码也不需要经过签名认证。这个机制在Safari上的JIT编译器上使用。这个运用场景中,就可能会产生漏洞,业界著名的例子就是Charlie Miller。