Die BIN100 Challenge (“Dice Game”) verlangt von uns, das “Würfelspiel” zu schlagen und so die Flagge zu erhalten. Bei dem Würfelspiel handelt es sich um diese EXE-Datei, die wir auch direkt ausführen.
Wir sehen, dass das Programm Würfel simuliert, die per Zufall geworfen werden. Beim ersten Wurf war es mir hier noch aus eigener Kraft möglich, die Bedingung, eine Drei zu würfeln zu erfüllen ;-). Beim zweiten Wurf jedoch war der Zufall nicht mehr auf unserer Seite.
Es sieht also nach danach aus, das Programm binär manipulieren zu müssen, weshalb wir es in den Immunity Debugger laden. Wir starten das Programm, lassen es bis zur Eingabeaufforderung laufen und übernehmen dann mit dem Debugger. Dabei stößt man schnell auf folgenden Programmteil:
Hier sehen wir, dass die rand() Funktion aufgerufen wird, die einen Zufallswert produziert. Nach einigen Rechenoperationen auf diesem Ergebnis werden mehrere Vergleiche (CMP) durchgeführt. Hierbei handelt es sich offenbar um den Abschnitt, der für unser Würfelergebnis verantwortlich ist.
Zum aktuellen Zeitpunkt (markierte Zeile) sollte im Register EAX daher 3 stehen, damit die Bedingung, eine Drei zu würfeln erfüllt wird. Diesen Wert ändern wir daher mit dem Debugger:
Anschließend lassen wir das Programm weiter laufen und wiederholen diese Schritte auch bei den folgenden Wurfbedingungen. Nach der Drei folgt eine Eins, Drei, Drei und anschließend folgende Forderung:
Wir sollen eine Sieben würfeln!! 😛 Ohne Debugger wäre das ohnehin schwierig geworden ;-). Aber so gehen wir im Assembler-Code voran bis zu der Stellen, an der das Würfelergebnis verglichen wird. Diesmal stellen wir jedoch eine Veränderung fest:
Es gibt keine rand()-Funktion, die unser zufälliges Ergebnis bestimmen soll. Vielmehr wird nur auf einen Speicherbereich zugegriffen (EBP-5C) und das Würfelergebnis von dort verglichen. Ohne uns zunächst beirren zu lassen, springen wir zu dem Speicherbereich und ändern die dort vorhandene Zahl.
An der Speicheradresse befindet sich die Zahl 3, die wir direkt im Speicher auf eine Sieben (07 00 00 00) ändern. Wenn wir das Programm nun weiter laufen lassen, erhalten wir folgende Meldung:
Die Sieben wurde zwar erkannt, eine Flagge aber nicht ausgegeben. Es scheint so, als gäbe es im Programm noch weitere Schutzfunktionen, die solche Manipulationen verhindern sollen.
Besonders auffällig sind die wiederholt auftretenden time()-Funktionen (siehe Assembler-Code). Diese werden vor der rand() Funktion und nach der Überprüfung des Wurfes ausgeführt und könnten so überprüfen um wir das Programm angehalten und die Werte manuell editiert haben.
Wir werden das gesamte Vorgehen nun wiederholen, jedoch diesmal den Assembler-Code anpassen um direkt die Würfe zu erzeugen, die vom Programm erwartet werden. Wir beginnen mit dem ersten Wurf (der Drei) und manipulieren die Quellcode nach der rand()-Funktion wie folgt:
Anstatt also den Rückgabewert von rand() zu nutzen, setzen wir die beiden involvierten Register (ECX und EAX) auf die Werte, die beim zufälligen Wurf von Drei entstanden wären. Das selbe tun wir für die anderen Würfe von Eins, Drei und Drei. Nur beim Wurf von Sieben müssen wir, da sich der Quellcode ändert, eine Befehle einfügen.
Hier ändern wir direkt im Speicher (EBP-5C) den Wert auf 7. Da für dieses Kommando mehr Bytes benötigt werden als verfügbar sind, ersetzen wir die komplette Überprüfung auf den Wurf von Eins ebenfalls mit NOPs.
Die Änderungen können wir nun in eine gecrackte Binärdatei exportieren. Wenn wir diese anschließend ausführen, erhalten wir folgendes Ergebnis:
Die Lösung lautet “ebCTF{64ec47ece868ba34a425d90044cd2dec}“.
You can record the video?
I did not record a video, sorry.
Are you missing a certain part or step that I could explain in detail?
I don’t understand deutsch 😉
Google translate does not help 🙁
I’m sorry for that. 🙁 I just changed some parts of the writeup to make it more readable in the translation. In fact you just have to step through the code and change the registers before comparing them with the expected numbers. It might help to search for the memory addresses shown on the screenshot and set breakpoints there.
So…
http://i47.fastpic.ru/big/2013/0604/a8/bfceddd1435c402af78d8b8862ae17a8.jpg
I can not find the memory for cmp 🙁
sorry for delay…
check address 0x0040254E or search for text string “[*] You rolled a seven, with a six sided dice! How awesome are you?!” – you will find the interesting compares just above…
Pingback: Thice.nl » Eindbazen ebCTF write-ups