[DE] Bufferoverflow - Praxisbeispiel
Vorallem eingebettete Systeme nutzen oftmals Hardwarenahe Programmiersprachen und sind damit anfällig für Buffer-Overflows. Nachdem ich in einem vorherigen Beitrag die theoretische Funktionsweise beschrieben habe, möchte ich diese in diesem Artikel anhand eines Beispiels verdeutlichen.
Um sich mit dem Ausnutzen von Bufferoverflows in Firmware näher zu beschäftigen bietet sich die Damn Vulnearable Router Firmware an. Hierbei handelt es sich um eine Firmware, die insofern modifiziert wurde, dass eine Menge verschiedener Schwachstellen enthalten sind. Dies ermöglicht es sich neben der Theorie auch praktisch mit Schwachstellen auseinander zu setzen um diese besser verstehen zu können und anschließend an einer "echten" Firmware überprüfen zu können.
Mit dem Tool Binwalk können erste Informationen über das Binary gesammelt werden:
Mithilfe des Firmware-Modificatoin-Kits ist es möglich Zugriff auf das in der Firmware enthaltende Sqasch-Dateisystem zu erhalten.
In dem Ordner pwnable/Intro befindet sich unter anderem die Datei stack_bof_01. Diese wurde extra so entwickelt, dass eine als Parameter übergebene Benutzereingabe unter gewissen umständen zu einem Pufferüberlauf führen kann. Ziel ist es eine Funktion innerhalb der Datei auszuführen, die nur über die entsprechende Schwachstelle ausführbar ist.
Mit dem Befehl rabin2 -I stack_bof_01
lassen sich weitere Informationen zur Binärdatei anzeigen. So hat sich herausgestellt, dass die Datei auf einem MIPS System laufen soll.
Nun kann die Datei mithilfe des radare2 frameworks analysiert werden. Radare2 ist ein Forensik und Reverse Engineering Framework, mit dem es möglich ist Binärdateien zu analysieren. Das Tool kann mit radare2 -a mips -b 32 pwnable/Intro/stack_bof_01
die entsprechende Datei öffnen.
Anschließend können mit dem Befehl aa (analyse all) gefolgt von afl die während des Programmflusses genutzten Funktionsaufrufe eingesehen werden. Hierbei ist unter anderem die für Pufferüberläufe bekannte C-Funktion strcopy zu sehen. Des weiteren wird die Funktion dat_shell angezeigt, dessen Ausführung das Ziel dieser Übung ist.
Radare2 bietet neben diesen noch eine Menge anderer Funktionalitäten die eine weitere Analyse erlauben. Eine davon ist über den Befehl izz aufzurufen und gibt alle druckbaren Strings aus.
Um herauszufinden, welche Datenmenge erforderlich ist um den Puffer zum Überlaufen zu bringen, wird eine einzigartige Zeichenkette genutzt, die größer als der zur Eingabe reservierte Speicher ist.
Eine einfache möglichkeit zur erstellung diese Zeichenkette bietet Metasploit. Das Metasploit-Framework ist ein Projekt zum finden von Sicherheitslücken und Penetrationstests. Dieses bietet eine sehr umfangreiche Sammlung von Exploits und Tools. Im Ordner tools/exploit des Frameworks befindet sich die Datei pattern_create.rb die eine solche Zeichenkette mit definierbarer länge erstellt. In meinem Fall habe ich 400 Zeichen gewählt.
->Emulation des Programmes:
Um die Datei stack_bof_01 ausführen zu können, muss diese emuliert werden.
Ich nutze hierzu qemu. Für unsere Zwecke reicht eine Installation mittels
sudo apt-get install qemu-user-static
Anschließend Kopieren wir die Datei qemu-mipsel-static in das Root-Verzeichniss unseres Dateisystems. Nun kann das Programm mittels chroot ausgeführt werden:
Die oben zueben generierte Zeichenkette wird nun als Argument des Programmes angegeben. Wie erwartert beendet sich das Programm mit einem Segmentation fault. Um nun die Menge der Zeichen zu ermitteln, habe ich den Debugger gdb-multiarch genutzt.
Der Debugger wird in einer gesonderten Konsole auf auf die Architektur mips gesetzt und über "target remote 127.0.0.1:1234" mit dem Programm verbunden.
Anschließend können die Register über den Debugger eingesehen werden. Interessant ist hierbei der Programmcounter (PC) dieser enthält in meinem Fall den Wert 0x41386741.
Nachdem diese Hex-Zahl in ASCII umgewandet wurde ist wichtig zu beachten den entsprechenden Wert umzukehren (A8gA->Ag8A). Um den Offset, also die Stelle zu finden, an der sich die 4 Zeichen in meiner Urspünglich erstellten Zeichenkette befinden gibt es ein pattern_offset genanntes Tool im Metasploit-Framework. In meinem Fall war der Offset 204.
Somit kann eine neue Zeichenkette erstellt werden, die diesmal eine länge von 204 Zeichen hat. An diese wird nun eine Sprungadresse der Funktion dat_shell angehängt.
Wir nehmen in diesem Fall 40095c:
Nach der Zeichenkette von 204 Zeichen gefolgt von "echo -e '\\x5c\\x09\\x40'
" springt das Programm an die Entsprechende Stelle und dat_shell wird ausgeführt.
Offene Fragen beantworte ich wie immer gerne in den Kommentaren.
Vielen Dank fürs Lesen !
Bin ja durchaus am Lesen, aber wenig am kommentieren. Wirklich Hut ab! Man wird doch recht oft gefragt, was ein BufferOverFlow eigentlich ist und merkt selbst wie oft man die Leute mit einfachen Erklärungen abspeist.
Deine Beispiel mit Kali hier ist wirklich alles andere als eine einfache Lösung und lässt keine Fragen offen. Ich beginne mich für meine einfachen Erklärungen zu schämen und kann nur sagen: Kudos!
Gut, dass Du das hier erklärst. Ich selbst scheitere vollkommen daran anderen Menschen diese Abläufe verständlich zu schildern, weil ich sie selbst nur grob verstehe. Wir brauchen alle viel mehr IT Allgemeinwissen. Thx & Props!
Hat mir gefallen :)
Hello to a bunch of people who are people in Chaos Computer Club :) . Cool writeup thanks to google translate.