Objectif
Exploiter une vulnérabilité inhérente à un service antivirus Android pour permettre l’exécution de code à distance (RCE).
Outil
Source
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.cyclicscanner.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 Cyclic Scanner :

Il est possible d’identifier un Service (com.mobilehackinglab.cyclicscanner.scanner.ScanService) au sein de ce dernier. Celui-ci n’étant pas exporté, il est nécessaire d’aller dans les entrailles du code source pour comprendre comment il est utilisé.
Commençons par la MainActivity
Au sein du fichier MainActivity, la méthode onCreate() est exécutée une seule fois au début de cycle de vie de l’activity. Cette dernière fait appel aux fonctions suivantes :
- setupPermissionLauncher();
- handlePermissions();
La fonction handlePermissions() fait appel à la fonction setupSwitch() (uniquement si l’application dispose de l’ensemble des droits sur le stockage externe (vérification ligne 96))

La méthode setupSwitch() installe un listener sur le bouton serviceSwitch afin de réagir à chaque changement d’état. Lorsque cet état change, la méthode setupSwitch$lambda$3() est exécutée : si le switch est activé, un message informe l’utilisateur que le service de scan démarre et celui-ci est lancé en mode foreground, s’il est désactivé, un message indique qu’il ne peut pas être arrêté et le switch est immédiatement réactivé.
A votre Service ma bonne dame
Rappel technique : Un service ne possède pas d’interface graphique, mais permet de dérouler un algorithme sur un temps indéfini. Il peut être soit exécuté lors du lancement du téléphone (arrivée d’un appel, d’un SMS, etc.), soit au cours d’une action particulière dans votre application via un « Broadcast Receiver ».
À la suite du déclenchement du service (startForegroundService), la méthode onCreate() du fichier com.mobilehackinglab.cyclicscanner.scanner.ScanService est appelée pour préparer l’environnement d’exécution.
Lorsqu’Android exécute ensuite onStartCommand(), le service affiche une notification permanente “Scanner is running…” et envoie un premier message au ServiceHandler (ligne 79).

La méthode handleMessage() du ServiceHandler réalise alors le cœur du traitement :
- Affichage d’un message de log indiquant le début du scan (ligne 48),
- Parcours récursif de tout le stockage externe (ligne 51),
- Pour chaque fichier lisible, appel à la fonction scanFile(file) pour déterminer s’il est « SAFE » ou « INFECTED » (ligne 56),
- Affichage d’un message de fin de scan (ligne 60).
Au sein de com.mobilehackinglab.cyclicscanner.scanner.ScanEngine, il est possible d’identifier la fonction scanFile(), appelée pour chaque fichier :

Rappel technique : sous Android, toybox fournit un ensemble unifié d’outils en ligne de commande (cp, ls, ps, etc.) utilisés par le système et en shell, similaire à BusyBox mais en plus minimal et intégré par Google.
En analysant la fonction scanFile(), il semblerait que cette dernière, et notamment la ligne 43 soit vulnérable à une injection de commande. En effet, le chemin du fichier (file.getAbsolutePath()) est directement concaténé à la commande toybox sha1sum sans aucune validation ni échappement, ce qui pourrait permettre à un attaquant contrôlant le nom d’un fichier d’insérer des caractères spéciaux ou des opérateurs shell afin d’exécuter des commandes arbitraires sur le système.
On attaque à l’aveugle ?
Maintenant que nous avons identifié la vulnérabilité, il est possible de l’exploiter à l’aveugle. Néanmoins, en lignes 55 et 57 du fichier com.mobilehackinglab.cyclicscanner.scanner.ScanService, il est possible de voir que l’application réalise un log des actions réalisées (fichiers scannés).
Nous allons donc créer notre fichier malveillant réalisant une injection de code grâce aux commandes suivantes :
adb shell
cd /storage/emulated/0
cd Documents
echo orhus > "test ; touch ORHUS_RCE"
Puis lancer adb logcat afin de s’assurer que notre injection est fonctionnelle :
