细数iOS上的那些安全防护

 龙磊,黑雪,蒸米 @阿里巴巴移动安全


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

(3). Team ID

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

0x02 沙盒机制(SandBox)

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

(1). UID/GID permission

一般情况下,iOS会将进程的权限分为root和mobile,一些特殊的模块(比如基带)会有自己的用户组。需要注意的是,所有第三方的app都是运行在mobile权限下的。

(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_XMTY5NjQxMDc0OA==.html

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

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程序的证书和签名机制

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

细数iOS上的那些安全防护的更多相关文章

  1. 细数 Windows Phone 灭亡的七宗罪(过程很详细,评论很精彩,但主要还是因为太慢了,生态跟不上,太贪了,厂商不愿意推广)

    曾梦想仗剑走天涯,看一看世界的繁华 年少的心有些轻狂,如今你四海为家 曾让你心疼的姑娘,如今已悄然无踪影 犹记得上大学攒钱买了第一台智能手机Lumia 520时,下载的第一首歌曲<曾经的你> ...

  2. 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上)【转载】

    转自: DBAplus社群 http://www.toutiao.com/m5762164771/ 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上) - 今日头条(TouTiao.com ...

  3. 转:基于IOS上MDM技术相关资料整理及汇总

    一.MDM相关知识: MDM (Mobile Device Management ),即移动设备管理.在21世纪的今天,数据是企业宝贵的资产,安全问题更是重中之重,在移动互联网时代,员工个人的设备接入 ...

  4. 细数AutoLayout以来UIView和UIViewController新增的相关API

    本文转载至 http://www.itjhwd.com/autolayout-uiview-uiviewcontroller-api/ 细数AutoLayout以来UIView和UIViewContr ...

  5. 细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一

    细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一(转) ADO.NET Entity Framework        ADO.NET Entity Framework 是微软以 ADO.N ...

  6. 细数Qt开发的各种坑(欢迎围观)

    1:Qt的版本多到你数都数不清,多到你开始怀疑人生.从4.6开始到5.8,从MSVC编译器到MINGW编译器,从32位到64位,从Windows到Linux到MAC.MSVC版本还必须安装对应的VS2 ...

  7. IOS上传文件开发

    IOS上传文件开发     在移动应用开发  文件形式上传是不可缺少的,近期把IOS这块文件上传文件代码简单的整理一下.假设大家有须要安卓这边的代码,本人也能够分享给大家! QQ群:74432915 ...

  8. 细数Python Flask微信公众号开发中遇到的那些坑

    最近两三个月的时间,断断续续边学边做完成了一个微信公众号页面的开发工作.这是一个快递系统,主要功能有用户管理.寄收件地址管理.用户下单,订单管理,订单查询及一些宣传页面等.本文主要细数下开发过程中遇到 ...

  9. 基于IOS上MDM技术相关资料整理及汇总

    (转自:http://www.mbaike.net/special/1542.html) 一.MDM相关知识:MDM (Mobile Device Management ),即移动设备管理.在21世纪 ...

随机推荐

  1. [知识笔记]Java 基本数据类型的大小、取值范围、默认值

    数据类型 大小(字节) 范围 默认值 boolean 1/8(1bit) true/false false byte 1 -128~127 (-2^7~2^7-1) 0 short 2 -32768~ ...

  2. [Spring] AOP, Aspect实例解析

    最近要用到切面来统一处理日志记录,写了个小实例练了练手: 具体实现类: public interface PersonServer { public void save(String name); p ...

  3. HTML5 五子棋 - JS/Canvas 游戏

    背景介绍 因为之前用c#的winform中的gdi+,java图形包做过五子棋,所以做这个逻辑思路也就驾轻就熟,然而最近想温故html5的canvas绘图功能(公司一般不用这些),所以做了个五子棋,当 ...

  4. Redis - 常用命令详解

    1.远程连接redis服务器 # 用法:redis-cli [OPTIONS] [cmd [arg [arg ...]]] # -h <主机ip>,默认是127.0.0.1 # -p &l ...

  5. NetBeans连接SQL server数据库教程

    不废话,直接开始 1.下载sqljdbc.jar 可以从微软中国官方网站下载 SQLJDBC微软中国 笔者提供一个网盘链接Sqljdbc.jar 4个压缩包视版本选择,SQL 2012 用sqljdb ...

  6. oracle(sql)基础篇系列(四)——数字字典、索引、序列、三范式

      数字字典表 --查看当前用户下面有哪些张表 select * from user_tables; select table_name from user_tables;   --查看当前用户下面有 ...

  7. Idea 实时编译 和 热部署

    实时编译 idea自动保存编写好的文件,但是不会编译,想要编译需要按ctrl+F9(编译整个项目)ctrl+shift+f9(单个文件),不仅麻烦而且和平常习惯也不相复合.怎么令idea的ctrl+s ...

  8. bootstrap入门

    Bootstrap提供了如下重要的特性:❑一套完整的基础CSS插件.❑丰富的预定义样式表.❑一组基于jQuery的JS插件集.❑一个非常灵活的响应式(Responsive)栅格系统,并且崇尚移动先行( ...

  9. ubuntu 用apt-get 安装apache 和php 之后php不能解析的问题

    sudo apt-get install apache2 sudo apt-get install php7.0 sudo apt-get install libapache2-mod-php //关 ...

  10. C++-文件【1】-按行读文本文件的两种方法

    测试环境—— 系统:Win7 64bit 编译器:TDM-GCC 4.9.2 64-bit Release #include <iostream> #include <fstream ...