Reversim MIPS et Golang - les bases de l'inverse. Résolution des problèmes de marche arrière avec r0ot-mi. 2e partie

image

Dans cet article, nous traiterons de la décompilation du binaire MIPS dans Ghidra et inverserons le programme écrit en golang dans l'IDA.

Partie 1 - Décompilation C, C ++ et DotNet.

Information organisationnelle
Surtout pour ceux qui veulent apprendre quelque chose de nouveau et se développer dans l'un des domaines de l'information et de la sécurité informatique, j'écrirai et parlerai des catégories suivantes:

  • PWN;
  • cryptographie (Crypto);
  • technologies de réseau (réseau);
  • reverse (Reverse Engineering);
  • stéganographie (Stegano);
  • recherche et exploitation des vulnérabilités WEB.

En plus de cela, je partagerai mon expérience en criminalistique informatique, analyse de logiciels malveillants et micrologiciels, attaques sur les réseaux sans fil et les réseaux locaux, réalisation de pentests et écriture d'exploits.

Afin que vous puissiez vous renseigner sur les nouveaux articles, logiciels et autres informations, j'ai créé une chaîne dans Telegram et un groupe pour discuter de tout problème dans le domaine de l'ICD. Aussi, je considérerai personnellement vos demandes, questions, suggestions et recommandations personnelles et répondrai à tout le monde .

Toutes les informations sont fournies à des fins éducatives uniquement. L'auteur de ce document n'assume aucune responsabilité pour tout dommage causé à quelqu'un du fait de l'utilisation des connaissances et des méthodes obtenues à la suite de l'étude de ce document.

ELF MIPS


image

Téléchargez et vérifiez le fichier.

image

Il s'agit d'un fichier exécutable 32 bits pour les processeurs d'architecture MIPS. Pour résoudre ce problème, nous utiliserons Ghidra. Ouvrez l'hydre, créez un nouveau projet et ajoutez-le à notre fichier exécutable.

image

Ouvrez maintenant le fichier étudié et accédez à la fenêtre de l'arbre des symboles. Dans la recherche, tapez main pour trouver le point d'entrée du programme.

image

Lorsque vous sélectionnez une fonction, elle s'ouvre immédiatement dans le décompilateur.

image

Convertissons le code.

image

Nous voyons que 64 octets sont lus dans la variable local_54, renommons-la en entrée (raccourci clavier L) et en faisons un tableau de 64 caractères (raccourci clavier Ctrl + L). Vous pouvez également renommer la variable sVar1.

image

image

Après une certaine conversion, le code a commencé à être un peu plus beau.

image

Nous analysons le code. La chaîne que nous entrons doit comporter 19 caractères. À quelle position quel caractère doit être clair dans le code. Dans ce cas, du 8 au 17 devrait être le symbole «i». Nous récupérons, passons le mot de passe.

Golang basic


image

Dans cette mission, nous sommes fournis avec un fichier exécutable écrit en Go. Vous pouvez même savoir quelle version. Je jette l'IDA. Il faut dire tout de suite que la fonction principale n'est pas appelée main, mais appelée main_main. Par conséquent, nous effectuons une recherche par fonction et passons à la vraie principale.

image

Analysons le code. Commençons par le tout début.

image

Il existe des définitions d'une entrée clé. Le bloc de gauche est responsable de l'achèvement de la fonction main_main. Considérez le bloc de gauche.

image

La fonction fmt_Scanln est conçue pour lire une ligne depuis la console. Nous observons également les données main_statictmp_2 déjà enregistrées dans le programme.

image

Ensuite, la fonction runtime_stringtoslicebyte est appelée, selon le code, nous pouvons supposer qu'elle prend les 6 premiers octets de la ligne suivante.

image

Key.ptr pointera vers le début de cette tranche. Voyons ce qui vient ensuite.

image

En fonction de la comparaison du registre annulé r9 et du registre rsi, où se trouve la longueur de l'entrée utilisateur. De cela, nous pouvons conclure que r9 sera très probablement un compteur. Regardons le bloc de droite, où ira le contrôle, après la vente sur la ligne que nous avons entrée.

image

La fonction bytes_Compare est appelée, qui, selon le résultat de la comparaison, affiche l'une des lignes.

image

image

Nous avons compris la sortie du programme, maintenant regardons les sauts de ligne (sur la branche de gauche).

image

Le caractère de l'entrée utilisateur est entré dans le registre r10, puis il y a un tas de code complexe pour les comparaisons afin de contrôler les exceptions comme la division de panique et l'index de panique. J'ai mis en évidence la branche d'exécution du programme.

image

Ainsi, un octet d'une chaîne spécifiée statiquement est placé dans EDX et se dispute avec r10, où est l'octet de la tranche. Ensuite, le compteur r9 augmente. Deux blocs adjacents au milieu sont probablement nécessaires pour contrôler la longueur de la coupe.

Combinons tout ensemble: la ligne entrée est contaminée par une tranche et comparée à une ligne spécifiée statiquement. Prenons un proxy pour trouver le mot de passe correct.

image

Nous obtenons la réponse. La complexité de l'inverse des binaires Go est qu'il y a des facteurs de complication comme l'absence de caractère nul à la fin des lignes, la présentation de leurs types, le garbage collector, etc.

C'est tout pour l'instant. À suivre ... Vous pouvez nous rejoindre sur Telegram . Là, vous pouvez proposer vos propres sujets et voter sur le choix des sujets pour les articles suivants.

Source: https://habr.com/ru/post/fr474656/


All Articles