安卓SEAndroid安全机制初探

这是一篇Android系统SEAndroid安全机制的学习笔记。主要参考内容“老罗的Android之旅”博客。

一、SEAndroid是什么?

从4.3开始,Android引入了一套基于SELinux的安全机制,称为SEAndroid,来加强系统安全性。

 

引入新的安全机制肯定是要解决之前安全机制的不足。所以先看一下SEAndroid之前安卓系统有什么样的安全机制。

 

其实安卓之前安全机制并不复杂,《Android安全攻防权威指南》第二章有描述,就是两点:

1.基于Linux UID/GID的进程隔离(安卓沙箱)

在Linux中,每一个用户都拥有一个用户ID,并且也有一个用户组ID,分别简称为UID和GID。此外,Linux系统的进程和文件也有UID和GID的概念。Linux就是通过用户、进程、文件的UID/GID属性来进行权限管理的。

 

Linux内核在启动完成后,启动的第一个进程是init进程,它是以root权限运行的。然后init进程fork出login进程用于用户登录,用户登录成功之后由login来fork出一个shell进程,因此shell进程也是root权限。而后shell进程通过调用setuid来进行降权操作。

 

因此后面用户的shell进程以及通过shell运行的进程都是以用户UID权限运行的。如果一个用户想将一些自己创建的文件交给另外一个用户访问,那么应该怎么办呢。Linux将文件的权限划分为读、写和执行三种,分别用字母r、w和x表示。每一个文件有三组读、写和执行权限,分别是针对文件的所有者、文件所有者所属的组以及除了所有者以及在所有者所属组的用户之外所有其它用户。这样,如果一个用户想要将一个自己创建的文件交给另外一个用户访问,那么只需要相应地设置一下这个文件的其它用户权限位就可以了。

 

Android是一个基于Linux内核的系统,但它并不像传统Linux系统登录才能使用。Android系统将每一个安装在系统的APK都映射为一个不同的Linux用户。也就是说,每一个APK都有一个对应的UID和GID。这些UID和GID是在APK安装的时候由系统安装服务PackageManagerService分配的。

 

我们知道,APK所运行在的进程是由另外一个系统服务ActivityManagerService负责启动的。

 

ActivityManagerService在启动APK进程之前,会先向PackageManagerService查询APK安装时分配到的UID和GID。有了APK的UID和GID后,ActivityManagerService就向另外一个以root身份运行的zygote进程发出创建APK进程的请求。Zygote进程收到请求之后,就会fork出一个子进程来作为请求创建的APK进程。

 

我们上面提到,zygote进程是以root身份运行的。因此,它fork出来的子进程,也就是APK进程,在一开始的时候也是以root身份运行的。不过,APK进程在可以执行APK代码之前,会通过系统接口setuid将自己的UID设置为APK安装时分配到的UID。这个过程与传统的Linux系统通过login进程启动用户shell进程的过程非常类似。通过这种方式,就可以保证每一个APK进程都以不同的身份来运行,从而保证了相互之间不会受到干扰。这就是所谓的沙箱了,这完全是建立在Linux的UID和GID基础上的。

 

2.Permission的应用层权限控制

一个应用如果需要访问一些系统敏感或者特权资源,那么就必须要在AndroidManifest.xml配置文件中进行申请,并且在安装的时候由用户决定是否赋予相应的权限。应用安装过后,一般是通过系统服务来间接使用系统敏感或者特权资源的。这样系统服务在代表应用使用这些资源之前,就会先检查应用之前是否已经申请过相应的权限。如果已经申请过,那么就直接放行,否则的话,就拒绝执行。

二、传统安全的机制缺陷

这种基于Linux UID/GID的安全机制存在什么样的问题呢?注意我们前面提到的,当一个用户想将授予另外一个用户访问自己创建的文件的时候,它只需要修改一下该文件的访问权限位就行了。也就是说,在Linux系统中,文件的权限控制在所有者的手中。因此,这种权限控制方式就称为自主式的,正式的英文名称为Discretionary Access Control,简称为DAC。

 

在理想情况下,DAC机制是没有问题的。然而,在现实中,会产生严重的安全问题。例如,一个用户可能会不小心将自己创建的文件的权限位错误地修改为允许其它用户访问。如果这个用户是一个特权用户,并且它错误操作的文件是一个敏感的文件,那么就会产生严重的安全问题。这种误操作的产生方式有三种:

 

  1. 用户执行了错误的命令

  2. 负责执行用户命令的程序有BUG

  3. 负责执行用户命令的程序受到攻击

 

由此可见,DAC机制只能在理想情况下没有问题,但是在现实中是防不胜防!例如,GingerBread漏洞就是通过攻击以root身份运行Android磁盘管理守护进程vold来获得root权限,从而实现对设备进行root的。

 

注意,上面我们说的DAC问题虽然是针对内核级别的Linux UID/GID机制,然而同样适用于应用级别的Permission机制。这个问题通过MasterKey漏洞表现得淋漓尽致。我们知道,MasterKey漏洞可以在不改变签名的情况下对APK进行篡改。这会导致什么后果呢?假如被篡改的APK申请有特殊的Permission,那么就意味着嵌入的恶意代码可以任意地使用这些特殊的Permission。

 

更为严重的是被篡改的APK是一个系统APK。Android系统的Permission分为两种,一种是所有APK都可以申请的,另一种是系统APK才可以申请的。只有系统APK才可以申请的Permission更为敏感,例如用来安装APK的Permission–android.permission.INSTALL_PACKAGES。这意味着一个具有android.permission.INSTALL_PACKAGES的系统APK被篡改后,恶意代码就可以在设备上安装任意的恶意APK了。

 

事实上,应用级别的Permission机制也是建立在Linux UID/GID基础上的。当我们在APK的AndroidManfest.xml配置文件中申请某一个Permission的时候,Android系统的安装服务PackageManagerService除了会记录它申请有相应的Permission之外(以便APK调用需要权限的API接口时进行验证),还会将APK加入到相应的某个Linux用户组去。这是因为在Android系统中,并不是所有的特权操作都是间接地通过系统服务来执行的,例如网络访问。一旦一个APK申请网络访问的Permission,那么它就会加入到Linux的网络用户组去,这时候APK就可以通过创建socket来访问网络了。

 

这样,在Android系统中,无论是应用级别的Permission机制,还是内核级别的Linux UID/GID机制,都同样会受到DAC问题的困扰。这时候我们就需要一种更为强有力的安全机制来保证系统的安全。

 

现在我们知道,无论基于Linux UID/GID的安卓沙箱,还是安卓应用层的Permission,其不够安全的原因是使用了DAC,也就是自主式的权限控制。

三、SEAndroid如何解决上述问题

那安卓如何应对DAC带来的安全机制方面的缺陷呢。方法是MAC,MAC的全称是Mandatory Access Control,翻译为强制访问控制。

 

在MAC机制中,用户、进程或者文件的权限是由管理策略决定的,而不是由它们自主决定的。例如,我们可以设定这样的一个管理策略,不允许用户A将它创建的文件F授予用户B访问。这样无论用户A如何修改文件F的权限位,用户B都是无法访问文件F的。这种安全访问模型可以强有力地保护系统的安全。SEAndroid就是一种MAC机制。

 

在SEAndroid中,每一个进程和文件都会关联有一个安全上下文。这个安全上下文由用户、角色、类型、安全级别四个部分组成,每一部分通过一个冒号来分隔。例如,u:r:t:s0描述的就是一个SEAndroid安全上下文。当每一个进程和文件都关联上一个安全上下文之后,系统管理员就可以基于这些安全上下文制定一个安全访问策略,用来规定什么样的进程可以访问什么样的文件。

 

上面描述的SEAndroid安全机制如图一所示:

安卓SEAndroid安全机制初探

 

红色标注的即为SEAndroid安全上下文。其中,u:r:unstructed_app:s0描述的是用户安装的APK所运行在的进程的安全上下文,而u:object_r:app_data_file:s0描述的是用户安装的APK在运行过程中生成的数据文件的安全上下文。

 

从图中可以看到,SEAndroid安全机制与传统的Linux UID/GID安全机制是并存关系的,也就是说,它们同时用来约束进程的权限。当一个进程访问一个文件的时候,首先要通过基于UID/GID的DAC安全检查,接着才有资格进入到基于SEAndroid的MAC安全检查。只要其中的一个检查不通过,那么进程访问文件的请求就会被拒绝。

 

关于SEAndroid安全机制,还有一个关键点是值得提及的。那就是SEAndroid安全机制的目的不是为了完全杜绝别人攻击我们的设备,而是为了保证我们的设备受到攻击时,受到的损害减少到最少的程度。例如,SEAndroid安全机制并不能完全阻止我们的设备被root,但是它能保证我们的设备被root之后,一些敏感的文件仍然是不可访问,这样就可以最大程度地保护我们的设备。

四、总结

  1. SEAndroid是什么,是基于SELinux实现的一种强访问控制的安全机制(MAC)

  2. 为什么引入SEAndroid,传统的DAC机制存在缺陷(安卓沙箱和Permission机制)

  3. 以上只是对SEAndroid的一个粗略认识。接下来要学习,一、SEAndroid的实现原理,二、SEAndroid的应用场景

五、参考资料

  1. SELinux by Example – Using Security Enhanced Linux

  2. Security Enhanced (SE) Android: Bringing Flexible MAC to Android

  3. 老罗的相关博客,http://blog.csdn.net/luoshengyang/article/details/35392905

你可能感兴趣的:(安卓SEAndroid安全机制初探)