Reversim MIPS und Golang - die Grundlagen des Reverse. Lösen von Problemen beim Umkehren mit r0ot-mi. Teil 2

Bild

In diesem Artikel werden wir uns mit der Dekompilierung der MIPS-Binärdatei in Ghidra befassen und das in golang in der IDA geschriebene Programm umkehren.

Teil 1 - C, C ++ und DotNet dekompilieren.

Organisatorische Informationen
Speziell für diejenigen, die etwas Neues lernen und sich in einem der Bereiche Informations- und Computersicherheit weiterentwickeln möchten, werde ich folgende Kategorien beschreiben und besprechen:

  • PWN;
  • Kryptographie (Crypto);
  • Netzwerktechnologien (Netzwerk);
  • Reverse (Reverse Engineering);
  • Steganographie (Stegano);
  • Suche und Ausnutzung von WEB-Schwachstellen.

Darüber hinaus werde ich meine Erfahrungen in den Bereichen Computerforensik, Analyse von Malware und Firmware, Angriffe auf drahtlose Netzwerke und lokale Netzwerke, Durchführung von Pentests und Schreiben von Exploits teilen.

Damit Sie sich über neue Artikel, Software und andere Informationen informieren können, habe ich in Telegram einen Channel und eine Gruppe erstellt, um alle Fragen im Bereich ICD zu diskutieren . Auch ich werde Ihre persönlichen Wünsche, Fragen, Anregungen und Empfehlungen persönlich berücksichtigen und auf alle antworten .

Alle Informationen werden nur zu Bildungszwecken bereitgestellt. Der Autor dieses Dokuments übernimmt keine Verantwortung für Schäden, die jemandem durch die Verwendung von Kenntnissen und Methoden entstehen, die er durch das Studium dieses Dokuments erlangt hat.

ELF MIPS


Bild

Laden Sie die Datei herunter und überprüfen Sie sie.

Bild

Dies ist eine ausführbare 32-Bit-Datei für MIPS-Architekturprozessoren. Um dieses Problem zu lösen, werden wir Ghidra verwenden. Öffnen Sie die Hydra, erstellen Sie ein neues Projekt und fügen Sie es unserer ausführbaren Datei hinzu.

Bild

Öffnen Sie nun die untersuchte Datei und wechseln Sie zum Symbolbaumfenster. Geben Sie bei der Suche main ein, um den Einstiegspunkt des Programms zu finden.

Bild

Wenn Sie eine Funktion auswählen, wird diese sofort im Dekompiler geöffnet.

Bild

Lassen Sie uns den Code konvertieren.

Bild

Wir sehen, dass 64 Bytes in die Variable local_54 eingelesen werden. Benennen wir sie in input um (Hotkey L) und erstellen daraus ein Zeichen-Array mit 64 Zeichen (Hotkey Strg + L). Sie können die Variable sVar1 auch umbenennen.

Bild

Bild

Nach einiger Konvertierung sah der Code etwas schöner aus.

Bild

Wir analysieren den Code. Die eingegebene Zeichenfolge muss 19 Zeichen lang sein. An welcher Stelle soll welches Zeichen aus dem Code ersichtlich sein. In diesem Fall sollte vom 8. bis 17. das Symbol 'i' sein. Wir erholen uns, geben das Passwort weiter.

Golang Basic


Bild

In dieser Aufgabe erhalten wir eine ausführbare Datei, die in Go geschrieben ist. Sie können sogar herausfinden, welche Version. Ich werfe die IDA ein. Es sollte sofort gesagt werden, dass die Hauptfunktion nicht main heißt, sondern main_main. Daher führen wir eine Suche nach Funktionen durch und gehen zur eigentlichen Hauptfunktion über.

Bild

Lassen Sie uns den Code analysieren. Fangen wir von vorne an.

Bild

Es gibt Definitionen für eine, Taste, Eingabe. Der linke Block ist für die Ausführung der main_main-Funktion verantwortlich. Betrachten Sie den linken Block.

Bild

Die Funktion fmt_Scanln dient zum Lesen einer Zeile von der Konsole. Wir beobachten auch die bereits im Programm gespeicherten main_statictmp_2-Daten.

Bild

Als nächstes wird die Funktion runtime_stringtoslicebyte aufgerufen. Entsprechend dem Code können wir davon ausgehen, dass die ersten 6 Bytes aus der nächsten Zeile stammen.

Bild

Key.ptr zeigt auf den Anfang dieses Slice. Mal sehen, was als nächstes kommt.

Bild

Abhängig vom Vergleich des annullierten Registers r9 und des Registers rsi, in dem sich die Länge der Benutzereingabe befindet. Daraus können wir schließen, dass r9 höchstwahrscheinlich ein Zähler sein wird. Schauen wir uns den rechten Block an, in den die Steuerung nach dem Verkauf auf der von uns eingegebenen Linie geht.

Bild

Es wird die Funktion bytes_Compare aufgerufen, die abhängig vom Vergleichsergebnis eine der Zeilen anzeigt.

Bild

Bild

Wir haben die Ausgabe des Programms herausgefunden. Schauen wir uns nun die Zeilenumbrüche an (im linken Zweig).

Bild

Das Zeichen aus der Benutzereingabe wird in das r10-Register eingegeben, und dann gibt es eine Reihe komplexer Codes für Vergleiche, um Ausnahmen wie Panic Divide und Panic Index zu steuern. Ich habe den Programmausführungszweig hervorgehoben.

Bild

So wird ein Byte aus einem statisch festgelegten String in EDX gestellt und mit r10 gestritten, wobei das Byte aus dem Slice steht. Als nächstes erhöht sich der Zähler r9. Zwei in der Mitte benachbarte Blöcke werden höchstwahrscheinlich benötigt, um die Länge des Schnitts zu steuern.

Kombinieren wir alles miteinander: Die eingegebene Zeile wird mit einem Slice kontaminiert und mit einer statisch festgelegten Zeile verglichen. Lassen Sie uns Proxy das richtige Passwort herausfinden.

Bild

Wir bekommen die Antwort. Die Komplexität der umgekehrten Go-Binärdateien besteht darin, dass es komplizierende Faktoren gibt, wie das Fehlen eines Nullzeichens am Ende der Zeilen, die Darstellung ihrer Typen, den Garbage Collector usw.

Das ist alles für jetzt. Fortsetzung folgt ... Sie können sich uns per Telegramm anschließen . Dort können Sie Ihre eigenen Themen vorschlagen und über die Themenauswahl für die folgenden Artikel abstimmen.

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


All Articles