Objectif
Exploiter une vulnérabilité XSS dans un composant WebView pour obtenir un RCE dans une application Android.
Outil
- Jadx – https://github.com/skylot/jadx
- ADB – https://developer.android.com/tools/adb?hl=fr
- MobSF – https://github.com/MobSF/Mobile-Security-Framework-MobSF
Installation
Pour commencer, nous allons installer l’application sur un périphérique virtuel (bien que cela fonctionne également avec les périphériques physiques), le tout grâce à ADB :
$ adb install com.mobilehackinglab.postboard.apk
Performing Streamed Install
Success
L’application est installée avec succès et se lance parfaitement :

Commençons l’analyse !
Fichier AndroidManifest.xml
Voici le fichier AndroidManifest.xml de l’application Post Board :

Il est possible d’identifier une activity exportée, c’est-à-dire accessible par d’autres applications du système. Il s’agit de l’activity com.mobilehackinglab.postboard.MainActivity qui sera lancée par défaut quand l’utilisateur clique sur l’icône de l’application.
Il est également possible de déclencher cette activity via des URI de type postboard://postmessage, aussi appelées deep links.
Pour rappel, les deep links (Android >= 6.0) sont des URI conçues pour s’ouvrir directement dans une application mobile, guidant les utilisateurs vers un contenu ou une action spécifique sans passer par l’écran d’accueil de l’application.
Compréhension de la MainActivity
Plusieurs éléments semblent très intéressants au sein du fichier MainActivity. En effet, dans un premier temps, il est possible d’identifier l’utilisation des deep links avec une vérification stricte de l’action (areEqual(« android.intent.action.VIEW », action)), du schéma (areEqual(data.getScheme(), « postboard »)) et de l’hôte (areEqual(data.getHost(), « postmessage »)) (ligne 60).
La valeur passée au sein du deep links est décodé du base64 (ligne 66) avant d’être envoyé à la WebView (ligne 74 ou 82) :

D’après ce que l’on voit, il est donc possible d’envoyer des éléments directement via ADB avec la commande suivante : adb shell am start -n com.mobilehackinglab.postboard/.MainActivity -a android.intent.action.VIEW -d postboard://postmessage/b3JodXM= :

Autre fait intéressant, au sein de la fonction setupWebView(), deux fonctions attirent notre attention :
- setJavaScriptEnabled permettant d’activer le JavaScript au sein de la WebView
- addJavascriptInterface permettant de créer un lien entre le code JavaScript dans la WebView et le code Java de l’application Android

Avec ces éléments en tête, tentons d’exploiter une simple XSS au sein de notre WebView grâce à la payload suivante :
$ echo ‘<script>alert(« ORHUS »)</script>’ | base64
PHNjcmlwdD5hbGVydCgiT1JIVVMiKTwvc2NyaXB0Pgo=

La simple XSS fonctionne parfaitement ! Néanmoins, notre objectif est d’aller jusqu’à l’exécution de code à distance (RCE).
Pour cela, nous allons nous servir de l’attribut addJavascriptInterface de la WebView en faisant appel à certaines méthodes natives de l’application (les méthodes annotées @JavascriptInterface).
En effet, en auditant le code (manuellement ou grâce à MobSF), il est possible d’identifier 3 fonctions annotées @JavascriptInterface : clearCache(), postMarkdownMessage() et postCowsayMessage(), toutes présentes au sein du fichier com/mobilehackinglab/postboard/WebAppInterface.java :

La fonction postCowsayMessage() fait appel à la fonction runCowsay au sein du fichier defpackage.CowsayUtil pouvant permettre une injection de commande (RCE) (ligne 64) :

Il est ainsi possible de faire appel à cette dernière en utilisant le nom de l’interface WebAppInterface déclarée de la manière suivante : WebAppInterface.postCowsayMessage(« COMMANDE »).
Il est à présent possible d’encoder notre payload en base64 avant de la passer en argument de notre deep links :


