type
status
date
slug
summary
tags
category
icon
password
0x00 引言
在Android系统中,
installer package name
(安装程序包名)是指安装某个应用程序的包名。具体来说,当你通过命令行工具pm install
安装一个应用时,可以使用-i
标志来指定安装该应用的程序包名。在Android 12和13中,存在一个安全漏洞,即通过
pm install
命令的-i
标志设置的安装程序包名没有经过适当的校验和清理。这意味着攻击者可以利用特殊字符(如换行符和空格)来注入恶意数据,从而影响系统文件/data/system/packages.list
的内容。之后可以通过伪造的条目欺骗run-as
从而获得受害应用的权限,可以操作内部目录等。
0x01 漏洞说明
拥有 Android 设备 ADB 访问权限的攻击者可以欺骗
run-as
工具,使其认为任何应用都可以调试。通过这样做,他们可以像系统中的大多数应用一样读取和写入私有数据并调用系统 API(包括许多特权应用,但不是以system
用户身份运行的应用)该漏洞于
GoogleAndroid 2024-03-01
安全公告中批露修复,影响范围12, 12L, 13, 14
而
validateName
校验要求包名中必须只含字母数字以及_
符号0x02 漏洞利用
1. 漏洞利用说明
run-as
是Android系统中的一个命令行工具,它允许用户以指定应用程序的身份运行代码或命令。具体来说,run-as
可以让你在ADB shell中以某个已安装应用的权限和上下文执行命令,从而模拟该应用的行为。但它会从packages.list
查询应用程序的可调试性(以及其 UID、SELinux 上下文和数据目录)。通过pm install -i
向/data/system/packages.list
注入虚假条目,攻击者可以绕过可调试性检查并成为系统上的几乎任何应用程序。观察
/data/system/packages.list
内容,以其中一条为例com.android.phone.auto_generated_rro_product__ 10047 0 /data/user/0/com.android.phone.auto_generated_rro_product__ default:targetSdkVersion=31 none 0 1 1 @system
- 包名 (
com.android.phone.auto_generated_rro_product__
): 这是应用程序的唯一标识符。
- 用户ID (
10047
): 每个应用程序安装时都会被分配一个唯一的用户ID(UID),用于操作系统的权限管理和资源分配。
- app是否处于调试模式,由
AndroidManifext.xml
里android:debuggable
指定,0表示不可调试,1 表示可调试
- 数据目录 (
/data/user/0/com.android.phone.auto_generated_rro_product__
): 指向应用程序的数据存储目录。
- SElinux信息:
default
- targetSdkVersion (
targetSdkVersion=31
): 指明应用针对的Android SDK版本。这对于应用的兼容性处理非常重要。
- user group(GID)信息 :
nono
表示没有user group
- 安装分类(
@system
): 表示应用安装的分类或来源。@system
表示这是一个系统应用。
其他字段并不重要,更多内容见
system/core/libpackagelistparser/packagelistparser.cpp
run-as
命令不能通过stat()
访问privapp_data_file
,因此在检查数据目录时将失败。但check_directory()
函数中存在一个特殊的case,用于允许/data/user/0
路径作为符号链接。这导致了UID
验证被跳过(最新代码中删去了这一特殊case)。攻击者可以将fake app的数据路径设置为
/data/user/0
,满足run-as
的内部安全检查。并且在runas_app
环境中,攻击者可以读写privapp_data_file
也就是App私有数据目录。简单的利用脚本如下,该脚本将注入一个新的条目
victim $UID 1 /data/user/0 default:targetSdkVersion=28 none 0 0 1 @null
,该包的UID将是受害App的UID,并且数据目录是/data/user/0
其中两者中间的1表示可调试非
system
的privapps
容易受到攻击,但对于这些应用程序,攻击者不会获得任何 SELinux 权限,除了 run-as 授予普通非特权应用程序的权限。2. 访问WhatsApp数据示例
使用
Android12
模拟器作为实验设备查看
/data/system/packages.list
发现注入成功能够成功访问数据,除此之外,由于可以访问私有目录数据,也可以覆写数据目录中可能存在的动态链接库或者ODEX以及VDEX文件(例如
/data/user_de/0/com.google.android.gms/app_chimera/m/*/oat/
),从而进行持久化。3.限制
因此,攻击者虽然可以"几乎"成为任何应用,但仍有一些限制,无法完全获取系统最高权限。
不过
run-as
有一些额外的防御机制:- 它不会假冒非应用程序的UID,包括高权限的
system
用户UID,即使packages.list
中存在相应条目。
- 它只考虑
fromRunAs=true
的seapp_contexts
,而不会假冒与真实应用相同的SELinux
上下文。对于非特权应用来说,runas_app
的权限已经高于untrusted_app
,所以这没有影响。但它确实阻止了攻击者以通常可以执行的priv_app
或platform_app
身份执行受限操作。
A local attacker with ADB shell access to an Android 12 or 13 device with Developer Mode enabled can exploit the vulnerability to run code in the context of any non-system
-UID app. From there, the attacker can do anything the app can, like access its private data files or read the credentials it's stored in AccountManager. This violates the security guarantees of the Application Sandbox, which is supposed to safeguard an app's data from even the owner of the device.Non-system
privapps are vulnerable, but for those the attacker does not gain any SELinux permissions beyond what run-as grants for a normal unprivileged app. That means no access to Binder APIs marked only assystem_api_service
, for example.
参考
- 作者:LLeaves
- 链接:https://lleavesg.top//article/CVE-2024-0044
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章