Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
OrganizerTransaction — PoC for CVE-2021-39749, allowing starting arbitrary Activity on Android 12L Beta | Kitploit
Tools/GitHubGitHub/michalbednarski/organizertransaction
Android SecurityVulnerability AnalysisExploitationMobile App PentestingMobile Security
GitHubmichalbednarski/organizertransaction

OrganizerTransaction

PoC for CVE-2021-39749, allowing starting arbitrary Activity on Android 12L Beta

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
3711724 years agoReviewed by Kitploit

This is PoC for CVE-2021-39749, which allows starting activities of other apps on Android 12L Beta regardless of their permission and exported settings

In Android 12L TaskFragmentOrganizer access (intentionally) no longer requires MANAGE_ACTIVITY_TASKS permission

Using app provided here requires disabling Hidden API Checks, you can do so through adb shell settings put global hidden_api_policy 1. These are not security boundary and there are known app-based bypasses

Here are commits fixing this bug (and few related mentioned in original report):

  1. startActivityInTaskFragment no longer rely on Binder.getCallingUid()
  2. ResolverActivity now has relinquishTaskIdentity enabled
  3. (Not needed for starting other activities, but allows repositioning them around screen and making them transparent and tap-jackable) SurfaceControl of TaskFragment is no longer provided
  4. (Not shown in code here, issue only mentioned in original report) Deciding whenever to send ActivityRecord#appToken to TaskFragmentOrganizer is now based on uid instead of pid

You can checkout android-12.1.0_r4, revert first 3 commits (or first 2, application will still be able shutdown device (by starting ShutdownActivity), but "Zoom and set alpha" checkbox won't work)

(First commit from that list will have merge conflicts in tests if you try to revert it, but you can ignore these)

Binder.getCallingUid() that always returns system uid

Binder.getCallingUid() method returns uid of process that sent currently processed Binder transaction. That uid is stored in thread-local variable. Code handling transaction can call Binder.clearCallingIdentity() to set that variable to uid of own process to indicate to methods called later during transaction handling that permission checks should be done against itself (code handling transaction) and not caller of Binder transaction

Sometimes there are Binder.getCallingUid() that are always called after Binder.clearCallingIdentity(), therefore always return uid of own process. Sometimes this happens intentionally, for example in ActivityTaskManagerService#startDreamActivity (although thats rather convoluted way of doing Process.myUid() or Os.getuid())

I've written for myself a (Soot-based) static analysis tool that reports such Binder.getCallingUid() calls (and other permission checks) that can only happen after Binder.clearCallingIdentity(). (I have custom logic handling Jimple/Shimple IR provided by Soot, although there might be better way to do so with Soot, but thats what I have now)

In Android 12L Beta that tool found one in ActivityStartController#startActivityInTaskFragment (Note: source code was not available then as Beta releases are not open source, but Shimple is generally readable so I've been using Soot also as Java decompiler)

How to call startActivityInTaskFragment

As part of static analysis report I've got call hierarchy from onTransact() implementation (where Binder call starts) to startActivityInTaskFragment:

  1. onTransact in aidl-generated code of IWindowOrganizerController
  2. WindowOrganizerController#applyTransaction (without CallerInfo argument)
  3. WindowOrganizerController#applyTransaction (with CallerInfo argument)
  4. WindowOrganizerController#applyHierarchyOp
  5. ActivityStartController#startActivityInTaskFragment

I've found that Binder calls to applyTransaction are present in TaskFragmentOrganizer class and I've decided to use it as more convenient wrapper than doing all Binder calls directly (neither is public API so I had to use reflection anyway)

First of all, method "2." calls enforceTaskPermission, which on Android 12.0 checked signature-only MANAGE_ACTIVITY_TASKS permission which we couldn't get, however on Android 12L rules were relaxed so certain transactions can be made without permissions. It turned out that none of operations needed for doing startActivityInTaskFragment required a permission (if transaction had TaskFragmentOrganizer associated)

So we want to perform HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT. In order to do so we must have our TaskFragment registered in mLaunchTaskFragments otherwise "Not allowed to operate with invalid fragment token" exception will be reported

We can register such TaskFragment through HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, which calls createTaskFragment()

Download Tool