iOS 系统安全机制
共 3646字,需浏览 8分钟
·
2022-04-09 07:23
引言
在开发过程中,经常会遇到这么一些问题:
修改App结构后无法运行
不能直接读取其他应用程序
程序每次运行地址都不一样
系统升级了不允许降级
带着这些问题,我们来学习一下,iOS系统提供的安全机制。
iOS系统安全架构
上图是苹果官方的iOS系统安全架构图,他分为两个部分,第一个部分是硬件和固件层,上面提供的安全保障;第二个部分是软件上面提供的安全保障。
我们可以看到,在硬件层上面,它有一个加密引擎,对我们的设备密钥、主密钥以及Apple的根证书进行加密。除了加密引擎以外,他还有一个Secure Enclave的一个模块,这个模块是用来加密和解密,我们touch ID保存用户的指纹密码。
再往上看他的软件层有一个用户分区,整个用户分区是完全加密的,而且这个加密功能是不能关闭的,苹果的加密引擎是硬件级别的,所有进出的存储数据都要通过苹果加密引擎进行加密,而且加密引擎进行加密的key是跟硬件相关的。所以说我不能把一个设备加密的数据拿到另外一个设备上面去解密,这样是行不通的。
最后,应用沙盒提供了一个数据保护类的一个安全机制,这个数据保护类可以保护我们应用类数据的安全性。比如我们在应用沙盒里面写入的数据,我们可以通过数据保护类限定只有在用户解锁了设备之后才能读取这个数据。
接下来,我们将从安全启动链系统
、应用代码签名
、沙盒机制
、ROP
、ASLR
、加密和数据保护
几个方面来认识iOS系统安全架构。
安全启动链系统
在启动过程中,每一步所包含的组件都是通过苹果的签名,只有验证了签名之后才能继续往后面执行。我们来看下系统启动的流程,在iOS设备里面集成了一段名为Boot ROM的代码片段,这段代码被烧制到处理器的一块存储上并且是只读的,在系统启动的时候,它会通过苹果的证书对底层引导加载程序,进行签名验证。如果通过验证的话,那么底层加载引导程序就会对引导加载程序进行验证,如果引导加载程序也通过验证了才会去加载内核。在上面所谓的过程中都会有签名验证,如果某一部发现签名验证失败了,就会进入到恢复和固件升级模式。
系统软件授权机制是为了避免设备降级为缺少最新安全性更新的早期版本,iOS采用了名为系统软件授权的构成,下面我们通过的刷入固件到手机上面这么一个流程来讲解。
我们的固件,要通过cpu刷到手机上面去了,cpu在写入我们的固件之前,会让iTunes把我们的固件签名发送到服务器,如果服务器开启了验证的话,它就会返回。验证许可或者是验证许可加一个随机串,拿到这个验证许可的时候,我们才能通过验证,cpu才会真正的把我们的固件刷到手机上面去上面去。
如果苹果关闭了验证,在早期的版本,如果只返回一个验证许可,我们可以通过保存SHSH来欺骗CPU写入我们的固件。但是在后面的版本,苹果除了返回验证许可之外,还返回了一个随机串,这个随机串是和硬件相关的并且只能使用一次,也就保障了,最后数字是不能模拟的,所以我们保存SHSH是没有用。
应用代码签名
应用代码签名是为了保证所有的应用都是来一致来源,并且没有被篡改,iOS要求所有的可执行代码都是通过苹果颁发的证书进行签名,包括我们的可执行程序,里面的代码或者代码加载的动态库,以及加载的资源,那么可执行代码和动态库,在我们运行的时候会进行签名验证,只有验证通过之后才能正常运行。
沙盒机制
iOS的还提供了沙盒机制,保证我们所有运行的应用都是在一个沙盒模块里面。从上面这张图,我们可以看到,我们安装一个应用时候,他都是运行在一个隔离的环境,每一个应用都是一个隔离的环境,并且互不干扰,也不能随意去访问其他应用程序的数据。所以沙盒会有这么几个特点:
每个应用程序都有自己的存储空间; 应用程序不能直接去访问别的程序的存储内容。比如说它不能读取其他app文件或者内容; 应用程序所请求的数据都要通过权限的检测。这里所说的请求数据,就是类似于短信,照片等等这些数据,如果我们应用程序要去访问这些数据,那么他会通过一个权限检测,让用户决定是否允许你去访问这个数据;
ROP[1]
处理器能区分哪部分内存是可执行代码哪部分内存是数据,他不允许数据的执行,只允许代码的执行,下面我们看一个简单的例子。假设这是一个目标程序,它上面是数据段,下面是代码的,如果我们把恶意代码作为数据写到数据段里面去,他是没有办法执行的,只有在代码段里面的内容才能执行,在数据段里面的内容是无法执行。
我们可以通过ROP创建一块可写入可执行的内存时。首先我们来解释一下什么叫ROP,就是相当于把我们程序里面不同地方的代码片段组合起来,通过一个指令流程去执行,来达到我们最终的目的,那么如果我们通过ROP创建一块可写入可执行的内存区域,往里面写入我们自己的一些代码,但是这些代码是我们自己写入的,他是没有通过签名的,这个时候代码签名的作用就体现出来了,他是不会允许这块代码的执行,当然,我们可以只通过ROP把目标的一些代码片段连接起来,执行我们自己想要的一些功能。
ASLR[2]
再来看一下地址空间布局随机化这个特性,也是为了避免ROP攻击。因为ROP攻击必须知道一个指定的地址才能拿到我们想要的代码片段,然后再来执行,那么地址空间的随机化,就是说在二进制文件、库文件、动态库文件和堆栈内存地址的位置都是随机的,我们把这些文件加载到内存中的时候,它加载的基地址每次都是变化的。我们可以通过这么一个命令image list -o -f
来查看我们应用程序中加载的模块的基地址。
下面我们来演示一下,这是我们编写的一个简单Demo,我们在程序执行的入口下一个断点:
然后,让程序跑起来。跑起来之后,他会断到这个断点上面,这个时候我们用刚才的命令是查看他加载的模块以及模块的地址。我们可以看到,现在这个可执行文件加载的基地址是ef9e000
。
我们再来运行一次,再通过的命令去查看他加载的模块,我们看到这个可执行文件加载的基地址变为2f1e000
,所以说他每次在加载的时候,他的地址都是随机的。
通过刚刚的实验,我们看到我们的可执行程序,在加载的时候,他每次加载在内存中,他的基地址都是变化的。
加密和数据保护
我们文件中的内容是通过文件密钥加密的,当然,文件密钥是通过类密钥加密,并且保存在文件元素之中。而文件原数据是通过文件系统密钥来加密的,那么此时如果我们要去读取一个文件的内容,只有硬件和密码密钥同时拥有,这个加密文件才能被解密。如果我们把加密的文件内容放到其他的硬件上面去解密,由于硬件密钥在每一个设备上面都是不一样的,所以它不能正确的解密出来。如果我们用户没有输入密码密钥,那么这个文件内容也不能解密出来。当然,这里我们看到一个文件系统密钥,这个文件系统密钥可以实现快速抹除的功能,我们只要删除了这个文件系统密钥,那么所有的文件都不能访问,所以就能快速入抹除设备的数据。
总结
安全启动的安全启动链,在系统启动的时候会保障我们启动的系统是受信任的;
系统软件授权机制,它能保障我们的系统更新之后就不能退回到原来的老的版本;
应用代码签名,所有的运行的代码都要通过苹果的签名才能运行;
运行时的安全性,主要包括三个点:首先是沙盒机制,苹果提供了沙盒机制,让我们应用运行在沙盒里面。再一个是数据执行保护,他能区别哪些是数据,哪些是代码,数据是不能运行代码才能运行。最后是地址空间布局随机化,每一次程序加载的时候,他的基地址都是随机变化的;
苹果提供了数据加密保护类来保护我们应用里面的数据的安全性。
虽然iOS系统提供了很多的安全保障来保障我们应用的安全性,但是还是会存在很多问题。比如在之前XcodeGhost的问题,因为开发者使用了第三方的开发工具,而第三方开发工具中又嵌入了恶意代码,所以导致我们在编写应用的时候把恶意代码直接编写到我们应用当中去了,系统也是无法检测到的,因为所有的代码都是经过签名验证,并且运行在系统中。
除了第三方工具带来的危害以外,我们还可以通过越狱来破坏iOS系统本身的安全。在越狱之后,很多iOS系统权限都会被突破,我们可以直接直接以root权限去运行我们的一些应用,所以这些应用我们可以随意读取系统的一些文件等等。
参考资料
ROP: https://blog.csdn.net/jinzheng069/article/details/14184401
[2]ASLR: https://www.jianshu.com/p/fc4abdb50b2e
来源:喵渣渣
https://juejin.cn/post/7077942169016729607
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
面试题
】即可获取