Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
OrganizerTransaction — CVE-2021-39749 的 PoC,允许在 Android 12L Beta 上启动任意 Activity | Kitploit
工具/GitHubGitHub/michalbednarski/organizertransaction
Android安全漏洞分析漏洞利用移动应用渗透测试移动安全
GitHubmichalbednarski/organizertransaction

OrganizerTransaction

CVE-2021-39749 的 PoC,允许在 Android 12L Beta 上启动任意 Activity

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
3711724年前Kitploit 审核通过

这是CVE-2021-39749的PoC,它允许在Android 12L Beta上无视其他应用的permission和exported设置启动其Activity

在Android 12L中,TaskFragmentOrganizer的访问(有意地)不再需要MANAGE_ACTIVITY_TASKS权限

使用此处提供的应用需要禁用Hidden API Checks,你可以通过adb shell settings put global hidden_api_policy 1来实现。这些不是安全边界,并且存在已知的基于应用的绕过方法

以下是修复此漏洞(以及原始报告中提到的几个相关问题)的提交:

  1. startActivityInTaskFragment不再依赖Binder.getCallingUid()
  2. ResolverActivity现在启用了relinquishTaskIdentity
  3. (启动其他Activity不需要,但允许在屏幕上重新定位它们并使其透明且可被点击劫持)TaskFragment的SurfaceControl不再提供
  4. (此处代码未展示,仅在原始报告中提及)决定是否将ActivityRecord#appToken发送给TaskFragmentOrganizer现在基于uid而非pid

你可以检出android-12.1.0_r4,还原前3个提交(或前2个,应用仍然能够关闭设备(通过启动ShutdownActivity),但“缩放并设置透明度”复选框将无法工作)

(如果你尝试还原该列表中的第一个提交,测试中会出现合并冲突,但你可以忽略这些)

始终返回系统uid的Binder.getCallingUid()

Binder.getCallingUid()方法返回发送当前正在处理的Binder事务的进程的uid。该uid存储在线程局部变量中。处理事务的代码可以调用Binder.clearCallingIdentity()将该变量设置为自身进程的uid,以指示在事务处理期间稍后调用的方法应针对自身(处理事务的代码)而非Binder事务的调用者进行权限检查

有时存在总是在Binder.clearCallingIdentity()之后调用的Binder.getCallingUid(),因此总是返回自身进程的uid。有时这是有意为之,例如在ActivityTaskManagerService#startDreamActivity中(尽管这是执行Process.myUid()或Os.getuid()的一种相当迂回的方式)

我为自己编写了一个(基于Soot的)静态分析工具,用于报告此类只能在Binder.clearCallingIdentity()之后发生的Binder.getCallingUid()调用(以及其他权限检查)。(我有处理Soot提供的Jimple/Shimple IR的自定义逻辑,尽管使用Soot可能有更好的方法,但这是我目前拥有的)

在Android 12L Beta中,该工具在ActivityStartController#startActivityInTaskFragment中发现了一个(注意:当时源代码不可用,因为Beta版本不是开源的,但Shimple通常可读,因此我也将Soot用作Java反编译器)

如何调用startActivityInTaskFragment

作为静态分析报告的一部分,我获得了从onTransact()实现(Binder调用开始处)到startActivityInTaskFragment的调用层次结构:

  1. IWindowOrganizerController的aidl生成代码中的onTransact
  2. WindowOrganizerController#applyTransaction(不带CallerInfo参数)
  3. WindowOrganizerController#applyTransaction(带CallerInfo参数)
  4. WindowOrganizerController#applyHierarchyOp
  5. ActivityStartController#startActivityInTaskFragment

我发现TaskFragmentOrganizer类中存在对applyTransaction的Binder调用,我决定将其用作比直接执行所有Binder调用更方便的包装器(两者都不是公共API,因此无论如何我都必须使用反射)

首先,方法“2.”调用enforceTaskPermission,在Android 12.0上检查仅signature级别的MANAGE_ACTIVITY_TASKS权限,我们无法获得该权限,然而在Android 12L上规则被放宽,某些事务可以在没有权限的情况下进行。事实证明,执行startActivityInTaskFragment所需的操作都不需要权限(如果事务关联了TaskFragmentOrganizer)

因此我们想要执行HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT。为此,我们必须将我们的TaskFragment注册在mLaunchTaskFragments中,否则将报告"Not allowed to operate with invalid fragment token"异常

我们可以通过HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT注册这样的TaskFragment,它会调用createTaskFragment()

(在PoC代码中,这些事务在SecondActivity中发送:HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT由initOrganizerAndFragment()发送,HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT由startActivityInOrganizer发送)

因此这允许我们调用startActivityInTaskFragment,并且此处启动的Activity的Intent被视为来自系统uid,但事实证明这本身并不能让我们做任何事情:系统启动的Activity不能进行URI授权,如果我们尝试启动另一个应用的Activity,我们将被canEmbedActivity检查阻止

绕过canEmbedActivity

让我们再次查看canEmbedActivity:如果taskFragment.getTask().effectiveUid是系统uid或与启动的应用的uid匹配,则允许嵌入。我们需要处于effectiveUid为系统的任务中

再回到createTaskFragment():仅当rootActivity.getUid() != ownerActivity.getUid()时才允许创建TaskFragment。这意味着我们的Activity需要位于其所在Task的返回栈底部

我们需要启动一个新的Task(通过Intent.FLAG_ACTIVITY_NEW_TASK),该Task将包含属于系统uid的Activity(因此Task#effectiveUid将被设置为AID_SYSTEM),然后该Activity将启动我们的Activity(在同一Task内)并finish()自身(因此我们的Activity将成为该任务的根Activity,允许我们使用createTaskFragment())

下载工具