SELinux on Android(三)

咳咳,继续。


  • 应用案例


下面有几个关于攻击安卓的例子,用来讲解如何精心开发自己的软件和制定相关的SELinux策略:

软链接 —— 因为软链接看似一个文件,他们经常被作为一个文件来读取。这可能会导致系统被攻击。例如,一些特权组件(例如init)改变某个文件的权限,有时被过分的暴漏。

攻击者这时可能会将这些公开的文件用软链接替换掉,用自己写的代码来代替,当然,自己写的代码可能会允许攻击者修改任意文件。但是如果你知道自己写的应用程序肯定不会和软链接打交道,那你就可以使用SELinux来阻止这一切的发生。

系统文件 —— 我们都知道系统文件只有系统服务可以修改,但是,因为netd、init和vold都是(Native service)以root身份运行的,他们可以访问这些系统文件。所以,如果netd被攻陷,它就可以破坏这些系统文件,这势必会危害系统服务本身。

有了SELinux,你就可以标记这些文件为原生的系统数据文件。因此,可以读和写这些文件的domain只有系统服务。即使netd被攻陷,它也不能切换domains到系统服务的domain。尽管它具有root权限,也无法访问这些系统文件。

应用数据 —— 另外一个例子是,一些进程必须以root身份运行,但是我们又不想让其访问应用数据。SELinux在这里就非常有用了,因为可以做声明来阻止某进程去访 问应用数据,例如某一个和应用数据无关的domain,就可以被阻止,而不能去访问internet。

设置文件属性 —— 有一些命令,例如chmod和chown等,我们可以为他们确定一个文件集,在这个文件集里,相关的domain可以执行文件属性设置命令。对于任何该文 件集外部的文件,一旦文件属性变化,则被阻止,即使是root也没门儿。所以,一个应用程序可以针对标记过的app_data_files,执行 chmod或者chown,但是不能直接对未经标记的shell_data_files或者system_data_files进行文件属性设置。

 

  • 相关文件

如果你决定定制SELinux策略的配置,那么本段可以帮助你。参见客制化段落的各个步骤。

建议设备生产商从默认的安卓SELinux策略开始修改,对默认的策略做最小的修改,来解决自己对安卓系统的修改和添加所带来的安全问题。现存的安卓SELinux策略文件在~platform/external/sepolicy目录下。

安卓对SELinux策略版本进行升级,这允许 SELinux模式可以在某个domain设置为permissive(而在其他domain设置为enforcing)。例如,如果你在一个单一的 domain中运行所有你的应用程序,你可以将该domain设置为permissive,然后将所有其他的功能和他们的domains设置为 enforcement。domains通过密钥(用于对应用程序进行签名)和应用发生关联。这些设置是在SELinux策略原文件*.te中进行配置 的。

如果你要定制SELinux,那么你必须创建或者编辑下面这些文件:

新的SELinux策略原文件(*.te) —— 位于<root>/device/manufacturer/device-name/sepolicy路径。这些文件定义domains和 他们的labels。在编译过程中新的策略文件和现存的策略文件会链接起来,成为一个SELinux内核策略文件。

重要提示:不要修改app.te文件,这个文件是AOSP提供的。如果你修改了,那么你就破坏了第三方应用的安全环境,将他们置于危险的境地。

修改BoardConfig.mk文件 —— 该文件位于<device-name>路径下,该路径包含了sepolicy子路径。这个文件必须得倒合适的修改,用于引用sepolicy子路径。

修改file_contexts文件 —— 该文件位于sepolicy子路径。这个文件用于给文件打标签,并且在用户空间进行管理。因为你生成了新的策略,所以你要修改这个文件来引用他们。为了让 新的file_contexts产生作用,你必须在一个将再次打上标签的文件中运行restorecon。

sepolicy路径中剩下的其他文件要么是自动生成的,要么应该保持原封不动。策略文件的形式是:allow,domain和context,为一个动作集合:

Allow —— 给角色权限来在指定的domain中实现具体动作,该动作在context中做具体描述

Domain —— domain代表了规则的范围,并且在内核里面可以转化为一个安全的ID(SID)。

Context —— 规则的标识符,这会被转换为一个内核中的整数

 

  • 标签,规则和域

SELinux是由与动作或者策略匹配的标签所决定,而标签取决于你允许了什么。socket,file和process 都有SELinux各自对应的标签。SELinux的决定取决于对象所关联的标签和相互的策略。在SELinux中,标签是由user:role:type:mls_level 这样的形式定义的,其中的type(类型)是影响决策的重要组成部分,而这些对象(objects)则被他所属于的类和类型去匹配其他类的权限检查

策略规则的格式是allow domains types:classes permissions

·         Domain – 进程或者进程集合的标签

·         Type – 对象(e.g. file, socket)或者对象集合的标签

·         Class – 对象(e.g. file, socket)被允许(授权)访问的种类

·         Permission – 允许采取的操作(e.g. read, write)


下面我们来看一个例子:

allow appdomain app_data_file:file rw_file_perms

这条策略的意思是说一个app可以去读写有app_data_file标签的file。注意到这条规则依赖于一个已经定义好的全局的宏文件,这些宏可以在 文件te_macros里面找到。宏是用来提供公共的类,权限,规则,是用来帮助减少由于相关权限缺少而导致失败的可能。在编译时这些这些使用宏的地方将会被宏中所使用的语句替换掉。

以上的格式是创建规则的重要组成部分,再来看一遍,一条规则有这么多

<rule variant> <source_type> <target_type> : <class> <permission>

这条rule表明当一个打着source type标签的对象尝试去以一个符合permission的动作去访问属于class类的有着target_type标签的对象的时候这条规则就会被触发。实际应用中,这条规则常常包含着几条permission比如说:


allow domain null_device:chr_file { getattr open read ioctl lock append write};


domain是所有进程都有的标签,null_device是chr_file类/dev/null的标签,这条策略的意思就是允许对/dev/null进行基本的读写操作。

一般说来一个domain都有与它匹配的打了标签的进程

比如一个APP是运行在自己的打untrusted_app标签的进程中的,所以只能获得对应于这个标签的受限的权限。

随着系统安装的原装APP是在另一个标签下的。而系统应用则是在system_app标签下的拥有另外的权限

下面这些标签可能会在以后出现:

·         socket_device

·         device

·         block_device

·         default_service

·         system_data_type

·         tmpfs

SELinux默认情况是采取最小授权机制。这就意味着除非你在策略文件里面允许了特定的权限后才能hook kernel。这意味着一个良好的策略文件必然是由大量的规则信息组成。对SELinux安全策略的完整设计已经超出了本文档的范文。我们现在的着重点是当打算配置一台安全的android系统应该如何去写配置这些文件,可以参看下面这几个网站

http://seandroid.bitbucket.org/PapersandPresentations.html

https://www.codeproject.com/Articles/806904/Android-Security-Customization-with-SEAndroid

https://www.nsa.gov/research/_files/publications/implementing_selinux.pdf

https://events.linuxfoundation.org/sites/events/files/slides/abs2014_seforandroid_smalley.pdf

https://www.internetsociety.org/sites/default/files/02_4.pdf

https://www.gnu.org/software/m4/manual/index.html

http://freecomputerbooks.com/books/The_SELinux_Notebook-4th_Edition.pdf

下面是让你的设备支持SELinux的步骤

1、 添加内核对SELinux的支持,这个我也不太了解,但是4.4以后是都有的。

2、 为每一个init启动的服务(进程或者后台程序)授予各自的域(domain)

3、 通过下面这些来定制服务:

检查init文件寻找要启动的服务

审核内核的输出信息(dmesg)

寻找(grep)在init域中的进程

4、 为这些新增的进程,驱动,套接字打标签。所有的上述对象都需要打上一个对应他们自己的合适的标签以方便你的安全策略的编写.AOSP中有例子

5、 确保安全策略的稳定性以及授权范围的最小化。



本文由Hack Blog原创,如需转载注明原文链接

作者:wesly 分类:Android 浏览:9503 评论:0
留言列表
发表评论
来宾的头像