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