logo资料库

将SELinux安全特性加入安卓.pdf

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
焦虑的娃温馨提示:焦虑的娃的专题博客“关注安卓安全”的第二篇竟还是一篇译文,呵呵。最近花了好多时间看了许多 SEAndroid 方面的资料,发现有一篇英文文章讲的很好,简明扼要的概括了 SELinux 是如何应用到 android 系统里面去的。简单介绍了强制访问 控制的概念,如何将 SELinux 添加到安卓,如何定制 SELinux 安全策略,如何验证你所定制的 SELinux 安全策略,同时给出了好几个 应用案例。总而言之,这篇文章可以引领你了解 SEAndroid 的大概情况,有抛砖引玉的效果。请看到文章的朋友们批评指正,有什么 问题就给焦虑的娃留言或者发邮件,我会虚心并且热情地和你探讨。 本文章由焦虑的娃编写,欢迎转载,但是——转载请注明出处。 文章链接:http://blog.csdn.net/obsessive_compulsive/article/details/19567035 作者:焦虑的娃 邮箱:seandroidresearch@163.com 英文原文:http://source.android.com/devices/tech/security/se-linux.html ========================================================================== 将 SELinux 的安全特性加入安卓 引言 作为安卓安全模型的一部分,安卓使用了 SELinux 的访问控制策略。SELinux 的出现大幅度增强了安卓的安全性。此外,还有许多公司 和组织也为增强安卓的安全性做出了不懈的努力。你可以在 android.googlesource.com 站点看到所有安卓源代码及其贡献者。 在 SELinux 的强力保护下,安卓可以更好的对应用程序数据和系统日志进行访问控制。这不仅减轻了恶意程序对系统的影响力,而且保 护了用户不受移动设备上隐藏的恶意代码所攻击。 在安卓的最新版本中,SELinux 是以“enforcing mode”形式存在的,并且具有一套相应的默认的安全策略,该策略遍布于整个安卓开 源工程。
在“enforcing mode”中,非法的操作是被禁止的,并且所有的攻击行为会被 Linux 内核记录下来,保存在 dmesg 里面。针对 SELinux 在安卓中的应用,安卓设备生产商应该做的是:在将 SELinux 的状态置为 enforcing mode 之前,不断收集 SELinux 所报出的系统错误 信息,并依此改善自己的软件,更新安卓系统的 SELinux 策略。 背景 注意,安卓可以更新自己的 SELinux 策略版本,并允许 SELinux 基于 domain 来设置到底处于那一种模式(disable、permissive、 enforcing)。 例如,如果你让自己开发的所有应用程序运行在一个单一的 domain 中,你可以设置该 domain 为 permissive,然后设置其他其他功能 和他们的 domains 为 enforcing 状态。 Domains 通过密钥(用于对应用进行签名)和应用程序建立关联。这是在 SELinux 策略源文件*.te 的顶部进行设置的。 安卓遵循此模型: 即将各个不同应用程序分别孤立在一个单一的 domain 中。基于此,只有 root domain 和 root 级别的进程(例如 initd、installd 和 vold)现在被设置为 enforcing 模式。 普通应用程序的 domain 仍然保持在 permissive 模式,这一举动允许对应用程序的 SELinux 策略做进一步的评估,阻止没必要的系统 错误。但是,恶意程序仍可以在 root domain 激发一个行为(该行为是不被允许的),随之而来的便是导致应用程序的崩溃。 因此,设备生产商应该保留安卓默认的设置,并且只让 root domain 保持 enforcing 状态,直到完全解决了 dmesg 中报告的问题。 也就是说,设备生产商可能需要不断改善他们的 SELinux 的策略实现来满足对操作系统的诸多添加和修改所带来的问题。参见:客制化 段落。 强制访问控制
与安卓的其他安全措施协同工作,安卓的访问控制策略很大程度上限制了目前脆弱的设备和账户受到潜在的破坏。安卓的 DAC(自主访 问控制)和 MAC(强制访问控制)可以提供一个强有力的方法,确保你的软件运行在最低权限级别。这不仅削弱了攻击行为对系统的影 响,而且减小了恶意进程重写系统数据,甚至偷窃数据的可能性。 从安卓 4.3 版本开始,在传统 DAC 的基础上,SELinux 为安卓提供了 MAC 保护伞。举例说明:有些进程必须以 root 身份运行来向原 始块设备写入数据。我们知道,在传统的基于 DAC 的 Linux 环境中,如果 root 用户被攻陷,那么拥有 root 权限的进程则可以向任何原 始快设备中写入数据。然而,现在安卓有了 SELinux 的帮助,SELinux 可以用来标记这些设备,以实现即使获取到 root 权限,该进程也 仅可以向策略中指定的设备写入数据,其他的设备想都别想。 参见“用例段落”中更多地例子,来理解 SELinux 是如何抵御威胁的。 如何把 SELinux 特性加入到安卓中 安卓中的 SELinux 目前是以 enforcing mode 存在的,而不是 disable 状态或者 permissive 状态(permissive 状态可以作为指引,使 测试和开发变得更加容易)。 尽管 enforcing mode 是全局的,请牢记着这种情况在基于单个 domain 的这种情况可是例外,就像在应用 domain 中一样。 SEAndroid 拥有一切 SELinux 的特征。你只需要把最新的安卓内核整合进来,然后把~platform/external/sepolicy(你可以在该路径 下找到许多例子)路径下的文件包含进来:  https://android.googlesource.com/kernel/common/  https://android.googlesource.com/platform/external/sepolicy/ 这些文件在编译时会包含 SELinux 内核安全策略并兼容以前老版本的安卓操作系统。 把这些文件放置在/device/manufacturer/device-name/sepolicy 路径下。
然后修改 BoardConfig.mk 文件(该文件位于包含 sepolicy 的子路径),来引用 sepolicy 策略文件,方法如下: BOARD_SEPOLICY_DIRS := \ /device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION := \ genfs_contexts \ file_contexts \ sepolicy.te 在重新编译整个工程之后,你的设备就具备 SELinux 功能了。 你现在可以定制自己的 SELinux 策略,来适应你自己对安卓系统的修改(这将会在定制段落说明),或者验证你的当前存在的配置(后面 有介绍)。 客制化 一旦你在安卓系统中整合了这些基础功能,并且彻底地分析了结果,你就可以在你自己的策略设置中添加条目来对安卓系统做一些客制 化的工作。 当然,你添加的这些策略必须满足安卓兼容性程序的需求,并且,你不能移除默认的 SELinux 设置。 设备生产商不应该移除现存的安卓安全设置。否则可能会破坏 SELinux 在安卓上的部署,破坏受 SELinux 保护的应用的良好安全环境。 这也包含了第三方应用(需要改进以变得更易用和更具操作性)。在具备 SELinux 功能的设备上,如要应用正常工作,则绝不允许自身有 任何修改。 参见内核安全特征段落,该段提供了安卓兼容性定义文档(针对特殊要求): http://source.android.com/compatibility/index.html
SELinux 使用白名单的方法,这意味着 SELinux 会向某些特殊的角色赋予特权。 因为目前安卓默认的 SELinux 策略已经支持整个 AOSP,OEM 实际上不需要再去修改 SELinux 的默认设置。但是,如果 OEM 做了 SELinux 策略的修改和定制,就应该特别注意,切勿破坏现存的应用。这里给出一些建议吧: 1. 使用最新的安卓内核; 2. 采用最少特权原则; 3. 你只管处理你自己对安卓系统的添加和修改,其他的不用管。因为默认的安全策略会自动在 AOSP 的代码库中产生作用。也就是说, 你对安卓原生态系统添加了什么内容,你就写你所添加内容对应的策略配置就 OK 了,其他的就别管了,否则可能会出问题(这时 我的理解); 4. 把软件组件划分为不同的模块,由不同的模块分别执行单一的任务; 5. 建立 SELinux 策略,该策略可以将这些任务从无关的功能中孤立开来; 6. 将这些策略写入*.te(SELinux 策略文件的扩展)文件中,该文件位于: /device/manufacturer/device-name/sepolicy; 7. 发布你定制的 SELinux 版本时,先让其处在 permissive mode 中(因为还没经过测试噢); 8. 分析结果,并不断改善策略配置。 一旦将自己的 SELinux 定制内容整合到安卓系统中,OEM 安卓开发过程应该包含一个步骤来确认 SELinux 的兼容性。在一个理想的软 件开发过程中,SELinux 策略只有在软件模型改变时才会发生改变,而不是在实际的实现时(不是很懂)。 当设备生产商开始定制 SELinux 时,应该首先仔细审核对安卓的添加内容。如果他们添加了一个组件,用以实现一个新的功能,设备生 产商必须确保该组件满足安卓安全策略的要求,同时也要(在开启为 enforcement 之前)满足 OEM 精心开发的相关安全策略。 为了阻止非必要的问题发生,最好能够做到足够的宽泛和兼容,而不是过于限制和不兼容,结果是破坏了的设备功能。相反的,设备生 产商对安卓系统的改变将会使其他人受益,它们应该提供一个针对默认 SELinux 策略的修改补丁。如果该补丁可以直接打给默认安全策 略,那么设备生产商将不再需要在每个安卓发布版中做相应的修改。 应用案例
下面有几个关于攻击安卓的例子,用来讲解如何精心开发自己的软件和制定相关的 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) —— 位于/device/manufacturer/device-name/sepolicy 路径。这些文件定义 domains 和他们的 labels。在编译过程中新的策略文件和现存的策略文件会链接起来,成为一个 SELinux 内核策略文件。 重要提示:不要修改 app.te 文件,这个文件是 AOSP 提供的。如果你修改了,那么你就破坏了第三方应用的安全环境,将他们置 于危险的境地。  修改 BoardConfig.mk 文件 —— 该文件位于路径下,该路径包含了 sepolicy 子路径。这个文件必须得倒合适的 修改,用于引用 sepolicy 子路径。  修改 file_contexts 文件 —— 该文件位于 sepolicy 子路径。这个文件用于给文件打标签,并且在用户空间进行管理。因为你生成 了新的策略,所以你要修改这个文件来引用他们。为了让新的 file_contexts 产生作用,你必须在一个将再次打上标签的文件中运 行 restorecon。 sepolicy 路径中剩下的其他文件要么是自动生成的,要么应该保持原封不动。策略文件的形式是:allow,domain 和 context,为一个 动作集合:  Allow —— 给角色权限来在指定的 domain 中实现具体动作,该动作在 context 中做具体描述  Domain —— domain 代表了规则的范围,并且在内核里面可以转化为一个安全的 ID(SID)。  Context —— 规则的标识符,这会被转换为一个内核中的整数 举一个例子吧: allow appdomain app_data_file:file rw_file_perms; 这条语句说明,一个应用程序被允许读取或者写入打 app_data_file 标签的文件。在编译的过程中,这些重写文件和已有的 SELinux 设 置链接起来,成为一个单独的安全策略。这些重写的文件加到基础安全策略里面比从现有安全策略里面除去来得更好。
一旦新的策略文件和 BoardConfig.mk 更新的比较到位,新的策略配置将会自动在设备上产生作用。 验证你当前 SELinux 的配置 安卓强力推荐 OEM 去测试他们的整个 SELinux 实现方案。当设备生产商实现自己的 SELinux 策略时,应该首先发布他们自己的策略在 permissive mode 状态下。如果可能,可以把新的策略应用到设备列表的测试池。 一旦予以应用,一定要确保 SELinux 是跑在正确的 mode 上,这可以通过下面命令实现: getenforce 这将会打印全局 SELinux mode:或者 disabled,或者 enforcing 或者 permissive。请注意,这个命令仅仅显示全局 SELinux mode。 如果要为每个 domain 决定 SELinux mode,你必须检查相应的文件。 然后检查错误。错误码是以事件日志的方式发送并存储在内核 dmesg 中,并且你在本地设备上可以看见它。设备生产商应该在设备商 的 demsg 中认真审查 SELinux 的输出,并在发布为 permissive 模式之前,精炼和改善 SELinux 的策略配置,并最终使之成为 enforcing mode。 利用这个内核 dmesg,设备生产商可以轻易的确认系统用户或者系统组件什么时候违反了 SELinux 策略。设备生产商此时可以处理并解 决掉这个恶意的行为:或者对软件做一些修改,或者对 SELinux 策略做一些修改,或者全都修改。 特别的,这些日志消息暗示着什么样的角色和什么样的进程会在策略加强下失败并且为什么会失败。下面是一个例子: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket 解释说明:  上面的 { connectto } 代表到底做了什么操作。它和最后的 tclass(unix_stream_socket)一起,粗略的告诉你“之前到底在谁身 上发生了什么事情”。在这种情况下,我们可以大概了解到,一些什么东西曾试图链接一个 unix stream socket。
分享到:
收藏