Author Archives: Rup0rt

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

PHDays CTF Quals 2012 –
Pwn 400

PHDays CTF 2012 - Pwn 400 - task description

Bei dieser Challenge (Pwn 400) wird ein Server mit Port genannt und der Hinweis gegeben, dass mit der Funktion “Reader()” drei Dateien ausgelesen werden könnten.

Um einen Überblick über die vor uns liegende Aufgabe zu erhalten, verbinden wir uns zunächst mit dem Server und Testen deren Funktionsmöglichkeiten aus:

rup0rt@lambda:~/PHDays2012$ nc ctf.phdays.com 1831
>>> Reader
<function Reader at 0x86a28ec>

>>> Reader("log.1")
<Some ASCII here...>

>>> Reader("flag.txt")
ValueError : You can't read that shit!

Es handelt sich also um eine Python-Schnittstelle (was die drei “>>>” andeuten). Die Funktion “Reader()” listet uns unter Angabe eines Dateinamens deren Inhalt auf. Dabei können jedoch nur die drei Dateinamen angegeben werden, die in der Aufgabenbeschreibung genannt werden. Andere Namen führen zu einer Fehlermeldung.

Um uns nun weiter voran zu arbeiten, untersuchen wir zunächst die Python-Umgebung und die uns zur Verfügung stehenden Funktionen mit der Methode “dir()”:

>>> dir()
['Reader', '__builtins__', '__doc__', '__file__', '__name__',
'__package__', 'a', 'e', 'inp']

>>> dir(__file__)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__',
'__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip',
'swapcase', 'title', 'translate', 'upper', 'zfill']

Wir sehen, dass uns neben der Funktion “Reader()” nicht viel weiteres bereitgestellt wird und auch aus der “file”-Bibliothek die für uns interessanten Funktionen, wie beispielsweise “open()” entfernt wurden. Wir müssen also einen anderen Weg finden, um an die von uns gewünschten Methoden zu gelangen.
Continue reading

PHDays CTF Quals 2012 –
Pwn 300

PHDays CTF 2012 - Pwn 300 - task description

Neben einigen zusätzlichen Informationen wird uns bei dieser Challenge (Pwn 300) die URL eines Webservers genannt, mit dem wir angeblich die Kontrolle über die Stadt South Park erlangen können.

Der Besuch der Webseite liefert uns folgendes Ergebnis:

PHDays CTF 2012 - Pwn 300 - website

Über die Oberfläche haben wir die Möglichkeit ausgewählte Bürger von South Park zu töten, einzusperren oder in den Bankrott zu treiben. Das Ausführen der Handlung führt immer zu einer Bestätigung, dass die Aktion vollzogen wurde. Eine genauere Betrachtung des Quellcodes der Webseite offenbart uns:

PHDays CTF 2012 - Pwn 300 - source code

Wir finden also heraus, wo sich der Schlüssel und somit das Ziel der Challenge befindet, nämlich in der Datei “/etc/passwd”. Über diesen Hinweis wissen nun also auch, dass unser Weg uns irgendwie auf das lokale Dateisystem führen muss – also zum Beispiel über einen “Directory Traversal” oder das Ausnutzes der Webserver-Skripte.
Continue reading

PHDays CTF Quals 2012 –
Misc 200

PHDays CTF 2012 - Misc 200 - task description

Diese Challenge (Misc 200) hat das Ziel, das “braune Quadrat” näher zu untersuchen um darin wohlmöglich weitere Informationen zu finden. Zusätzlich zu dieser Aufgabenbeschreibung erhalten wir eine ZIP-Datei.

Als erstes entpacken wir das Archiv und stellen fest, dass ein GIF-Bild enthalten ist, das sich wie folgt darstellt:

PHDays CTF 2012 - Misc 200 - original GIF image

Zu unserer Überraschung finden wir kein “braunes Quadrat”, sondern nur ein schwarzes. Der Text aus der Aufgabenbeschreibung könnte jedoch ein Hinweis sein, dass Farben bei der Lösung dieser Challenge eine Rolle spielen.

Im Vergleich zu anderen Bildformaten unterscheiden sich GIF-Dateien unter anderem dadurch, dass nicht jeder Pixel für sich eine Farbe erhält, sondern jedem Pixel eine Farbe aus einer vorher definierten Farbtabelle (einer sogenannten colormap) zugeordnet wird.

Wir könnten nun, wie allgemein üblich, das Werkzeug Stegsolve verwenden um einige Untersuchungen an der GIF-Datei durchzuführen und dabei auch die Farbtabellen überprüfen. An dieser Stelle möchte ich jedoch zeigen, wie man auch mit dem Programm GIMP zum Ziel kommen kann.
Continue reading

PoliCTF 2012 – Bin-Pwn 100

Für die “Bin-Pwn 100” Challenge wird uns ein Archiv bereit gestellt sowie die recht simple Aufgabenbeschreibung:

Retrieve the key!

genannt.

Wir arbeiten uns also langsam vor, entpacken als erstes die Datei und sehen uns den Inhalt genauer an:

rup0rt@linux:~/PoliCTF2012$ tar xfvz umad.tar.gz 
jpeg/
jpeg/jconfig.h
jpeg/jpeglib.h
jpeg/jmorecfg.h
jpeg/jerror.h
libjpeg.a
Makefile
umad.cpp

Im Archiv befinden sich Header-Dateien der JPEG-Bibliothek, die statisch kompilierte JPEG-Bibliothek selbst (libjpeg.a) sowie eine C++-Quellcodedatei “umad.cpp” und deren Makefile. Wir kompilieren zunächst den Quellcode mit Hilfe der “Makefile” um so das Verhalten abzuschätzen.

rup0rt@linux:~/PoliCTF2012$ make
g++ -o umad umad.cpp -L. -ljpeg

rup0rt@linux:~/PoliCTF2012$ ./umad 
Done

rup0rt@linux:~/PoliCTF2012$ ls -lh
drwxr-xr-x 2 creeq creeq 4.0K May 26 00:23 jpeg
-rw-r--r-- 1 creeq creeq 1.4M Aug  8 16:11 libjpeg.a
-rw-r--r-- 1 creeq creeq   56 May 26 00:30 Makefile
-rw-r--r-- 1 creeq creeq  13K Nov 21 17:15 out.jpeg
-rwxr-xr-x 1 creeq creeq 422K Nov 21 17:15 umad
-rw-r--r-- 1 creeq creeq 3.3K May 26 10:51 umad.cpp

Anhand der Kompilierungszeile der Makefile erkennen wir, dass sowohl die JPEG-Header-Dateien (-l) als auch die statische JPEG-Library (-L) tatsächlich für die Kompilierung verwendet werden. Die Ausführung des erstellten Programmes “umad” liefert eine weitere Datei “out.jpeg”, die wir uns als nächstes ansehen.

PoliCTF 2012 - Bin-Pwn 100 - library image output

Bis auf die Frage “U MAD ?” ist an diesem Bild nichts besonderes erkennbar. Auch nach binärer Betrachtung scheint es sich um ein herkömmliches JPEG-Bild zu handeln. Das Betrachten des C++-Quellcodes sowie der Header-Dateien lässt uns ebenfalls keine besonderen Auffälligkeiten vorfinden.
Continue reading

CScamp 2012 Quals – Misc 200

CScamp CTF 2012 - Misc 200 - task description

Neben dieser Aufgabenstellung zur Challenge “Misc 200” – “Bilder laden um Türen zu öffnen” – wird uns eine ZIP-Datei übergeben. Diese entpacken wir zunächst einmal und sehen uns an, womit wir es bei dieser Challenge genau zu tun haben.

CScamp CTF 2012 - Misc 200 - binary layout and file drop

Das Archiv beinhaltet viele Dateien von denen die Datei “drop.exe” als das Hauptprogramm der Challenge ins Auge fällt. Der Aufruf dieses Binarys lässt ein Fenster erscheinen, das über einen großen Button “Load” Bilder annimmt und an dessen Unterkante sich zehn Radiobuttons befinden, die vom Benutzer durch Klicken verändert werden können.

Das testweise Laden beliebiger Bilder führt zunächst zu keinem sichtbaren Ergebnis. Man erkennt jedoch, dass das Programm arbeitet – nicht zuletzt, da im Verzeichnis kurzzeitig temporäre Dateien erscheinen. Eine genauere Überprüfung des Verhaltens mit dem Werkzeug “procmon” aus der Sysinternals Suite liefert:

CScamp CTF 2012 - Misc 200 - procmon output

Demnach wird nach dem Laden des Bildes das Programm “dontdelete.exe” mit den Parametern “temp.bmp temp” ausgeführt sowie im weiteren Verlauf auf die Datei “temp.txt” zugegriffen. Es wird Zeit, sich die anderen Dateien des Archives – hier insbesondere die Datei “dontdelete.exe” – genauer anzusehen.
Continue reading

CScamp 2012 Quals – Crypt 300

CScamp CTF 2012 - Crypt 300 - task description

Bei dieser Challenge (Crypt 300) sollen wir den originalen Schlüssel zu einem Schlüsseltext bestimmen. Wir erhalten dazu das Verschlüsselungsprogramm, ein Linux 64bit Binary, die Information, dass der Schlüssel alphanumerisch sowie 11 Zeichen lang ist, den Schlüsseltext “7f e7 ff ce 0 98 15 dd 88 fb 6e” und die CRC-XMODEM Prüfsumme 0x8124 des Originalschlüssels.

Zunächst einmal sehen wir uns die Binary genauer an um die Aufgabe etwas besser fassen und das Ziel näher bestimmen zu können:

rup0rt@linux64:~$ ./crypt 111
your encrypted key is : ff ff ff 0 0 0 0 0 0 0 0 
rup0rt@linux64:~$ ./crypt 123456
your encrypted key is : ff 86 89 d3 89 27 0 0 0 0 0 
rup0rt@linux64:~$ ./crypt A A A 
your encrypted key is : 8f 0 0 0 0 0 0 0 0 0 0

Auf den ersten Blick sieht es so aus, dass das crypt-Tool einen Parameter übernimmt, diesen zeichenweise auswertet, dabei das entsprechende Zeichen verschlüsselt und den verschlüsselten Key ausgibt. Wir müssen es demnach schaffen, den originalen Schlüssel (Übergabeparameter) zu finden bzw. so zu wählen, dass der von der Aufgabe geforderte Cipher “7f e7 ff ce 0 98 15 dd 88 fb 6e” entsteht.

Um dies zu erreichen Schreiben wir ein (hier zugegeben sehr unsauberes) Python-Skript, dass den Schlüssel per Brute Force bestimmt:

#!/usr/bin/python

import commands
import re

chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

for c1 in chars:
 if re.match(".* : 7f.*", commands.getoutput("./crypt " + c1)):
  for c2 in chars:
   if re.match(".* : 7f e7.*", commands.getoutput("./crypt " + c1 + c2)):
    for c3 in chars:
     if re.match(".* : 7f e7 ff.*", commands.getoutput("./crypt " + c1 + c2 + c3)):
      for c4 in chars:
       if re.match(".* : 7f e7 ff ce.*", commands.getoutput("./crypt " +c1+c2+c3+c4)):
        for c5 in chars:
         if re.match(".* : 7f e7 ff ce 0.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5)):
          for c6 in chars:
           if re.match(".* : 7f e7 ff ce 0 98.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5+c6)):
            for c7 in chars:
             if re.match(".* : 7f e7 ff ce 0 98 15.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5+c6+c7)):
              for c8 in chars:
               if re.match(".* : 7f e7 ff ce 0 98 15 dd.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5+c6+c7+c8)):
                for c9 in chars:
                 if re.match(".* : 7f e7 ff ce 0 98 15 dd 88.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5+c6+c7+c8+c9)):
                  for c10 in chars:
                   if re.match(".* : 7f e7 ff ce 0 98 15 dd 88 fb.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5+c6+c7+c8+c9+c10)):
                    for c11 in chars:
                     if re.match(".* : 7f e7 ff ce 0 98 15 dd 88 fb 6e.*", commands.getoutput("./crypt " +c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+c11)):
                      print c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+c11

Continue reading

CScamp 2012 Quals – Web 300

CScamp CTF 2012 - Web 300 - puzzle image website

Bei dieser Challenge (Web 300) ist das eigentliche Ziel sehr schnell klar. Es existiert ein Bild, deren Teile verwürfelt sind, und die von uns innerhalb von zwei Sekunden in die richtige Reihenfolge gebracht werden müssen. Da es sehr schwer werden wird, das Bild innerhalb von zwei Sekunden per Hand zu sortieren und das Ergebnis einzugeben, bleibt uns nur der Weg, eine automatisierte Lösung per Skript zu entwickeln.

Dabei wird es erforderlich sein, jedes der zwölf Quadrate eindeutig zu identifizieren. Zur Umsetzung habe ich mir daher überlegt, aus jedem Quadrat die Farben (Rot – Grün – Blau) von vier Pixeln aus den Eckbereichen zu entnehmen und darüber eine Art “Fingerabdruck” jedes Quadrates zu erhalten – hier vereinfacht dargestellt ;-).

CScamp CTF 2012 - Web 300 - identifying puzzle pieces by pixel

Bei der Umsetzung hat sich jedoch das Problem ergeben, dass – wohlmöglich durch die jeweils erneute JPEG-Umwandlung – die Farben der Pixel sich immer (minimal) unterscheiden. Als Umweg werden wir daher nur festhalten, ob sich viel oder wenig Rot-/Grün-/Blau-Töne in den Pixeln befinden und so eine eindeute Zuordnung der Quadrate realisieren.

Um den Server nicht unnötig mit Anfragen zu beschäftigen, nutzen wir hier zwei Skripte. Ein Bash-Skript zur Kommunikation mit dem Server sowie ein Python-Skript zur Sortierung des Bildes. Somit kann die Sortierung an ein- und demselben Bild wiederholt durchgeführt werden um die korrekte Funktion des Sortieralgorithmus zu testen.
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