许广林 漆仁 魏玉蕊
摘要:苹果iOS设备素以卓越的用户友好度著称,它的安全问题不是公众关注的焦点。然而iOS繁荣的生态系统背后,离不开一个设计良好的整体安全体系的支撑。这个整体安全体系是iOS生态系统核心竞争力的有机组成部分,它的成功之处值得其它生态系统借鉴,它的不足不处也蕴含了竞争对手借以超越的机会。
本文分两大部分:第一部分,介绍OS平台的整体安全体系,揭示了安全引导和访问控制两大核心技术的支撑作用;第二部分,从iOS应用开发者的角度出发,详细展现了iOS应用的安全运行环境和安全接口。在每一部分,我们也对现行安全机制的不足提出了改善建议。
苹果是一家重视安全的公司,信息安全方面的考虑一直贯穿于iOS平台的设计过程中。
iOS架构透露出一种整体安全的设计思路,它使用一些现有的安全标准和设计原则,比如安全引导、访问控制,它也进行了一些创新,最终构建了一个用户友好的安全体系,可称之为安全系统设计的典范。
iOS安全设计的成功经验主要有:1、强制的安全机制:当安全成为一个必选项时,安全需求不用再屈从于性能需求;2、软硬件协同的安全机制:既保证关键模块可信,又减少安全机制对性能的影响;3、用户友好的安全机制:强制安全和自主安全相混合,安全又可控,一个口令,使用方便。
iOS的整体安全主要由安全引导、访问控制两大技术来保证。在设备引导启动过程中,以只读ROM的代码为信任根,对引导模块进行逐级验证;iOS内核开始运行后,便通过复杂的访问控制策略,强制执行运行时的安全机制,确保更上层的功能和应用是可信的。
然而,iOS平台仍然存在不少安全缺陷。其中,越狱成功意味着iOS安全体系仍存在薄弱点,但这不意味着iOS安全体系的彻底失败。因为1、越狱需要设备所有者的主动操作;2、越狱只是要绕过应用代码签名机制而已,不对底层安全造成影响。在其他方面,比如强行重设Passcode,固件降级,都意味着iOS的安全机制仍待完善。
说明:本节内容主要来源于苹果公司于2012年10月发布的iOS Security白皮书,如果您担心我们对该白皮书的解读存在误解,建议您详细阅读原文。
安全引导链包含一级验证一级的思想。引导过程的每个步骤都包含经苹果公司数字签名(以保证引导组件的完整性)的组件。每一步都要对信任链进行验证,只有通过验证才能继续下一步。这些组件包括bootloader,内核,内核扩展和基带固件。
当iOS设备启动时,首先执行只读Boot ROM芯片上的代码。这些代码是在芯片制造时烧录进去的,不可更改,因此是可信的(苹果没有公开技术细节,不知道是否采用了和TPM可计平台模块一样的硬件保护技术)。Boot ROM的代码里包含了苹果的Root CA公钥,以便在加载Low-level Bootloader(LLB)之前验证它确实是苹果签名的。这是信任链的第一步,每一步都会保证下一步加载的代码是经苹果签名的。当LLB的任务完成时,它会验证并运行iBoot,iBoot接着又会验证和运行iOS内核。
安全引导链确保最底层软件不会被篡改,这个安全性是由Boot ROM芯片的只读性来保证的。此外,它还保证iOS仅能在通过验证的苹果设备上运行。
如果引导过程有一个步骤不能成功验证和运行下一个组件,则iOS会引导用户连接iTunes进行系统恢复。
和其他软件一样,iOS本身也在不断地升级完善。iOS包含一个安全的升级组件分发机制,确保iOS设备得到安全更新,而且不会向下降级。
在升级的过程中,iTunes或iOS设备本身连接苹果的安装授权服务器(gs.apple.com),向它发送一个密码学度量值列表(基中包含每个升级组件如LLB、iBoot、内核和OS映像的度量值),一个随机抗重放攻击的值(nounce)和一个设备的唯一ID(ECID)。
服务器检查这个度量值列表是否和最新升级版本相匹配。如果匹配,把ECID加入度量,然后对结果进行签名,最后把签名过的数据发送回请求升级的设备。通过加入ECID,使得这个升级数据包仅适用于该设备。由于苹果服务器只对最新版本的度量值进行签名,所以能确保升级包是由苹果提供的。
安全引导过程验证升级包具有苹果的签名,并且ECID和本设备相匹配,然后执行升级过程。
一旦iOS内核引导起来,它就可以控制哪个用户进程和应用可以运行。为了确保所有应用都来自已经和授权的软件源,并且没有被篡改,iOS要求所有可执行代码都使用苹果发行的证书进行签名。设备自带的应用如Mail, Safari具有苹果公司的签名。第三方应用也用苹果发行的开发者证书进行签名。强制的代码签名把信任链从OS扩展到应用程序,防止第三方应用加载未经签名的代码或使用自我修改的代码。
跟其他移动平台不同,iOS不允许用户从其他地方下载应用程序,或者执行不可信的代码。在运行时,代码签名会检查所有可执行内存页和安装时的代码一致,而没有被篡改。
所有第三方应用都局限在沙箱中,所以它们不能访问其他应用创建的文件,也不能对设备做出修改。如果应用有必要访问沙箱外的资源,它只能通过API接口或iOS服务来进行。
系统文件和资源也被保护起来,不让用户应用访问。iOS的大部分以及所有应用,都在非特权的用户模式下运行。OS文件系统是用只读模式挂载的。不必要的工具,如远程登录服务,不被iOS支持。应用程序也不能使用API函数来提升权限以修改别的应用或iOS。
如果应用要进行一些特别的操作,比如发起一个向外的socket,就要在程序设计时进行entitlement的登记,这样可以对应用的行为进行很严格的限制。
在移动设备上,速度和电能效率非常关键。密码学操作非常复杂,如果不经正确地设计,会带来严重的性能和电能问题。
每个iOS设备都有一个专用的AES 256加密引擎,挂接在介于闪存和主存之间的DMA总线上,使文件加密非常地高效。除了AES引擎,SHA-1也在硬件上实现,进一步降低了密码学操作的开销。
设备的UID和设备组ID(GID)都是AES256位密钥,在应用处理器生产过程中置入芯片中。除了硬件AES引擎,没有任何软件和固件能够直接读取这两个密钥,只能看到通过它们进行加密和解密的结果。
擦除密钥和生成密钥一样重要。由于闪存的磨损均衡机制,要安全地擦除密钥并不简单。iOS设计了一个安全的数据擦除机制,称为可擦除存储(Effaceable Storage)。该技术直接和存储底层控制芯片打交道,可以直接寻址并擦除指定的闪存块。
由于AES加密引擎已经安排在闪存和主存之间,所以iOS对一切文件都进行加密。每当创建一个文件时,iOS为新文件分配一个256位的文件密钥(per-file key),并交给硬件AES引擎,让它用这个密钥来加密文件,再写入闪存。
iOS最低加密级别是设备UID作密钥加密,保证数据不被非法迁移到其他设备上;如果用户设置Passcode,则与设备UID密钥相结合,对数据进行所有者身份绑定;同时,考虑到移动设备随时收到电话、短信或电子邮箱,iOS又对文件的加密需求进行了分类。
iOS通过采用密钥生成和密钥包装(wrap)技术,建立了一套密钥层次体系,如下图所示。
[1]
文件密钥和文件系统密钥都是随机密钥,文件密钥在文件创建时产生,文件系统密钥在iOS第一次安装或者设备被用户擦除时产生。
密钥包装是指用一个密钥对另外一个密钥进行加密,层层包装形成一个包装链条。文件密钥通过某一种加密类密钥进行包装,类密钥又通过UID和Passcode密钥来包装。
许多应用需要存储密码以及其他简短但敏感的数据,比如密钥和登录口令。iOS密钥链提供安全的方法来存储这些数据。
密钥链是用SQLite数据库来实现的,以无保护加密类别存储于文件系统中,不过它使用了跟文件系统类似但另一套的密钥层次体系。密钥链只有一个SQLite数据库,securityd守护进程决定哪个密钥能被哪个进程或应用访问。对密钥链访问API的调用需要提供"keychain-access-group"和"application-identifier"授权(entitlement)。通过访问组机制,应用之间可以共享同一个密钥。
所有类密钥(包括用于文件保护和密钥链保护的两套类密钥),都通过密钥包来集中管理。这些类密钥在放入密钥包之前,都用UID进行了包装,保证密钥包不会在别的设备上恢复出来。iOS使用4个密钥包。
系统密钥包
是唯一的存放在设备上的密钥包,包含了包装过(wrapped)的类密钥。比如,当用户输入Passcode时,从密钥包里出NSFileProtectionComplete类的密钥,并进行解包装。
备份密钥包
当通过iTunes创建一个加密备份时,也就建立一个备份密钥包。这个密钥包通过iTunes密码进行保护。即使用户不设置iTunes密码,也将获得UID密钥的保护,防止别的设备进行读取。
契约密钥包(Escrow keybag)
用于iTunes同步或移动设备管理(MDM),存放在相应的管理设备上。这个密钥包允许iTunes在不经用户输入Passcode的条件下进行备份和同步,也允许MDM服务器远程清除用户的Passcode。
契约密钥包能减少用户输入Passcode的麻烦。当设置了Passcode的设备首次连接到iTunes时,用户被要求输入Passcode。然后,设备会建立一个契约密钥包,其中的类密钥使用一个新生成的密钥进行包装,然后把包传递给iTunes主机。这个新生成的密钥就用来解锁协议密钥包,它存放在设备上用首次认证类进行保护。
iCloud备份密钥包(iCloud Backup keybag)
类似于备份密钥包。里面的所有类密钥都是非对称密钥,所以iCloud备份可以在后台自动完成,不需要Passcode。这些类密钥都使用iCloud密钥进行保护。
2013年2月初,Evasi0n越狱团队授受福布斯杂志的专访,并透露了刚刚发布的iOS6.1完美越狱的技术细节[Jailbreak]。
1、利用iTunes漏洞(可以访问设备内的一个文件,里面记录设备的时区信息),把一个可读写的文件改写成软连接,指向launchd,即iOS引导完成后运行的首个进程,具有root权限。
2、使用shebang脚本绕过代码签名,运行launchd(需要用户在屏幕上点击),把只读根文件系统重新加载为可写。
3、改写launchd.conf文件,使前面的修改永久生效;
4、替换代码签名关键函数,永远返回真;
*技术细节1:使用ARM异常向量定位ASLR分配的代码页。
*技术细节2:利用iOS的USB接口漏洞(设备把一个内核地址传递出去,并接受传回的地址),任意修改内核代码。
1、【技术】仅通过软件访问控制策略保证的安全机制不可靠,可以考虑运行时信任试度量技术,保证关键代码(如代码签名)的运行时可信,或者在安全引导过程中对只读根文件系统进行验证;
2、【技术】警惕设备和外部连接过程中的安全设计,比如iTunes和iCloud;
3、【动机】安全体系应该保障用户的自由,而不能用于建立封闭的生态系统。
为了开发安全的iOS应用程序,开发者应该详细了解应用程序的安全环境和安全接口。需要注意的是,应用编码过程中的安全问题(如缓冲区溢出)不在我们的讨论范围内。
应用沙箱(App Sandbox)是iOS强制实施的一种访问控制技术,它是在操作系统内核层面进行实现的。它有2种策略:
1.应用沙箱让你可以描述你的应用将如何跟系统交互。然后,系统向你的应用进行必需(没有任何额外)的操作授权。
2.应用沙箱允许用户透明地对你的应用进行额外操作授权,比如通过对话框。
[4]
作为一种应用隔离技术,沙箱的设计目标,是建立应用程序的边界线,把应用的行为限制在一个必需的最小范围内,以尽可能地减小恶意代码的危害。
比如,对于非沙箱内的应用程序来说,由于它是用户的操作代理,所以它自动取得用户具有的一切权限,如访问文件系统,监听网络端口等高级操作。一个友善的应用程序(奇虎360系列软件除外)不会偷偷做这些事情,但当黑客利用应用程序内的致命漏洞(如缓冲区溢出)获取了应用的控制权时,他就能做一切事情!为了避免这种情况,我们开发者可以把自己的应用程序放在一个严格规范的沙箱中,通过强制的访问控制策略来限定代码的作用范围,从而大大减轻恶意代码的危害。
[5]
每个iOS应用都有一个主目录,应用程序、配置数据、用户数据都存放在该主目录中。
MyApp.app是应用程序可执行文件
Documents/目录存储不可再生的用户数据
Documents/inbox目录存储外部应用传入的数据,如mail程序调用本应用来显示一个附件。
Library/目录存储是用户数据以外的数据
tmp/是临时文件存放目录
一般情况下,应用只能访问主目录内的文件,但有2个例外:1、如果外部应用调用本应用打开一个文件(如邮件附件),通过系统的接口先把文件复制进本应用的相关目录;2、当应用被授权访问用户的联系人、音乐等数据时,可以通过系统框架提供的专用API进行操作。
iOS通过权利(entitlement)列表来授权应用的一切操作。权利列表是一组key-value对的集合,用来标识特定的应用操作能力,比如打开一个向外的网络套接字。
苹果建议的开发策略是,首先把应用的权利(entitlement)最小化,然后根据调试过程中出来的权利违反事件(entitlement violation),修改权利列表。
[4]
改善建议:如果分配操作权利成为开发者的负担,则不能很好地执行最小权利策略。可以考虑跟代码覆盖度测试相结合,对应用的操作权利需求进行自动化探测。
[4]
一个应用程序难免要存储一些用户的数据,iOS提供了4个安全存储类别供开发者考虑。至于以何种加密级别来存储取决于应用的实际需要。
类密钥由passcode导出的密钥和UID进行保护。锁屏后一段时间,内存上已解包的类密钥就被清除掉。
有一些文件在打开后,便需要在锁屏时继续读写,比如下载邮件附件。这个使用非对称的椭圆曲线公钥密码来实现。这个类别保护的文件,在新建时,除了正常的文件密钥(per-file key),还将获得公钥/私钥对。一个共享秘密通过该文件的私钥和类公钥(类的私钥由Passcode和UID进行保护)计算出来。文件密钥被共享秘密的哈希值进行包装,和文件公钥一起保存在元数据中(同时私钥被销毁)。当文件关闭的时候,文件密钥也从内存中删除。当再次打开这个文件的时候,这个共享秘密通过类私钥和文件的公钥被重建出来,它的哈希用于提取文件密钥,从而解密文件。在文件关闭前,文件密钥不会被销毁(http://esec-lab.sogeti.com/post/iOS-5-data-protection-updates)。
和完全保护类似,但是锁屏不销毁类密钥。
其实还是有保护,类密钥只通过UID进行保护。
密钥链存储类似于文件存储,也有一套密钥类,和文件安全存储类的对应关系如下:
密钥的数据结构如下所示:
元数据
创建时间
上次修改时间
属性的SHA-1哈希值(用于不解密情况下的查找)
帐号
服务名称
...
加密数据
版本号
保护类
密钥(经保护类密钥进行包装)
属性key-value词典(二进制的plist,用密钥进行加密)
参考文献:
[1] Apple Inc, IOS Security, 2012.10,
http://www.apple.com/ipad/business/docs/iOS_Security_Oct12.pdf
[2] Andy Greenberg, Inside Evasion, The Most Elaborate Jailbreak To Ever Hack Your iPhone, 2013.02.05,
http://www.forbes.com/sites/andygreenberg/2013/02/05/inside-evasi0n-the-most-elaborate-jailbreak-to-ever-hack-your-iphone/
[3]Dionysus Blazakis, The Apple Sandbox, 2011.01.11,
http://dl.packetstormsecurity.net/papers/general/apple-sandbox.pdf
[4]Apple Inc, App Sandbox Design Guide, 2013.03.14,
http://developer.apple.com/library/mac/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxDesignGuide.pdf
[5]Apple Inc, File System Programming Guide, 2012,
http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW2