Aujourd'hui on fait du reverse sur appli Android.
J'ai trouvé une série de crackMe à cette adresse.

L'auteur de ce crackMe est Bernhard Mueller.

Android Level 1

Pour reprendre les termes de l'auteur:

Objective: A secret string is hidden somewhere in this app. Find a way to extract it.

On va commencer par une analyse statique de l'application.
Donc première étape: Décompiler l'APK.

apktool -f d UnCrackable-Level1.apk

Première difficulté: apktool ne fonctionne pas. Pas de problème on va utiliser un autre programme pour décompiler notre APK.

apktool -f d UnCrackable-Level1.apk
C'est un peu plus long mais au moins ca fonctionne.

Maintenant on va pouvoir analyser l'application grâce à JD-GUI.

Comme on peut le supposer au nom des classes, il y a eu une petite phase d’offuscation sur cet APK (oui, on dit un APK).

On peut voir ici que l'application implémente des techniques pour complexifier le reverse et le débugging.

La fonction a() de la classe c recherche si su est présent dans le PATH (variable d'environnement) si oui renvoi True.
La fonction b() de la classe c recherche dans les tags de construction si la string "test-keys" est présente si oui renvoi True.
La fonction c() de la classe c recherche la présence d'un package qui permet d'être root s'il est trouvé renvoi True.

Donc l'application se lance etcommence par effectuer ces différents tests. Si un seul des tests renvoi True alors un message est affiché et à l'instant où l'ont clic sur le bouton l'appli est arrêtée.

En fouillant un peu le reste du code on tombe sur cette étrange fonction:

Cette fonction semble appliquer un masque binaire sur les flags présents dans l'application.
Si on s'attarde un peu, on trouve que seule la valeur 2 renvoie 0 (car c'est un ET logique). En cherchant un peu dans la documentation on apprend que le flag debuggable a cette valeur. On est donc en présence d'une fonction qui à pour but d'empecher le débugging.

Maintenant que l'on a fait le tour des techniques mises en place pour nous empêcher de travailler on va pouvoir s'attaquer au coeur du problème, la vérification du mot de passe.
A partir de maintenant tout se passe dans la classe a du package uncrackable1.

Commençons par étudier la fonction la plus simple: b

Le principe de cette fonction est assez simple, elle convertit une chaine de caractères en un tableau d'octet.

Maintenant concentrons-nous sur la fonction a du package sg.vantagepoint.

Cette fonction a pour but de créer un objet cipher qui va déchiffrer le tableau d'octet paramArrayOfByte2 avec la clé paramArrayOfByte1.

Maintenant revenons dans la fonction a du package uncrackable.

Ici le code va récupérer une chaine de caractères encodée en base64, la décoder et la déchiffré avec la clé 8d127684cbc37c17616d806cf50473cc. Ensuite il va vérifier que cette chaine de caractères avec la chaine passée en paramètre (Celle que nous devons rentrer dans l'application).

Ensuite tout se joue dans la fonction verify() qui va afficher ou non le message de succès.

Finalement, il ne reste plus qu'à trouver la valeur de la chaine de caractère pour valider le challenge.

Pour ça, c'est simple on va utiliser Cyberchef. Mais avant de pouvoir décoder le message il faut trouver le vecteur d'initialisation (IV). Normallement il est aléatoire mais dans notre cas et dans les anciennes version d'android, il est à la valeur par défaut soit zéro.
Voila il ne reste plus qu'à entrer les paramètres trouvés dans notre programme et nous obtenons le fameux mot de passe.

On peut vérifier que c'est le bon mot de passe sur l'appli.

Et voila un challenge de reverse résolu sans même utiliser le débugger !

Social et Media

Comme toujours je suis  disponible sur Twitter et cie, si vous avez des questions, des  remarques, des suggestions etc. N’hésitez pas !

Twitter: @GhostAgs

Discord: hackraw