0x00sec.dev: Exercise 1
Auf der Seite ctf.0x00sec.org werden CTF Spiele veröffentlicht. Für die erste Aufgabe hier ein writeup.
Challenge
Analyse
Da auf der Seite keine hilfreichen Informationen zu finden sind, wird der Quelltext der Seite untersucht.
Der Kommentar gibt einen Hinweis, an welcher Stelle gesucht werden soll.
</body> <!-- TODO: --> <!-- * Remove the git directory after publishing --> </html>
Bei einem GIT Repository wird per default ein Ordner mit dem Namen “.git” angelegt. Weiterhin wird automatisch eine Struktur erstellt. Ein Versuch “https://exercise-1.0x00sec.dev/.git/” aufzurufen, ergab folgendes:
Die Anzeige der Fehlermeldung ist gut. Warum? Dadurch ist ersichtlich, dass der Ordner “.git” vorhanden ist.
Als nächstes kann jede einzelne Möglichkeit von weiteren Dateien oder Ordnern probiert werden, welche in der Dokumentation von GIT zu finden ist. Manuell macht das aber keinen Spaß. Das Tool “gitdumper” ist für diese Aufgabe perfekt geeignet.
Durchführung
Herunterladen des Tools “gitdumper” und starten.
./gitdumper.sh https://exercise-1.0x00sec.dev/.git/ DEST_FOLDER
Parameter | Beschreibung |
---|---|
DEST_FOLDER | Der Ordnername gibt an, wo die heruntergeladenen Dateien lokal gespeichert werden sollen. |
Die Ausgabe von “gitdumper” stellt sich wie folgt dar:
Mit dem Befehl “tree” kann danach eine übersichtliche Darstellung der heruntergeladenen Daten erzeugt werden.
Die einzelnen Commits werden bei GIT gepackt (ZIP), um Speicherplatz zu sparen. Die relevanten Informationen befinden sich im Ordner “objects”. Für das Entpacken habe ich ein kleines Script geschrieben:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import zlib # A compression / decompression library ROOT_DIR = "/EDIT_ME_PATH_TO_FOLDER/.git/objects/" def readFile(path_to_file): compressed_content = open(path_to_file, 'rb').read() decompressed_content = zlib.decompress(compressed_content) print("--- BOF --- ") print(decompressed_content) print("--- EOF --- ") def main(): for root, subdirs, files in os.walk(ROOT_DIR): for file in files: tmp_file = os.path.join(root, file) print(tmp_file) readFile(tmp_file) if __name__ == "__main__": main()
Das Script gibt die gepackten Daten aus. Zuvor muss die Variable “ROOT_DIR” auf den Ort der heruntergeladenen Daten entsprechend angepasst werden. Daraufhin das Script ausführen:
./zip_to_text.py
Da die Ausgabe etwas unübersichtlich ist, den Befehl erweitern:
./zip_to_text.py | grep Pass
Das sieht doch sehr gut aus. Hier findet ein Vergleich zwischen Username und Passwort statt, wobei das Passwort als SHA256 HASH abgelegt ist.
Den HASH-Wert gilt es zu cracken. Dafür kann eine beliebige Plattform verwendet werden.
Nach einigen Sekunden wurde der Originalwert des HASH (Result) angezeigt. Jetzt sind die Informationen für den Usernamen “admin” und für das Passwort “l33tsupah4x0r” bekannt und der Login kann durchgeführt werden.
Nach der Anmeldung wird das Flag “flag{g1t-dump1ng-i5-c00l}” angezeigt und die Aufgabe ist abgeschlossen.