此问题已在 2026 年 6 月 Android 安全公告 中针对 Android 14+ 修复。点击此处查看补丁
待完成
等我有空时会补全文章
但在此之前我得先应付学校作业和考试
我决定在考试结束前完成这部分
祝我好运 😇
IApplicationThread 是系统提供给应用的私有回调,系统可以用它向应用发送命令(加载指定应用、通知组件生命周期的变化等)
它设计为仅系统可用,因此没有权限检查,安全性仅通过恶意进程无法获取该对象来保证。这听起来有点像 Web 中的“cookie”或“token”。这种访问控制模型称为基于能力的安全
如果其他人设法从其他进程获取了 IApplicationThread,他们可以发送任意命令,受害应用会像处理系统生成的命令一样处理这些伪造的命令。在 CVE-2022-20452 的先前漏洞利用 中,该技巧被用于执行任意代码
虽然 IApplicationThread 仅应传递给系统进程,但它可能意外地传出 system_server
没有人会实现一个向任何人公开的 getIApplicationThreadForApp(String packageName) API,这是明显的安全违规
但如果 IApplicationThread 被包装在另一个对象中,并且外部包装对象被发送,则可能性更大
RemoteTransition 就是这样一个包装器,它包含一个 IApplicationThread,用于提升运行动画的应用的优先级
该 API 的一个使用者是 Launcher3,即 AOSP 和 Pixel 设备上的默认主屏幕应用,它使用 RemoteTransition 创建 ActivityOptions,然后将其传递给 startActivity()
虽然 Launcher3 本身不会将该对象暴露给不受信任的因素,但 system_server 有时会
CVE-2022-20419 发生在 system_server 将调用者传递的 ActivityOptions 转发给启动的应用时,但忘记剥离 RemoteTransition,从而允许启动的应用接收它并在 launcher 进程内加载任意代码
在共享元素过渡动画期间,需要完成大量工作,WMCore 与 WMShell 之间需要进行通信,其中 WM 代表 Window Manager
您可以阅读本文来了解 WMShell
由于 WMCore 和 WMShell 运行在不同进程中(WMCore 在 system_server 中运行,WMShell 在 SystemUI 中运行),它们利用 Binder 机制进行通信
WMCore 暴露了一个 Binder registerTransitionPlayer API,WMShell 使用它来注册自己的 binder
当动画启动时,WMCore 调用 requestStartTransition,并将 TransitionRequestInfo 传递给远程端,其中包含初始的 RemoteTransition
因此,如果我们能替换 transition player,就能获取 Launcher 的 IApplicationThread,并在特权进程中实现任意代码执行
然而,registerTransitionPlayer 受 MANAGE_ACTIVITY_TASKS 权限保护,第三方应用无法获取该权限
但 adb shell 也可以运行不受信任的用户代码,并且 shell 被授予了 MANAGE_ACTIVITY_TASKS 权限,所以幸运的是我们可以从 adb shell 发起攻击
一个有趣的问题是攻击者能通过此漏洞做什么
由于 Launcher 被授予的绝大多数权限 adb shell 也持有,已经可以在 shell 身份下执行代码的攻击者不需要利用此漏洞来危害设备
这更像是一个用于学习 IApplicationThread 的教育性示例项目,而非恶意应用可用的漏洞利用
然而,有些人可能仍对此感兴趣
例如,这可用于提取 Launcher 的私有文件,这在无需 root 设备的情况下对恶意 Launcher 应用进行取证分析时非常有用。此前这是通过利用 CVE-2024-31317 实现的,而我的发现揭示了前一个漏洞修复后的另一种方法
这也允许用户无需 root 设备即可使用 Fabricated Runtime Resources Overlay (FRRO),因此无 root 自定义主题在 CVE-2021-39630 被修补后重新回归。我的漏洞利用通过将 android:integer/config_multiuserMaximumUsers 设置为 100 展示了这一点
此外,Launcher 默认也托管 Recents 屏幕组件,因此被允许执行一些特权操作。我认为 Launcher 被允许在现有任务中启动任意活动,无论启动活动是否设置了 exported/permission, 这可能是一些设备管理工具应用所需要的,尽管我尚未亲自测试
构建项目,安装生成的 apk 文件(如果在 Android Studio 中使用“Run”按钮,请打开“Always install with package manager”)
在 PC 上运行以下命令
adb shell app_process '-Djava.class.path=$(pm path top.canyie.transitionplayer | cut -c9-) /system/bin top.canyie.transitionplayer.Main'
然后从 launcher 中点击任意应用的图标启动它
Launcher 应用应发送一个通知,如果您运行的是 Android 14+,一个 Fabricated Overlay 将被注入系统,因此 adb shell cmd overlay lookup android android:integer/config_multiuserMaximumUsers 应返回 100