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
其修复了PackageInstallerService.java 中的代码,添加isValidPackageName 方法对包名进行校验
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
  1. 包名 (com.android.phone.auto_generated_rro_product__): 这是应用程序的唯一标识符。
  1. 用户ID (10047): 每个应用程序安装时都会被分配一个唯一的用户ID(UID),用于操作系统的权限管理和资源分配。
  1. app是否处于调试模式,由AndroidManifext.xmlandroid:debuggable指定,0表示不可调试,1 表示可调试
  1. 数据目录 (/data/user/0/com.android.phone.auto_generated_rro_product__): 指向应用程序的数据存储目录。
  1. SElinux信息: default
  1. targetSdkVersion (targetSdkVersion=31): 指明应用针对的Android SDK版本。这对于应用的兼容性处理非常重要。
  1. user group(GID)信息nono表示没有user group
  1. 安装分类(@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表示可调试
systemprivapps容易受到攻击,但对于这些应用程序,攻击者不会获得任何 SELinux 权限,除了 run-as 授予普通非特权应用程序的权限。

2. 访问WhatsApp数据示例

使用Android12模拟器作为实验设备
notion image
查看/data/system/packages.list 发现注入成功
notion image
 
notion image
能够成功访问数据,除此之外,由于可以访问私有目录数据,也可以覆写数据目录中可能存在的动态链接库或者ODEX以及VDEX文件(例如/data/user_de/0/com.google.android.gms/app_chimera/m/*/oat/),从而进行持久化。
 

3.限制

因此,攻击者虽然可以"几乎"成为任何应用,但仍有一些限制,无法完全获取系统最高权限。
不过run-as有一些额外的防御机制:
  1. 它不会假冒非应用程序的UID,包括高权限的system用户UID,即使packages.list中存在相应条目。
  1. 它只考虑fromRunAs=trueseapp_contexts,而不会假冒与真实应用相同的SELinux上下文。对于非特权应用来说,runas_app的权限已经高于untrusted_app,所以这没有影响。但它确实阻止了攻击者以通常可以执行的priv_appplatform_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 as system_api_service, for example.
 

参考

  1. 通过换行注入绕过 Android 上的“run-as”可调试性检查
  1. https://blog.canyie.top/2024/04/18/android-security-bulletin-index/
  1. Extracting WhatsApp Database (or any app data) from Android 12/13 using CVE-2024-0044
 
MRCTF2022 Stuuuuub WPbpf_probe_write_user补丁添加对只读内存的修改
  • Twikoo