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 InformationenSpeziell 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

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

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.

Ö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.

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

Lassen Sie uns den Code konvertieren.

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.


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

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

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.

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

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.

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

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.

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

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.

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


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

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.

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.

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.