Dans le précédent cas d’école Frida, nous avons abordé plusieurs notions telles que le Certificate Pinning, la détection de périphérique rooté, la vérification du User-Agent et le contournement de tout cela grâce à Frida-inject et Burp.
Cette fois-ci, l’objectif de cet article est d’utiliser Frida de plusieurs manières afin de contourner une application bien connue sur Internet, j’ai nommé AppLock :
Présentation d’AppLock
Comme décrit sur la page de l’application, AppLock permet de protéger votre vie privée par le biais d’un mot de passe en verrouillant des applications telles que Facebook, WhatsApp, Gallery, Messenger, Snapchat, Instagram, SMS, Contacts, etc.
Lors du premier lancement d’AppLock, l’application va demander un mot de passe permettant de verrouiller l’application :
Dès lors que l’application est fermée, il sera nécessaire de spécifier à nouveau ce mot de passer pour y accéder.
Analyse de l’application
Afin d’en savoir un peu plus sur l’application, il est possible d’utiliser APKFram afin d’identifier l’utilisation d’un éventuel Framework. En effet, comme abordé dans l’article « Audit d’application Android, Java ne répond plus », l’analyse statique peut être complètement différente en fonction du Framework de développement utilisé pour créer l’application.
Dans notre cas de figure, APKFram ne semble reconnaître aucun Framework spécifique :
Il est ainsi possible de décompiler l’application grâce à Jadx afin de voir si le code source peut nous apprendre quelque chose. Néanmoins, conformément aux meilleures pratiques de sécurité, le code de l’application est obfusquée, rendant plus difficile (mais pas impossible) l’audit de code :
Afin de ne pas partir dans un audit de code long (et pénible), nous allons changer notre angle d’attaque afin de voir ce qu’il est possible de faire de manière dynamique.
Analysons le type d’authentification
Avant même de lancer l’application, Burp est lancé, prêt à l’interception d’une éventuelle requête d’authentification envoyée vers une API d’AppLock, néanmoins, après plusieurs tentatives, Burp reste vierge :
Une rapide analyse via TCPDump nous confirme qu’aucune connexion ne transite et qu’il ne s’agit donc pas d’un mécanisme de Pinning. Une authentification possible sans connexion, nous en savons déjà plus, il s’agit d’une authentification locale.
Commençons réellement au commencement
L’identification de l’authentification locale est un vrai plus, car, cela nous confirme que l’analyse réseau n’était pas la première étape à mettre en place.
En effet, avant cela, nous allons lancer Frida afin de voir ce qu’il se passe au niveau du système de fichier au cours de l’initialisation de l’application (cela nécessite donc de désinstaller (adb uninstall com.domobile.applock) et de réinstaller l’application (adb install com.domobile.applock.apk)) :
Comme il est possible de le voir, le script android-filesystem-observer2.js va permettre d’identifier les différents appels au système de fichier et nous préciser les fichiers créés à l’initialisation.
Dès lors, il est possible de voir que l’application AppLock stocke de nombreuses informations dans des SharedPreferences. En effet, l’analyse du fichier com.domobile.applock_preferences.xml peut donner une première piste d’audit :
La ligne « password » attire forcément notre attention ! Néanmoins, ce dernier n’est pas celui que nous avons spécifié à l’initialisation (c’était 1234 (oui oui, pour de vrai)). Néanmoins, la chaîne de caractère juste après (« salt: ») nous intrigue et nous pousse à la retrouver dans le code, chose possible dans le fichier com.domobile.applock.hh :
Même si le code est obsuqué, il est possible de se rendre compte que la fonction b() permet la comparaison de deux chaînes de caractères et renvoi True si les chaînes correspondent, False dans le cas contraire, ressemblant ainsi parfaitement à une vérification du mot de passe. Tentons notre chance avec cette fonction.
Contournement de l’authentification
L’application AppLock ne semble pas disposer d’un contrôle d’intégrité. Ainsi, il est probablement assez simple de modifier le code smali de l’application afin que la fonction b() renvoie toujours True.
Néanmoins, cette technique étant largement documentée, nous allons passer notre chemin et créer notre propre script Frida pour l’occasion.
Afin de simplifier la tâche, il est possible d’utiliser un template de script Frida :
À présent, il est nécessaire de charger la classe en question au sein de la variable applock :
La dernière étape consiste à implémenter une « Yes Function » permettant de renvoyer True à chaque tentative.
Dans un cas classique, il serait possible d’avoir un code ressemblant à ce dernier pour notre fonction :
applock.b.implementation = function() {
return true;
}
Néanmoins, au sein du fichier com.domobile.applock.hh, il existe plusieurs fonctions nommées b() :
Il est donc nécessaire de surcharger notre appel (overload) en spécifiant la fonction à utiliser grâce à la précision du type de variable attendu (Context, String, String dans notre cas). Pour disposer de la chaîne complète à passer en argument de Frida, il est possible de se rendre directement dans la documentation d’Android :
En combinant tout cela, il est donc possible de disposer d’un script complet ressemblant à cela :
Il ne nous reste plus qu’à essayer notre script grâce à Frida de la manière suivante et se rendre compte qu’il contourne sans problème l’authentification locale :
frida -U -f com.domobile.applock -l AppLock.js