EBCTF Teaser 2013 – BIN100

EBCTF Teaser 2013 - BIN100 - task description

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.

EBCTF Teaser 2013 - BIN100 - dice game

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:

EBCTF Teaser 2013 - BIN100 - rand function assembler

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:

EBCTF Teaser 2013 - BIN100 - change register eax

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:

EBCTF Teaser 2013 - BIN100 - roll seven

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:

EBCTF Teaser 2013 - BIN100 - no rand function

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.

EBCTF Teaser 2013 - BIN100 - binary memory dump

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:

EBCTF Teaser 2013 - BIN100 - flag extraction failed

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:

EBCTF Teaser 2013 - BIN100 - patched result

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.

EBCTF Teaser 2013 - BIN100 - pachted last roll

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:

EBCTF Teaser 2013 - BIN100 - solution

Die Lösung lautet “ebCTF{64ec47ece868ba34a425d90044cd2dec}“.

7 thoughts on “EBCTF Teaser 2013 – BIN100

    1. Rup0rt Post author

      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.

      Reply
        1. Rup0rt Post author

          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…

          Reply
  1. Pingback: Thice.nl » Eindbazen ebCTF write-ups

Leave a Reply

Your email address will not be published. Required fields are marked *