Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Grundlagen des Reverse Engineering

Die ganze Lektion steht hier zum Lesen. Erstellen Sie ein kostenloses Konto, um sie in einem Live-Lab auszuführen.

Ubuntu-VM-Lab11 Min. Lesezeit7 Befehle

Eine Datei ohne Quelltext

Eine Firma findet auf ihrem eigenen Server ein kleines Werkzeug, und niemand weiß mehr, wer es geschrieben hat. Es gibt keinen Quelltext, nur das Programm. Bevor es jemand startet, muss jemand lesen, was es tut. Das ist Reverse Engineering: herausfinden, wie ein Programm funktioniert, allein aus dem Programm selbst.

Am Ende dieser Lektion

Notiz

Ich kann mit einem Werkzeug herausfinden, was ein Programm ohne seinen Quelltext tut.

Die eine Regel

Notiz

Dieses Lab dient dazu, zu lesen, wie ein Programm funktioniert, so wie es Verteidiger der IT-Sicherheit und Studierende des Compilerbaus tun. Nutze es für die Programme in deinem eigenen Lab und für nichts anderes. Es lehrt nie, und du darfst es nie benutzen für: Schadsoftware, das Umgehen der Lizenz echter Software, Schlüsselgeneratoren, das Verstecken eines Programms vor einem Debugger oder Angriffe auf ein Programm, das nicht dir gehört. In Großbritannien ist das nach dem Computer Misuse Act 1990 eine Straftat, und in Deutschland sind solche Handlungen nach dem Strafgesetzbuch strafbar.

Schlüsselwörter

  • Binärdatei: ein Programm in der Form, in der der Computer es ausführt, eine Datei aus Maschinenbefehlen.
  • Disassembler: ein Werkzeug, das Maschinenbefehle wieder in lesbaren Assemblercode verwandelt.
  • Debugger: ein Werkzeug, das ein Programm ausführt, dort anhält, wo du es sagst, und seinen Speicher zeigt.
  • Register: ein winziger Speicher im Prozessor. Auf dieser Maschine enthält rdi das erste Argument eines Aufrufs.
  • Bibliotheksaufruf: ein Aufruf von fertigem Code wie puts, das Text ausgibt.
  • Systemaufruf: eine Anfrage eines Programms an das Betriebssystem, zum Beispiel zum Schreiben.

Zum Start: Was du schon weißt

Notiz

Antworte im Kopf. 1. Was ist Quelltext? 2. Was macht ein Compiler damit? 3. Was ist ein Funktionsargument? Die dritte Antwort brauchst du gleich.

Bevor du anfängst

Notiz

Klicke oben in der Leiste dieser Lektion auf Lab starten. Dieses Lab ist eine ganze Ubuntu-Maschine nur für dich und braucht deshalb etwas länger zum Starten als ein Container. Jede Schaltfläche Ausführen tippt ihren Befehl ins Terminal der Maschine, einen nach dem anderen in derselben Sitzung. Wenn eine meldet, dass die Maschine noch startet, warte ein paar Sekunden und klicke noch einmal. Um zuzusehen oder eigene Befehle zu tippen, klicke in der Leiste auf Terminal öffnen.

Eine Binärdatei lässt sich beschreiben

Das Lab legt seine Programme im Ordner revlab ab. hello versteckt kein Geheimnis: Es gibt eine Zeile aus. Der Befehl file sagt, was für eine Datei es ist, ohne sie auszuführen. Achte auf ELF, das Format von Programmen unter Linux, auf den Prozessor, für den sie gebaut wurde, und auf not stripped: Die Namen ihrer Funktionen stecken noch darin.

Befehl
file revlab/hello

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Strings findet den Text in einem Programm

Ein Programm trägt seinen Text in sich, lesbar, ob jemand ihn zeigen wollte oder nicht. strings gibt jede Folge lesbarer Zeichen aus, das ist eine lange Liste, und der Befehl behält deshalb nur die Zeile mit Hello. Du erfährst, was das Programm sagt, ohne es auszuführen.

Befehl
strings revlab/hello | grep Hello

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Prüfe dich

Tipp

Woher kamen die Wörter, obwohl du das Programm nie gestartet hast? Antwort: aus der Datei selbst: Ein Programm trägt seinen Text mit sich.

Ein häufiger Fehler

Warnung

Viele glauben, das Kompilieren verstecke, was ein Programm sagt. Kompilieren ändert die Form, nicht die Tatsachen: Der Text, die Namen der Aufrufe und die Reihenfolge der Schritte sind alle noch da. Alles, was ein Programm zum Arbeiten wissen muss, kann ein Leser finden. Bewahre deshalb nie ein Geheimnis in einem Programm auf.

Ein Disassembler zeigt die Befehle

objdump -d verwandelt die Befehle in Assembler, einen pro Zeile. Der Befehl fragt nur nach der Funktion main und behält die Zeilen, die puts erwähnen: Es gibt eine, einen call auf die Bibliotheksfunktion, die ausgibt. radare2 macht dieselbe Arbeit und fügt Namen hinzu. aa lässt es die Datei analysieren, pdf @ main gibt die Funktion aus. Suche den Namen puts und den Text, den es bekommt.

Befehl
objdump -d revlab/hello --disassemble=main | grep puts

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Befehl
r2 -q -e scr.color=0 -c 'aa' -c 'pdf @ main' revlab/hello 2>/dev/null

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Ein Debugger hält das Programm an und zeigt seinen Speicher

Starte das Programm unter gdb und halte es in der ersten Zeile von puts an. So, wie ein Aufruf auf dieser Maschine funktioniert, findet puts die Adresse seines Textes im Register rdi. x/s $rdi heißt: Zeige den String (string) an dieser Adresse. So liest du das Argument einer Funktion, während das Programm pausiert, wie du später ein Passwort lesen wirst.

Befehl
gdb -batch -ex 'break puts' -ex 'run' -ex 'x/s $rdi' revlab/hello

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Tracing zeigt die Aufrufe eines Programms

ltrace gibt jeden Bibliotheksaufruf mit seinen Argumenten aus, strace jeden Systemaufruf. Der erste zeigt, wie puts den Text bekommt. Der zweite zeigt, wie das Programm das Betriebssystem bittet, dieselben Bytes auf den Bildschirm zu schreiben, mit write. Die Begrüßung wird hier ins Leere geschickt, damit nur die Aufzeichnung zu sehen ist. Keiner von beiden verlangt, Assembler zu lesen.

Befehl
ltrace revlab/hello

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Befehl
strace -e trace=write revlab/hello >/dev/null

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Jetzt das Lab machen

Tipp

Du hast ein harmloses Programm mit jedem Werkzeug angesehen. Dein Lab hat fünf Programme, jedes mit einem Schlüssel, der in deiner Kopie anders ist, und du liest jedes mit dem Werkzeug, das dazu passt. Öffne die Datei README.md in deinem Home-Ordner mit cat README.md im Terminal und schreibe die Schlüssel, die du findest, in answers.txt.

Abschlusscheck

Tipp

Antworte, ohne zurückzuschauen. 1. Welches Werkzeug listet den lesbaren Text eines Programms auf? 2. Welches Werkzeug lässt dich ein laufendes Programm anhalten und seinen Speicher lesen? 3. Was ist der Unterschied zwischen einem Bibliotheksaufruf und einem Systemaufruf? 4. Warum ist ein Geheimnis in einem Programm nie wirklich geheim? Antworten: strings; ein Debugger, gdb; ein Bibliotheksaufruf geht an fertigen Code, ein Systemaufruf an das Betriebssystem; weil jeder lesen kann, was in der Datei steht.

Für Lehrkräfte

Tipp

Diese Lektion ist ein kleines Beispiel für eine Lektion, die in einem Lab durchgeführt wird: Die Schritte und die Schaltflächen Ausführen sind die Lektion, und das Lab ist die Kopie jeder lernenden Person. Sie läuft in einem VM-Lab: Jede lernende Person hat eine eigene Ubuntu-Maschine, und eine Schaltfläche Ausführen tippt in ihr Terminal und zeigt, was ausgegeben wurde. Wichtige Lernpunkte: 1. Ein Programm lässt sich ohne Quelltext lesen. 2. Text und Aufrufe bleiben in einem kompilierten Programm erhalten. 3. Ein Debugger zeigt den Speicher eines laufenden Programms. 4. Tracing zeigt die Aufrufe eines Programms. Häufiger Fehler: glauben, Kompilieren verstecke, was ein Programm tut. Material: das Lab und ein Browser. Tipp: Lassen Sie die Klasse vor jedem Werkzeug sagen, was hello tut, und prüfen Sie dann jede Vermutung. Das Lab selbst hat eine Prüfung, die die Schlüssel in answers.txt mit denen vergleicht, die für jede Kopie erzeugt wurden. Es ist defensives Lesen der Programme des Labs und sonst nichts. Kopieren Sie die Lektion in Ihr eigenes Modul und ändern Sie sie, oder bauen Sie mit dem Menü Lab im Lektions-Editor eine neue von Grund auf.

Über dieses Lab und seinen Quellcode: Reverse-Engineering-Lab: Programme mit gdb, radare2, strace und ltrace in einer VM lesen

Sie unterrichten eine Klasse? Weisen Sie diese Lektionen Ihren Lernenden zu, mit Bewertung und einem Lab für jede lernende Person.