type
status
date
slug
summary
tags
category
icon
password
0x01 引言0x02 背景及题目环境1. 题目2. SELinux0x03 环境与利用思路0x04 Android4.4漏洞利用0x05 Android7.1.1 漏洞复现0x06 Android11漏洞复现 0x07 参考
0x01 引言
2023-Geekcon决赛 AVSS赛道其中的一道题目,现场时因为之前没接触过这种漏洞,当时虽然有想法但是没做出来,留到赛后复现,题目考点在于如何通过System的任意写造成任意代码执行,对于高版本的解题环境可能需要绕过SELinux,这里暂时仅复现了
Android4.4
环境的解题和另外两个环境的部分思路(暂时没有设备进行调试)。0x02 背景及题目环境
1. 题目
其中分析
SELinux-V
的AndroidManifest.xml
,其中包含android:sharedUserId="android.uid.system"
。sharedUserId
属性的值设置为与其他应用共享的 Linux 用户 ID 的名称。 默认情况下,Android 会为每个应用分配其唯一用户 ID。 不过,如果针对两个或多个应用将此属性设置为相同的值,则这些应用都将共享相同的 ID,前提是这些应用的证书集完全相同。具有相同用户 ID 的应用可以访问彼此的数据,如果需要的话,还可以在同一进程中运行。而设置为"android.uid.system"
意味着该APP拥有了System
权限,但是要想设置该值还需要使用与其他系统APP一样的签名密钥。而题目APP已经使用系统密钥完成了签名操作,可以直接安装。而漏洞利用点在于在APP内存在一个广播接收器,该接收器可以进行文件的读写操作,而正好可以利用任意写结合APP的System权限对系统内仅有System可写的文件进行任意写。一般情况下可以利用读和任意写来覆盖掉系统的部分文件完成漏洞利用,而题目要求任意代码执行,很容易想到覆盖APP的APK源文件、APP使用到的动态链接库so文件以及代码缓存文件等等。
2. SELinux
SELinux (Security Enhanced Linux)是由美国NSA(国安局)和 SCC 开发的 Linux 的一个扩张强制访问控制安全模块,目的是最大限度减少系统中服务进程可访问的资源。Google 在 Android 4.4 上正式添加以 SELinux 为基础的系统安全机制,命名为
SEAndroid
。SEAndroid 在架构和机制上与 SELinux 完全一样,基于移动设备的特点,SEAndroid 的只是所以移植 SELinux 的一个子集。DAC与MAC 自主访问权限(DAC) 当程序要操作文件时,系统根据程序的 Owner/Group,对比文件的权限,若通过权限检查,则可操作文件,但可能造成问题:
- root 具有最高权限,若某程序属于root,则该程序可操作系统的任何文件
- 使用者可利用程序来变更文件的权限
强制访问控制(MAC)以进程为主体,任何进程想在系统上干任何事情,都必须在《安全策略文件》中赋予权限。
- TEAC(Type Enforcement Accesc Control):一般用TE表示,是MAC的基础管理思路。根据Security Context中的 type 进行权限审查, 审查 subject type 对 object type 的某个class 类型中某种 permission 是否具有访问权限
- Role Based Accesc Control:MAC的高级管理思路基于角色控制,RBAC 是基于 TE 的 模式
Android 安全模型部分基于应用沙盒的概念。每个应用都在自己的沙盒内运行。在 Android 4.3 之前的版本中,这些沙盒是通过为每个应用创建独一无二的 Linux UID(在应用安装时创建)来定义的。Android 4.3 及更高版本使用 SELinux 进一步定义 Android 应用沙盒的边界。
基于 Android 4.3(宽容模式)和 Android 4.4(部分强制模式),在 Android 5.0 及更高版本中,已全面强制执行 SELinux。通过此项变更,Android 已从对有限的一组关键域(
installd
、netdvold
和 zygote
)强制执行 SELinux 转为对所有域(超过 60 个)强制执行 SELinux。类型强制执行对象的所有者对对象的安全属性没有决定权。标准 Linux 访问控制、所有者/组 + 权限标志(如 rwx)通常称为自主访问控制 (DAC)。SELinux 没有 UID 或文件所有权的概念。一切都由标签控制。这意味着无需强大的 root 进程即可设置 SELinux 系统。注意: SELinux 不允许您回避 DAC 控制。 SELinux 是一种并行执行模型。应用程序必须得到 SELinux 和 DAC 的允许才能执行某些活动。SELinux 的主要模型或强制执行称为类型强制执行。基本上,这意味着我们根据进程的类型定义进程的标签,并根据文件系统对象的类型定义标签。更多关于SELinux细节:SELinux可视化指南
模式Enforcing强制模式:SELinux在运行中,且已经开始限制domain/type之间的验证关系 Permisssive宽容模式:SELinux在运行中,如果验证不正确会发出警告 Disabled关闭模式:SELinux并没有实际运行
0x03 环境与利用思路
首先在
/data
目录下创建system
权限的flag
文件,题目要求对于Android4和Android7两个版本的目标为获取这个flag文件的内容。复现需要准备对应的设备Nexus5
Pixel1
和Pixle2
三台设备,对应三个环境并且需要刷入对应的ROM包。这里缺乏设备仅复现了Android4
版本的利用过程并且给出另外两个的部分思路。按照题目要求,漏洞利用需要是任意代码执行,然后获取到
/data/flag
文件。因此会想到使用system权限的任意写覆盖可执行的文件。0x04 Android4.4漏洞利用
在Android4中可执行的文件首先就会想到
odex
文件,即dalvik
代码的缓存文件,放置于/data/dalvik-cache
目录下。通常情况下APP无法读写该目录下的文件,但是对于system权限的APP而言则不存在该限制。那么就可以想到构造缓存文件替换掉该目录下的一个缓存文件,然后在使用对应APP时将会首先搜寻该目录下的缓存文件,如果存在缓存则直接执行缓存文件,造成恶意代码执行。而一般情况下如果不存在则在
/data/app
目录下寻找APK文件并从中获取可执行的dex文件进行执行。首先要搞清楚odex文件是什么以及基本的格式。
ODEX
是安卓上的应用程序apk中提取出来的可运行文件,即将APK中的classes.dex
文件通过dex优化过程将其优化生成一个odex
文件单独存放,原apk文件中的classes.dex
文件可以保留或删除。一般情况下在APK安装时系统就会提取生成优化的odex文件吗,在Android4系统中放置在/data/dalvik-cache
目录下。在ODEX文件中需要格外注意的几个点:
- 首先是
DexOptHeader
中的checksum
,即校验和,当修改完odex文件后需要重新计算校验和并且修改对应的四字节,否则系统会认为这是错误的odex文件而不选择使用。
- 然后是
DexOpt dependency table
中的mod When
字段和crc
字段,即前8个字节,分别代表了APK中classes.dex文件的修改时间和classes.dex校验和,加入这两个字段也是为了校验,可以看到这两个字段和APK有着直接关系,当APK固定后这两个字段基本固定。一般情况下如果是自己重新生成的odex文件要替换过去,尤其要注意这两个字段需要和原本的odex保持一致,或者直接提取APK中的信息填充这两个字段,否则系统会认为odex文件错误。
一开始的想法是直接单独生成一个修改过的广播接收器类,然后生成odex文件,但是实际上会造成crash,无法执行里面的代码
adb shell发送广播的命令
然后转变思路,既然这样单纯写一个类不行,那为什么不自己修改原APK包中的代码,重新打包后安装,获取到odex文件后patch三个校验相关字段,然后安装原本的APK进去。安装恶意APP,将后面生成的恶意odex文件任意写替换原本的odex,造成恶意代码执行。
然后尝试使用Shell命令直接覆盖SELinux-V APP的odex缓存文件则会成功,但是使用APP的任意写会出现crash的问题。
2023-11-04 03:59:04.544 9225-9225 SystemAppInternalLog
top.geekcon.avss.selinux.v D action.WRITE size=9767520
表明能读到并且正要开始写,但是在写的那一刻会crash,导致实际odex
文件为空的转换思路,既然odex是从
/data/app/top.geekcon.avss.selinux.v-1.apk
中的dex生成的,那么尝试直接写APK文件,然后随意写入字符到odex文件中,造成crash导致odex文件的不可用(为了保险,其实修改APK后可能无法通过校验,不写入空ye'x),从而在/data/app/top.geekcon.avss.selinux.v-1.apk
寻找dex执行,虽然此时不会生成odex但是已经可以任意代码执行,而且该APP的system权限也不会丢失,下一次打开SELinux-V
时才会生成,生成后的odex文件包含了恶意代码。总结一下就是 得任意写/data/app/apk包,替换成加了恶意代码的apk,这个加入恶意代码的APK包不能直接安装因为没系统签名,任意写能够绕过签名校验而直接安装到手机而且保留system用户权限,然后再写odex造成crash不然执行会执行以前的odex,crash之后odex是空白的执行代码就从APK包中dex执行然后就任意代码执行了,要是直接写odex就会直接crash,没办法写进去,因为是在执行代码过程中写odex执行会中断。
0x05 Android7.1.1 漏洞复现
对于Android7.1.1而言,SELinux为严格模式,selinux策略不允许的操作都会被拒绝,由于APP为system用户权限,可以通过
ps -Z
查看其SElinux上下文,发现其值为u:r:system_app:s0
其类型为system_app
但是当该APP写
/data/app/top.geekcon.avss.selinux.v-1
目录下文件内容时出现错误,logcat输出表明受到了SELinux策略的限制,但是可以读出/data/app/com.example.seattacker-1
目录下的文件。通过查阅Android源码中
apk_data_file
相关的策略可以发现允许任何APP读取和execute该类型的文件,但是没有允许写再查阅有关system_app
的SELinux
策略可以发现其可以读写/data/data目录,但是同样没有允许写apk_data_file
类型文件相关的策略。所以直接写/data/app/top.geekcon.avss.selinux.v-1
目录下APK文件的方案不可行,同样写odex
文件也不被SELinux策略允许。暂时搁置,
Android7
版本SELinux
策略中不允许通过上面所述的利用方式进行利用,可能需要审selinux
策略另辟蹊径,问了出题人说是没预期解,开放型。0x06 Android11漏洞复现
Android11中引入一个不当的SELinux策略(Android10中还不存在该问题),导致出现漏洞。在对
system_app
类型的APP进行策略设定时允许其写apk_data_file
类型的文件,因而可以引发一系列安全问题。CVE-2021-0691
即为因此问题而出现的漏洞,被评为中等级别,虽然其能达到写/data/app
目录下文件的目的,但是本身需要一个system_app
类型APP进行任意写,可以对 /data/app
目录下 apk 和 lib 库进行修改替换,这样达到突破沙箱限制,造成任意代码执行。其修复就是删除了这两条关于允许写的策略,因此该系统环境下的漏洞利用可能与此有关,但是由于缺乏设备暂时搁置复现计划。
从
Geekcon
官方给的rom
包中提取boot.img
,从中提取sepolicy
文件,使用sesearch
(Ubuntu可通过apt安装)反编译selinux
策略验证所给rom包中存在上述问题system_app
确实具有对apk_data_file
的写权限。因此该漏洞确认可以在所提供系统进行利用。0x07 参考
- 作者:LLeaves
- 链接:https://lleavesg.top//article/AVSS-SELinux
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章