Tag Archives: assembler

Boston Key Party CTF 2013 – randy

Boston Key Party CTF 2013 - randy - task description

Bei der Challenge “randy” wird uns eine Binärdatei bereit gestellt und auf “Zufälligkeit” hingeweisen. Nach dem Download starten wir das Programm direkt um dessen Funktionalität zu beobachten.

root@linux64:~# ./randy
Password: rup0rt
:(

Das Binary verlangt nach der Eingabe eines Passwortes. Bei Eingabe einer beliebigen (falschen) Zeichenfolge erhalten wir nur ein trauriges Smiley. Um zu erfahren, wie das Programm das Passwort verarbeitet und die Korrektheit bestimmt, nutzen wir objdump um den Assembler-Code zu erzeugen.

Darin fingen wir unter anderem folgende Abschnitte:

0000000000400884 <main>:
[...]
  400958:  e8 c3 fc ff ff  call   400620 <strlen@plt>
  40095d:  48 83 f8 1c     cmp    rax,0x1c
[...]
  400983:  b8 00 00 00 00  mov    eax,0x0
  400988:  e8 97 fe ff ff  call   400824 <wrong>

Zunächst wird die Funktion strlen() aufgerufen um die Länge des von uns eingegebenen Passwortes zu bestimmen. Anschließend wird das Ergebnis mit 0x1c (28) verglichen und bei Misserfolg, das Programm mit der <wrong> Funktion beendet. Wir wissen also, dass das Passwort 28 Zeichen lang sein muss.
Continue reading

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
Continue reading

plaidCTF 2013 – hypercomputer 1

plaidCTF 2013 - Hypercomputer 1 - Task description

Diese Challenge (hypercomputer 1) erinnert nicht nur vom Namen her an die Supercomputer-Challenge aus dem vorjährigen plaidCTF 2012. Auch die Aufgabenstellung selbst weist bereits auf diese Challenge hin und vermerkt, dass es diesmal einfacher sein soll. Neben der Beschreiben erhalten wir die IP-Adresse eines SSH-Servers von dem wir uns dieses Binary kopieren.

Eine erste Untersuchung zeigt uns…

root@linux64:~/Plaid2013# file hypercomputer 
hypercomputer: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x0b7c8d904831417f536c59b59fdecfc738136536, stripped

…, dass es sich um ein 64bit Linux-Binary handelt, das beim normalen, testweisen Ausführen diese Ausgabe liefert:

root@linux64:~/Plaid2013# ./hypercomputer 
...Welcome to Hypercomputer!...
...This could take a very long time...

Es ist jedoch nicht so, dass dieser Text sofort erscheint – vielmehr dauert es mehrere Sekunden, was darauf schließen lässt, wie lange die gesamte Berechnung und Ausgabe der Flagge dauern könnte. Im letzten Jahr musste der Assembler-Code per Hand untersucht und optimiert werden, also sehen wir uns auch diesmal das Programm im Debugger an.

root@linux64:~/Plaid2013# gdb ./hypercomputer 
GNU gdb (GDB) 7.4.1-debian
Reading symbols from /root/Plaid2013/hypercomputer...(no debugging symbols found)...done.
(gdb) run
Starting program: /root/Plaid2013/hypercomputer 
...Welcome to Hypercomputer!...
...This could take a very long time...
^C
Program received signal SIGINT, Interrupt.
0x00007ffff787cbc0 in nanosleep () from /lib/x86_64-linux-gnu/libc.so.6

Durch die Unterbrechung der Programmausführung mit CTRL+C sehen wir, dass die Ausführung in der Funktion nanosleep(), die eine bestimmte Zeit abwartet, angehalten wurde. Dies erinnert schon an das Vorjahr, in dem der Programmablauf ebenfalls durch solche Funktionen künstlich verzögert wurde.
Continue reading

ForbiddenBITS CTF 2013 – Old

ForbiddenBITS CTF 2013 - old - task description

Wie gewohnt ist Weniger auch diesmal Mehr und wir erhalten als Aufgabe (old) nur einen Kommentar, dass es sich um einen “scheinbaren binären Auftrag” handelt. Zusätzlich wird eine Datei zum Download bereit gestellt.

Die erste Betrachtung mit dem Werkzeug “file” um festzustellen, um was für einen Typ von Datei es sich in Wirklichkeit handelt, liefert:

rup0rt@lambda:~/FB2013/old$ file bin.bin
bin.bin: x86 boot sector, code offset 0x6e

Uns liegt also ein bootbares Image vor, das durch Übergabe an einen Emulator, wie QEMU gestartet werden könnte. Da die Datei allerdings nur 512 Bytes groß ist und das simple Starten per Emulator ohnehin nicht die Flagge liefern wird, sehen wir uns direkt etwas genauer an. Zunächst prüfen wir, welche Zeichenketten enthalten sind:

rup0rt@lambda:~/FB2013/old$ strings bin.bin
Password: 
,jNice, 16bits world is nice :D. Validate using that password :)
No :(, try again.

Offensichtlich scheint eine Passwortabfrage implementiert zu sein, die abhängig von der korrekten Eingabe eine positive oder negative Rückmeldung erzeugt. Unser Ziel zur Lösung der Challenge wird es also sein, an genau dieses Passwort zu gelangen.
Continue reading

ATAST CTF Quals 2012 –
Crack It!

Zu dieser Challenge gibt es keine weitere Aufgabenstellung, da der Name bereits selbsterklärend ist – “Crack It!”. Alles was wir erhalten, ist eine ZIP-Datei mit einem Binary.

rup0rt@lambda:~/ATAST2012$ file crackit
crackit: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, BuildID[sha1]=0x1eb85f9048b1d8dddfbc3898826aaddfe63a55ab, not stripped

… einem Linux-32bit-Programm um genau zu sein. Dieses führen wir, wie gewohnt, erst einmal aus um deren Funktionsweise überblicken zu können.

rup0rt@linux:~/ATAST2012$ ./crackit
Usage : ./crackit <password>

rup0rt@linux:~/ATAST2012$ ./crackit 12345
hahaha wrong password :p

Wie bei der vorherigen Challenge auch wird also ebenso ein Passwort benötigt um die Abfrage des Programmes passieren und somit die Lösung zur Aufgabe (Crackt It!) erhalten zu können. Erneut beginnen wir mit einer Betrachtung des Assembler-Codes durch Verwendung von “objdump”, wobei folgender Abschnitt direkt auffällt:

8048620: c7 44 24 0c 00 00 00  mov DWORD PTR [esp+0xc],0x0
8048628: c7 44 24 08 00 00 00  mov DWORD PTR [esp+0x8],0x0
8048630: c7 44 24 04 00 00 00  mov DWORD PTR [esp+0x4],0x0
8048638: c7 04 24 00 00 00 00  mov DWORD PTR [esp],0x0
804863f: e8 c4 fd ff ff        call 8048408 <ptrace@plt>
8048644: 85 c0                 test eax,eax
8048646: 79 16                 jns 804865e <main+0x6d>

Das Programm ruft die Funktion “ptrace()” auf (Zeile 5), prüft anschließend deren Rückgabewert (Zeile 6) und springt, davon abhängig, weiter in den Quellcode (Zeile 7). Mit “ptrace()” können Prozesse debuggt und gesteuert werden. Dies Funktioniert jedoch nur für einen Prozess. Sollten wir also bei Programmstart selbst einen Debugger verwenden, wird “ptrace()” fehlschlagen und das Programm beendet.

Hierbei handelt es sich hierbei also um eine Anti-Debugging-Methode, die verhindern soll, dass wir mit Programmen wie “strace” oder dem GDB das Programm bei der Ausführung beobachten. Um diesen Schutz zu umgehen verändern wir einfach den bedingten Sprung (Zeile 7) in einen unbedingten Sprung unter Verwendung eines Hex-Editors.
Continue reading

ATAST CTF Quals 2012 –
Chall2_200pts (crack1)

Wie so oft werden wir auch bei dieser Challenge (crack1) einfach nur mit den Worten

“get the password”

begrüßt. Dieses Passwort sollen wir aus einer Binärdatei extrahieren.

Sehen wir uns also als Erstes den Typ des Binarys an:

rup0rt@lambda:~$ file crack1
crack1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, BuildID[sha1]=0x4579db2a2ebe3b4e83948f7a650dc3fced1d812d, not stripped

Es handelt sich um ein einfaches Linux-32bit-Programm.

Wir führen das Programm zunächst einmal aus um uns einen Überblick über dessen Funktionsweise zu verschaffen:

creeq@linux:~/ATAST2012$ ./crack1 
Password Required : 12345 
Wrong !!!! better luck next time :D

Es wird eine Passwortabfrage durchgeführt, die uns anschließend, bei Eingabe von “12345”, mit “falsch” beantwortet wird. Unser Ziel ist es daher, den Programmcode zu untersuchen um festzustellen, wie genau das Passwort überprüft wird und so an die korrekte Lösung zu gelangen.

Dafür nutzen wir “objdump” um an den Assembler-Code des Binarys zu gelangen. Dabei fallen folgende Inhalte in der <main>-Funktion auf:

804865f:     mov    eax,DWORD PTR [esp+0x2c]
8048663:     mov    edx,DWORD PTR [esp+0x2c]
8048667:     movzx  edx,BYTE PTR [esp+edx*1+0x32]
804866c:     xor    edx,0x21

804866f:     mov    BYTE PTR [esp+eax*1+0x68],dl
8048673:     mov    eax,DWORD PTR [esp+0x2c]
8048677:     mov    DWORD PTR [esp+0x8],eax
804867b:     lea    eax,[esp+0x68]
804867f:     mov    DWORD PTR [esp+0x4],eax
8048683:     lea    eax,[esp+0x54]
8048687:     mov    DWORD PTR [esp],eax
804868a:     call   80484d0 <strncmp@plt>

804868f:     test   eax,eax
8048691:     jne    804869a <main+0x106>
8048693:     add    DWORD PTR [esp+0x2c],0x1
8048698:     jmp    80486ad <main+0x119>

In Zeile 4 wird eine XOR-Operation auf einen statischen Byte-Wert angewendet. Dies ist für gewöhnlich nur dann der Fall, wenn Daten im Programm versteckt wurden. Anschließend (Zeile 13) wird die “strcmp”-Funktion ausgeführt um den mit XOR erhaltenen Wert, mit den von uns eingegebenen Passwort-Buchstaben zu vergleichen. Zuletzt (Zeile 15) wird geprüft, ob die Zeichen überein stimmen und bei Erfolg der Buchstaben-Zähler (Zeile 17) erhöht.
Continue reading

Hack.Lu CTF 2012 –
Secure Safehouse

Hack.Lu CTF 2012 - Secure Safehouse - task description

Diese Challenge (Secure Safehouse) ist sehr ähnlich zu Safehouse. Es werden uns neben der oben genannten Aufgabenstellung wieder SSH-Zugangsdaten genannt. Nach dem Login und einem Listing des Verzeichnisinhaltes sehen wir folgendes:

Hack.Lu CTF 2012 - Secure Safehouse - setuid file view

Wieder gibt es eine Datei mit SUID-Bit namens “secure-safehouse” sowie eine “FLAG”-Datei, deren Auslesen wohl das Ziel dieser Challenge darstellt. Aus den Erfahrungen der vorherigen Challenge prüfen wir an dieser Stelle auch schon, welche UID der Benutzer “secure_safehouse” besitzt, hier: 1005.

Anschließend erstellen wir, wie vorher auch, zunächst einen Objekt-Dump. Die Instruktionen sind größtenteils mit denen der Challenge Safehouse identisch. Ich verzichte daher auf ein Ansprechen aller Einzelheiten und werde nur die Besonderheiten und Unterschiede zur vorherigen Challenge hervorheben.

4009cd:  ff 55 d8           call  QWORD PTR [rbp-0x28]
4009d0:  8b 5d 8c           mov   ebx,DWORD PTR [rbp-0x74]
4009d3:  ff cb              dec   ebx
4009d5:  39 c3              cmp   ebx,eax
4009d7:  0f 85 87 fe ff ff  jne   400864 <sig>

Zunächst einmal existiert keine Routine “again” mehr, das heißt der von uns übergebene Opcode wird nicht mehr alle vier Bytes per CALL angesprungen, sondern nur noch einmal (Zeile 1). Da aber immernoch alle vier Bytes ein 0xc3 (RET) geschrieben wird, müssen wir uns diesmal etwas anderes überlegen, wenn wir mehr als nur 3 Bytes für unseren Opcode verwenden wollen.

Außerdem wird, nachdem unser unser Opcode angesprungen wurde (Zeile 1) nicht wie in der vorherigen Challenge direkt die Shell geöffnet, sondern vorher noch ein Vergleich durchgeführt. Im Detail wird die Variable “ARGC” (RBP-0x74, Zeile 2) um Eins verringert (Zeile 3), was die genaue Anzahl der Übergabeparameter ergibt, und anschließend mit dem Register EAX verglichen (Zeile 4). Wenn die Register nicht überein stimmen, wird ein Fehlersignal ausgelöst (Zeile 5).
Continue reading

Hack.Lu CTF 2012 – Safehouse

Hack.Lu CTF 2012 - Safehouse - task description

Neben dieser Aufgabenstellung werden uns die SSH-Zugangsdaten zu einem Server genannt, zu dem wir uns auch direkt verbinden um das Ziel dieser Challenge (Safehouse) besser fassen zu können.

Nach Login und Ausführung eines Dateilistings erhalten wir folgende Ausgabe:

Hack.Lu CTF 2012 - Safehouse - setuid file view

Zunächst einmal erkennen wir den coolen ASCII-Art-Zombie, der uns freundlich begrüßt ;-). Darüber hinaus ist eine Binärdatei “safehouse” im Verzeichnis hinterlegt sowie eine Datei namens “FLAG”. Ziel wird es also sein, den Inhalt der Datei “FLAG” auszulesen um an das Lösungswort der Challenge zu gelangen.

Da wir selbst jedoch der Benutzer “ctf” sind, können wir die Datei “FLAG”, die nur für den Benutzer “safehouse” lesbar ist, nicht ohne weiteres betrachten. Die Binärdatei “safehouse” jedoch gehört dem Benutzer “safehouse” und ist mit dem SUID-Bit versehen, dass heißt, sie wird bei Ausführung mit den Rechten dieses Benutzers gestartet.

Damit ist der Weg zum Ziel erkennbar: Wir werden die Binärdatei “safehouse” zum Beispiel durch einen Exploit derart ausnutzen müssen, dass wir eine Shell erhalten (oder zumindest das Tool “cat” benutzen) um dadurch die Datei “FLAG” ausgeben zu können.
Continue reading

Hack.Lu CTF 2012 –
Zombie AV Part 2

Im weiteren Verlauf des Capture the Flags wurde die Challenge “Zombie AV” abgeändert, wohlmöglich um sie schwerer oder leichter zu machen. Die vorher vorgestelte Lösung funktioniert ab diesem Zeitpunkt nicht mehr.

Grund dafür ist eine Änderung im Quellcode der Datei “elfparsing.php”, die sich folgerndermaßen darstellt:

function getEntryPoint($contents) { 
  global $readelfpath; 
  global $objdumppath;     

  $output=shell_exec($readelfpath.' -h '.$contents);  

  $data = preg_match( '/0x[a-fA-F0-9]{5,8}/', $output,$matches); 
  //$retValue=(hexdec($matches[0]) & 4294967288); 
  $retValue=hexdec($matches[0]); 
  return ($retValue ); 
}

Zeile 8 wurde auskommentiert(!!), was dazu führt, dass der Entry point und der Beginn der “Zombie-Opcodes” vom Scanner nun einheitlich betrachtet werden. Wir müssen also eine andere Lösung finden.

Die Schwachstelle ist jedoch immernoch die obige “getEntryPoint”-Funktion, da weiterhin einfach nur die erstbeste hexadezimale Speicheradresse der Ausgabe des Tools “readelf -h” per regulärem Ausdruck zur Überprüfung der Opcodes herangezogen wird (Zeile 7).

Wenn wir es also schaffen, eine weitere Speicheradresse vor den Entry Point in die Ausgabe von “readelf” zu schleusen, wird der “Zombie-Opcode” an dieser Adresse vom Scanner gesucht werden. Wir sehen uns dazu die Ausgabe von “readelf -h” etwas genauer an:

rup0rt@lambda:~$ readelf -h virus2
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048062
  Start of program headers:          52 (bytes into file)
  Start of section headers:          144 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         5
  Section header string table index: 2

Da die Adresse oberhalb des eigentlichen Entry Points liegen muss, scheint auf den ersten Blick nur das Feld “Version” zur Manipulation geeignet, da die anderen Felder Einfluss auf die Interpretation als 32bit ELF-Binary, und so wohlmöglich auf deren Ausführung, zu haben scheinen.
Continue reading

Hack.Lu CTF 2012 – Zombie AV

Hack.Lu CTF 2012 - Zombie AV - task description

Diese Challenge (Zombie AV) liefert uns einige PHP-Dateien und nennt das Ziel, den Inhalt der Datei “config.php” auf einer bestimmten Webseite auszulesen. Ohne die PHP-Quellcodes vorher zu betrachten rufen wir zunächst die Webseite auf um uns einen Überblick über die vor uns liegende Aufgabe zu verschaffen.

Hack.Lu CTF 2012 - Zombie AV - virus upload

Es scheint sich um einen online AntiVirus (AV) Scanner zu handeln, dem Dateien übergeben werden können um auf das Vorhandensein von Viren zu prüfen. Wir testen das System probeweise mit einer beliebigen 32bit Binärdatei mit folgendem Ergebnis:

Hack.Lu CTF 2012 - Zombie AV - virus scan

Dem Anschein nach prüft das System den Beginn (ELF Header) des Binarys auf eine bestimmte (Viren-) Signatur. Welche Opcodes hier genau erwartet werden und was für eine Reaktion bei Fund erfolgt, können wir nur erahnen und müssen uns daher nun den PHP-Quellcodes widmen.

Continue reading