赞
踩
SEAndroid(Security Enhanced Android)是美国国家安全局(NSA)根据Android 以Linux 为内核基础的特性,将SELinux 修改移植到Android 系统上而形成的。SELinux通过提前编写各个进程的安全操作规则,防止其进行超越权限的访问来达到保障安全的目的。
SEAndroid 一开始的关注点在于将SELinux 的机制引入到Android 系统中,但是这仅仅是解决了底层的权限管理问题,考虑到这种问题,SEAndroid 结合了Android 的特征,在Framework 层参照了SELinux 的权限管理模式,实现了一种称为Middleware MAC(简称为MAC)的强制访问控制方式。
其安全结构可以简单表述为:SEAndroid =Android+MAC+ SELinux
因为SEAndroid 目前正处于发展阶段,在master 源码库里面只存在Install-time MAC 的强制访问控制方式。在分支代码库里面存在其它类型的强制访问控制方式。
图1. SEAndroid安全机制
SEAndroid是一种基于安全策略的MAC安全机制,这种安全策略实施在主体和客体的安全上下文之上(主体一般就是进程,而客体一般就是文件)。这个安全上下文由用户、角色、类型、安全级别四个部分组成,每一部分通过一个冒号来分隔。
例如,图1斜体部分即为SEAndroid安全上下文。其中,u:r:unstructed_app:s0描述的是用户安装的APK所在进程的安全上下文,而u:object_r:app_data_file:s0描述的是用户安装的APK在运行过程中生成的数据文件的安全上下文。当每一个进程和文件都关联上一个安全上下文之后,系统管理员就可以基于这些安全上下文制定一个安全访问策略,用来规定什么样的进程可以访问什么样的文件。
SEAndroid安全机制与传统的Linux UID/GID安全机制是并存关系的,也就是说,它们同时用来约束进程的权限。当一个进程访问一个文件的时候,首先要通过基于UID/GID的DAC安全检查,接着才有资格进入到基于SEAndroid的MAC安全检查。只要其中的一个检查不通过,那么进程访问文件的请求就会被拒绝。
以SELinux文件系统接口为边界,SEAndroid安全机制包含有内核空间和用户空间两部分支持。这些内核空间模块和用户空间模块的作用以及交互如下表所示:
用户空间 |
---|
主要模块 |
安全上下文(Security Context) |
安全服务(Security Server) |
安全策略(SEAndroid Policy) |
内核空间 |
主要模块 |
Linux安全模块(SELinux LSM)(通常包括访问向量缓冲(Access Vector Cache)和一个安全服务(Security Server)) |
SELinux安全访问流程:
首先,SELinux会在LSM中注册相应的回调函数。其次,LSM会在相应的内核对象子系统中会加入一些Hook代码,以便SELinux可以进行安全检查 。
SELinux在进行安全检查的时候,首先是看一下自己的Access Vector Cache是否已经有结果。如果有的话,就直接将结果返回给相应的内核子系统就可以了。如果没有的话,就需要到Security Server中去进行检查。检查出来的结果在返回给相应的内核子系统的同时,也会保存在自己的Access Vector Cache中,以便下次可以快速地得到检查结果。
内核中的资源在访问的过程中,一般需要获得三次检查通过:
SELinux检查,即基于安全上下文和安全策略的安全检查
DAC检查,即基于Linux UID/GID的安全检查
一般性错误检查,例如访问的对象是否存在、访问参数是否正确等
如前所述,这个标签实际上就是一个字符串,它由四部分内容组成,分别是SELinux用户、SELinux角色、类型、安全级别,每一个部分都通过一个冒号来分隔,格式为”user:role:type:sensitivity”。可通过ps -Z命令查看进程的安全上下文,通过ls -Z来查看文件的安全上下文
下面是针对安全级别和安全类型进行进一步研究分析:
安全级别
它是建立在TE的基础之上的。安全级别最开始的目的是用来对政府分类文件进行访问控制的。在基于安全级别的MAC安全机制中,主体(subject)和客体(object)都关联有一个安全级别。其中,安全级别较高的主体可以读取安全级别较低的客体,而安全级别较低的主体可以写入安全级别较高的客体。前者称为”read down”,而后者称为”write up”。通过这种规则,可以允许数据从安全级别较低的主体流向安全级别较高的主体,而限制数据从安全级别较高的主体流向安全级别较低的主体,从而有效地保护了数据。注意,如果主体和客体的安全级别是相同的,那么主体是可以对客体进行读和写的。
安全级别是由敏感性(Sensitivity)和类别(Category)两部分内容组成的,格式为"sensitivity[:category\_set]",其中,category\_set是可选的。例如,假设我们定义有s0、s1两个Sensitivity,以c0、c1、c2三个Category,那么"s0:c0,c1"表示的就是Sensitivity为s0、Category为c0和c1的一个安全级别。
安全类型
四种类型的对象的安全上下文,分别是App进程、App数据文件、系统文件和系统属性。这四种类型对象的安全上下文通过四个文件来描述:mac_permissions.xml、seapp_contexts、file_contexts和property_contexts,它们均位于external/sepolicy目录中。
在SEAndroid中,通常将用来标注文件的安全上下文中的类型称为file_type,而用来标注进程的安全上下文的类型称为domain,并且每一个用来描述文件安全上下文的类型都将file_type设置为其属性,每一个用来进程安全上下文的类型都将domain设置为其属性。
如:type init domain; 表示用type语句来将类型domain设置类型init的属性。
.三种文件安全上下文关联方式
.两种进程安全上下文设置方式
SEAndroid安全机制中的安全策略是在安全上下文的基础上进行描述的,也就是说,它通过主体和客体的安全上下文,定义主体是否有权限访问客体。SEAndroid安全机制主要是使用对象安全上下文中的类型来定义安全策略,这种安全策略就称Type Enforcement,简称TE。在external/sepolicy目录中,所有以.te为后缀的文件经过编译之后,就会生成一个sepolicy文件。这个sepolicy文件会打包在ROM中,并且保存在设备上的根目录下,即它在设备上的路径为/sepolicy。
其核心思想就是最小权限原则,即主体对客体拥有的权限必须要通过allow语句定义才允许,否则的话,一切都是禁止的。
SEAndroid 源码中的策略文件位于seandroid/external/sepolicy 中,其用于编译时候生成内核策略库文件,其中有几个重要的文件,其名称及功能如下:
文件名 | 功能 |
---|---|
file_contexts 配置文件 | 用于在编译和运行期间(如设备节点,服务套接字文件/init.rc 创建数据目录等)给文件打标签 |
seapp_contexts 配置文件 | 用于标签应用进程和应用程序包目录 |
property_contexts 配置文件 | 用于检查Android 的属性 |
mac_permissions.xml 配置文件 | 是中间件MAC 策略 |
其中seapp_contexts 配置文件和property_contexts 配置文件是标准SELinux 源码中没有的文件。SEAndroid 系统源码作为Android 的一部分和系统源码一起编译并被加入到ramdisk.img 中。在ramdisk.img 中的安全库策略文件编译后为sepolicy.
用户空间的Security Server主要是用来保护用户空间资源的,以及用来操作内核空间对象的安全上下文的,它由应用程序安装服务PackageManagerService、应用程序安装守护进程installd、应用程序进程孵化器Zygote进程以及init进程组成。其中,PackageManagerService和installd负责创建App数据目录的安全上下文,Zygote进程负责创建App进程的安全上下文,而init进程负责控制系统属性的安全访问。
以下是对创建说明的进一步阐述:
应用程序安装服务PackageManagerService在启动的时候,会在/etc/security目录中mac_permissions.xml文件,然后对它进行解析,得到App签名或者包名与seinfo的对应关系。当PackageManagerService安装App的时候,它就会根据其签名或者包名查找到对应的seinfo,并且将这个seinfo传递给另外一个守护进程installed。
守护进程installd负责创建App数据目录。 在创建App数据目录的时候,需要给它设置安全上下文,使得SEAndroid安全机制可以对它进行安全访问控制。Installd根据PackageManagerService传递过来的seinfo,并且调用libselinux库提供的selabel_lookup函数到seapp_contexts文件中查找到对应的Type。有了这个Type之后,installd就可以给正在安装的App的数据目录设置安全上下文了,这是通过调用libselinux库提供的lsetfilecon函数来实现的。
Zygote进程负责创建应用程序进程。 应用程序进程是SEAndroid安全机制中的主体,因此它们也需要设置安全上下文,这是由Zygote进程来设置的。组件管理服务ActivityManagerService在请求Zygote进程创建应用程序进程之前,会到PackageManagerService中去查询对应的seinfo,并且将这个seinfo传递到Zygote进程。于是,Zygote进程在fork一个应用程序进程之后,就会使用ActivityManagerService传递过来的seinfo,并且调用libselinux库提供的selabel_lookup函数到seapp_contexts文件中查找到对应的Domain。有了这个Domain之后,Zygote进程就可以给刚才创建的应用程序进程设置安全上下文了,这是通过调用libselinux库提供的lsetcon函数来实现的。
Init进程在启动的时候,会创建一块内存区域来维护系统中的属性以及Property服务。 这个Property服务通过socket提供接口给其它进程访问Android系统中的属性。其它进程通过socket来和Property服务通信时,Property服务可以获得它的安全上下文。有了这个安全上下文之后,Property服务就可以通过libselinux库提供的selabel_lookup函数到property_contexts去查找要访问的属性的安全上下文了。有了这两个安全上下文之后,Property服务就可以决定是否允许一个进程访问它所指定的属性了。
只有当进程和文件都关联安全上下文之后,SEAndroid安全策略才能发挥作用。也就是说,当一个进程试图访问一个文件时,SEAndroid会将进程和文件的安全上下文提取出来,根据安全策略规则,决定是否允许访问。
Android 的应用程序根据使用语言类型及是否调用链接库可以分为如下几类:
类别 | 说明 |
---|---|
只使用Java 语言编写的程序 | 其默认的是通过Java 虚拟机即Dalvik 解析并执行,其权限控制方式有Android 自带的方式。除此外,SELinux 在底层也提供安全防护,但由于是通过虚拟机解析后的,默认其安全性能得到保障,所提供的策略保护是默认的类型,其安全使用系统默认策略。 |
基于C/C++语言的NDK 开发方式编写的程序 | 可以直接使用SELinux 的安全防护方式。应用程序访问资源方式是通过SELinux 回调函数,经过查询SELinux 策略库、判断后给予是否允许访问的结果。其与一般SELinux 的使用时候类似,故安全性能较高。 |
Java 方式编写的程序中通过JNI 方式调用C/C++链接库 | Java 调用链接库*.so 文件。该类型程序Java 语言执行时候适用正常的Android 安全策略方式,当其调用链接库时候,调用底层C/C++语言的库,此时适用SELinux 安全策略方式。 |
MAC目前研究的Install-time MAC涉及的是应用软件APK中的AndroidManifest.xml文件和策略制定者编写的mac_permissions.xml,Install-time MAC是一种比较严格的权限控制机制,当开发者在AndroidManifest.xml文件中申请的权限并没有包括在mac_permissions.xml中,此时就没法进行应用程序的安装,因为AndroidManifest.xml中的权限必须是mac_permissions.xml中对该应用程序制定策略的权限子集。
在传统的权限配置层面上,SEAndroid区别于SELinux之外,针对Android的特殊性添加了property_contexts和seapp_contexts等文件。Install-time MAC中涉及到的文件主要有mac_permissions.xml、seapp_contexts和*.te。
Install-time MAC存在的两个主线:
其中安装阶段对应于:APK->PMS扫描处理->生成package对象。
而运行阶段对应于:点击应用图标->ActivityManagerService->Zygote->fork产生进程。
这里指的是MAC 中的Install-time MAC 的使用,SEAndroid 在Android 原有的permission 机制检查上加了新的一层过滤,主要体现在对策略库的进一步检查。在源码中是通过InstallPolicy 类进行检查的,InstallPolicy 类中存在解析及存储mac_permissions.xml 文件的属性, 还有用来存储权限字符串的字段以及一个属性pkgPolicy (用来存储那些待检查的APK 中申明使用的权限字符串).
在InstallPolicy 类中存在一个方法determineInstallPolicyType 用来解析mac_permissions.xml 文件,然后将应用对应的白名单和黑名单存放在相应的属性中,之后获得APK 中的权限属性。最后在该类中调用权限检查函数passedPolicyChecks进行权限字符串的匹配工作,该函数中就是使用迭代器得到权限字符串进行一一匹对,然后根据最后的结构来判断是否存在权限的乱用情况。
SEAndroid安全机制的目的不是为了完全杜绝别人攻击我们的设备,而是为了保证我们的设备受到攻击时,受到的损害减少到最少的程度。例如,SEAndroid安全机制并不能完全阻止我们的设备被root,但是它能保证我们的设备被root之后,一些敏感的文件仍然是不可访问,这样就可以最大程度地保护我们的设备。这是因为只要程序是由人类来编写的,就或多或少地存在BUG,或者说漏洞,特别是复杂的程序,进而就会被黑客利用,并且成功地侵入到我们的系统中来。这是防不胜防的。当然,我们并不是说SEAndroid对阻止设备被侵入毫无用处,它在一定程度上还是能加大侵入的技术难度的。
主要弊端: SEAndroid 系统须由开发者来预定义安全策略的弊端
SEAndroid 系统自身存在的最大的问题是沿袭了SELinux 固有的管理员操作方式,只有熟悉SELinux 系统的用户才有能力对系统的策略库进行定制,也就是从终端进行策略的修改,从而改变应用的安全上下文。这种操作方式很不符合面向普通消费者的移动终端操作系统的市场。
通常情况下,SELinux 下管理员需要自己编写应用的策略配置文件*.te,然后进行编译得到policy.xx 文件,当内核启动的时候,将该策略数据库映射到内存中供安全服务器进行查询和控制。同时管理员需要根据不同的需要设置相应的策略规则,进行进程的类型切换,这些都是在以消费者为导向的Android 系统所不能适应的,因为普通的消费者不可能深入系统到这种程度,更不用说进行相应的安全控制了。因此灵活性和易用性有待加强。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。