|
| 1 | +# Android Enterprise Work Profile Required-App Replacement |
| 2 | + |
| 3 | +{{#include ../../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## Attack surface |
| 6 | + |
| 7 | +Android Enterprise Work Profiles are implemented as **secondary Android users** (BYOD example: user `0` = personal, user `1` = work). Each user has independent `/data/user/<id>` trees, system apps, Play Services instances and policy objects maintained by the MDM. When an MDM such as **Microsoft Intune** marks an app as *required* for the Work Profile, the **Work-Profile Play Store (Finsky)** periodically confirms the package is present and auto-installs it if missing. |
| 8 | + |
| 9 | +Even after the **CVE-2023-21257** patch that blocks ADB sideloads when `DISALLOW_INSTALL_APPS` or `DISALLOW_DEBUGGING_FEATURES` are set, the following chain lets an attacker **replace any Intune-required Work Profile app** with arbitrary code: |
| 10 | + |
| 11 | +1. Abuse Android Studio's **"Install for all users"** path to stage a malicious APK that looks like an update of the managed package. |
| 12 | +2. Let the MDM notice the required app is missing. Intune triggers the Work-Profile Finsky instance to reinstall it. |
| 13 | +3. Finsky compares the staged APK version with the Play Store version and silently installs the **highest `versionCode`**, bypassing the original restriction. |
| 14 | + |
| 15 | +## Recon and prerequisite checks |
| 16 | + |
| 17 | +* Confirm multi-user layout and user IDs: |
| 18 | + |
| 19 | +```bash |
| 20 | +adb shell pm list users |
| 21 | +# Expect user 0 = Owner, user 1 = Work profile (or higher if multiple profiles exist) |
| 22 | +``` |
| 23 | + |
| 24 | +* Direct installs into the work user fail under policy (expected error): |
| 25 | + |
| 26 | +```bash |
| 27 | +adb install --user 1 legit.apk |
| 28 | +# java.lang.SecurityException: Shell does not have permission to access user 1 |
| 29 | +``` |
| 30 | + |
| 31 | +* You must have **temporary physical access to an unlocked BYOD** to enable Developer Options + USB debugging. |
| 32 | +* Identify the **package name** of a Work-Profile app marked as *required* (e.g. `com.workday.workdroidapp`). |
| 33 | + |
| 34 | +## Weaponising the Android Studio multi-user installer |
| 35 | + |
| 36 | +Android Studio's Run/Debug configuration can still push builds with the **`INSTALL_ALL_USERS`** flag. Before running, enable *Deploy as instant app* → *Install for all users*. |
| 37 | + |
| 38 | +Build the malicious payload with the **same package name** as the managed app and a **much larger `versionCode`** so PackageManager/Finsky treats it as a newer release: |
| 39 | + |
| 40 | +```gradle |
| 41 | +android { |
| 42 | + namespace = "com.workday.workdroidapp" |
| 43 | + defaultConfig { |
| 44 | + applicationId = "com.workday.workdroidapp" |
| 45 | + versionCode = 900000004 |
| 46 | + versionName = "9000000004.0" |
| 47 | + } |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +When Android Studio deploys: |
| 52 | + |
| 53 | +1. **Personal user (0)** installs the malicious package normally. |
| 54 | +2. **Work Profile user (1)** receives the APK in a temporary staging area and tries to treat it as an update. |
| 55 | +3. CVE-2023-21257's logic sees the user is restricted → **install is denied**, but the legitimate managed app is marked uninstalled and the staged APK remains cached. |
| 56 | + |
| 57 | +## Intune/Finsky auto-install bypass |
| 58 | + |
| 59 | +Within ~1–10 minutes (policy refresh interval): |
| 60 | + |
| 61 | +1. Intune/Company Portal detects the *required* package is missing from the Work Profile. |
| 62 | +2. The Work-Profile **Finsky** instance is asked to reinstall it. |
| 63 | +3. During version resolution Finsky compares: |
| 64 | + * Play Store metadata for `com.workday.workdroidapp`. |
| 65 | + * The locally staged APK from the previous install attempt. |
| 66 | +4. Because the local build has the **highest `versionCode`**, Finsky trusts it as the most recent release and installs it into the restricted Work Profile **without re-applying `DISALLOW_INSTALL_APPS` / `DISALLOW_DEBUGGING_FEATURES` checks**. |
| 67 | + |
| 68 | +The malicious binary now resides inside the Work Profile under the genuine package name and is considered compliant by the MDM. |
| 69 | + |
| 70 | +## Post-exploitation opportunities |
| 71 | + |
| 72 | +* **Work-profile data access** – other enterprise apps keep trusting Intents/content providers bound to the replaced package, enabling internal data theft and covert exfiltration from the Work Profile to attacker infrastructure. |
| 73 | +* **Per-app VPN hijack** – if the replaced package is mapped to an Intune per-app VPN (MS Tunnels + Defender), the malicious build automatically inherits the VPN profile, giving direct access to internal hosts from an attacker-controlled process. |
| 74 | +* **Persistence** – because the MDM now believes the required app is installed, it will **reinstall the malicious build** whenever the user or defender removes it, providing long-term foothold on BYOD Work Profiles. |
| 75 | + |
| 76 | +## References |
| 77 | + |
| 78 | +- [Bypassing CVE-2023-21257 via Intune Required-App Auto-Install](https://jgnr.ch/sites/android_enterprise.html) |
| 79 | + |
| 80 | +{{#include ../../banners/hacktricks-training.md}} |
0 commit comments