Diese Challenge (ImageUpload) erzählt uns von einer Website, auf der man Bilder hochladen kann um dem Scheriff bei der Verbrechenjagd zu unterstützen. Als erstes sehen wir uns diese Webseite etwas genauer an.
Die Seite ist sehr klein und übersichtlich. Es gibt eine Möglichkeit sich anzumelden, mit der wir – wegen Abfrage von Benutzernamen und Password – zunächst nichts anfangen können. Des Weiteren lassen sich offensichtlich Bilder hochladen. Diese Möglichkeit nutzen wir für ein Testbild.
Nach dem Hochladen sehen wir das Bild auf der Webseite. Zusätzlich wurden am unteren Ende des Bildes Daten angefügt. Bei diesen Daten handelt es sich vermutlich um Exchangeable Image File Format (EXIF) Daten, die aus dem Bild selbst ausgelesen wurden. Da mein Bild keine Daten enthielt, sind die Felder leer.
Wir verwenden nun das Werkzeug “exiftool” um beim Bild testweise das “Manufacturer” (MAKE) Feld zu befüllen.
rup0rt@lambda:~$ exiftool -MAKE="f00l.de" f00l.jpg 1 image files updated
Anschließend laden wir das Bild erneut hoch und beobachten das Ergebnis.
Die eingefügten Daten werden also tatsächlich ausgelesen und auf der Webseite dargestellt. Wie kann man nun aber an weitere Daten, zum Beispiel Anmeldeinformationen für die Webseite gelangen? Dazu sollte die Möglichkeit einer SQL-Injektion geprüft werden.
Zur Realisierung sollte man sich überlegen, wie die Bilddaten wohl von der Webseite behandelt werden. Vermutlich werden alle Felder beim Hochladen des Bildes ausgelesen und in die Datenbank eingefügt. Eine entsprechende SQL-Abfrage im PHP-Code könnte also zum Beispiel wie folgt aussehen:
INSERT INTO pictures SET (width, height, author, manufacturer, model) VALUES ( '$width', '$height', '$author', '$manu', '$model');
Um nun über den Wert “Manufacturer” per SQL testweise auf das Modell zu überschreiben, könnte man folgenden Wert verwenden:
MANUFACTUERER', 'MODEL'); --
Dies testen wir wieder mit dem Werkzeug “exiftool”:
rup0rt@lambda:~$ exiftool -MAKE="f00l.de', 'rup0rt') -- " f00l.jpg
1 image files updated
Im Ergebnis erhalten wir:
Die Daten wurden eingefügt! Wir können also die Datenbank mit frei wählbaren Inhalten manipulieren. Um nun Inhalte zu extrahieren, nutzen wir eine ähnliche Abfrage und fügen in das Modell-Feld per SELECT Inhalte der Datenbank ein. Als erstes interessiert uns, welche Tabellen existieren.
Dazu muss aus der Datenbank “information_schema” die Tabelle “table_name” ausgelesen werden. Da das Modell-Feld nur eine Zeichenkette beinhalten kann, fügen wir alle Ergebnisse der Abfrage mittels “GROUP_CONCAT” zu einem String zusammen. Die finalen EXIF-Daten sehen wie folgt aus:
rup0rt@lambda:~$ exiftool -MAKE="f00l.de', (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema' ) ) -- " f00l.jpg 1 image files updated
Nach dem Hochladen des Bildes, erhalten wir dieses Ergebnis:
Demnach existieren zwei Tabellen: “pictures” und “users”. Um sich auf der Seite anmelden zu können, scheint die Tabelle “users” am interessantesten zu sein. Nun benötigen wir die Namen der Spalten um gezielt Benutzerdaten abfragen zu können. Analog nutzen wir also wieder die EXIF-Daten:
rup0rt@quebec:~$ exiftool -MAKE="f00l.de', (SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'users' ) ) -- " f00l.jpg 1 image files updated
Hiernach erhalten wir diese Ausgabe:
Die Tabelle “users” beinhaltet also die Spalten “id”, “name” und “password”. Nun wiederholen wir diese Abfrage für die Benutzernamen sowie Passwörter mit folgenden Manipulationen:
rup0rt@lambda:~$ exiftool -MAKE="f00l.de', (SELECT GROUP_CONCAT(name) FROM users ) ) -- " f00l.jpg 1 image files updated rup0rt@lambda:~$ exiftool -MAKE="f00l.de', (SELECT GROUP_CONCAT(password) FROM users ) ) -- " f00l.jpg 1 image files updated
Damit erhalten wir diese Informationen:
Damnach existieren zwei Benutzer:
- sheriff : AO7eikkOCucCFJOyyaaQ
- deputy : testpw
Wir nutzen natürlich das Konto des Scheriffs und versuchen uns mit seinem Passwort auf der Login-Seite anzumelden. Mit folgendem Ergebnis:
Die Lösung lautet somit “flag{1_5h07_7h3_5h3r1ff}“.
Thank you so much.. It helped me alot 🙂 Really happy to see ur website 🙂