Defcon 20 CTF Prequals 2012 –
Grab Bag 400

Bei der “Grab Bag 400) – Challenge wird uns ein Webserver genannt und folgende Frage gestellt:

“What is Jeff Moss’ checking account balance?”

Wir sollen demnach den Kontostand von “Jeff Moss”, dem Defcon-Gründer, in Erfahrung bringen. Zuerst besuchen wir also die Webseite und verschaffen uns einen Überblick.

Defcon 20 CTF 2012 - Grab Bag 400 - website

Es handelt sich um die Webseite der “Bank of America”, die uns unter der Domain “boabank.com” vorgestellt wird. Nach einem kurzen Überfliegen der Links (von denen es nicht viele gibt), sticht schon das Suchfeld im rechten Bereich der Webseite ins Auge.

Hier kann man nach BoaBank-Filialen in seiner Nähe durch Eingabe der Postleitzahl suchen. Bereits die Eingabe einer Zeichenkette, die nicht aus Zahlen besteht, führt schon zu der Fehlermeldung:

“ERROR: column … does not exist Position: 55”

Dabei handelt es sich um eine Fehlermeldung des Datenbanksystems PostgreSQL. Dass der Fehler ohne die Eingabe von (einfachen oder doppelten) Anführungszeichen ausgelöst wird, lässt vermuten, dass der Wert der Postleitzahl ebenfalls ohne Anführungszeichen direkt an die Datenbank-Abfrage weitergegeben wird. Eine mögliche Anfrage könnte daher wie folgt aussehen:

SELECT ... FROM ... WHERE zip = $_POST['zip'];

Um diese Vermutung zu überprüfen und beispielsweise alle Filialen beliebiger Postleitzahl auszugeben, trage ich in das Suchfeld “1234 OR 1=1” ein, und erhalte folgendes Ergebnis:

Defcon 20 CTF 2012 - Grab Bag 400 - sql injection

Da wir tatsächliche alle Filialen aufgelistet bekommen, können wir nun sicher sein, dass das Suchfeld für klassische SQL-Injections anfällig ist. Der nächste Schritt besteht darin, mehr Informationen über das Datanbanksystem und die verwendete Datenbank selbst in Erfahrung zu bringen.

Dazu bietet PostgreSQL die Funktion “version()” an, die wir mit einem UNION-Statement so verbinden können, dass die Ausgabe der Filialen zusammen mit der Version angezeigt wird. Um das zu erreichen müssen wir jedoch die genaue Anzahl von Spalten kennen, die von dem originalen SELECT-Statement verwendet werden um die Filialen auszugeben. Da wir gerade sechs Spalten ausgegeben bekommen haben, vermute ich, dass auch nur sechs Werte abgefragt wurden und trage nun “1234 UNION SELECT version(), ‘1’, ‘2’, ‘3’, ‘4’, ‘5’” in das Suchfeld ein, worauf hin folgendes Ergebnis erscheint:

Defcon 20 CTF 2012 - Grab Bag 400 - sql injection union select preparation

Es handelt sich also um PostgreSQL in der Version 8.4.11, die auf einem 32bit-Debian-System betrieben wird. Nun sollten wir den Namen der derzeitigen Datenbank in Erfahrung bringen um uns dem Konto von Jeff Moss zu nähern. Dazu verwenden wir die PostgreSQL-Funktion “current_database()”, tragen “1234 UNION SELECT current_database(), ‘1’, ‘2’, ‘3’, ‘4’, ‘5’” in das Suchfeld ein und erhalten:

Defcon 20 CTF 2012 - Grab Bag 400 - sql injection database name

Die derzeitige Datenbank heißt demnach “boa_bank”. Um trotzdem nichts zu übersehen schauen wir uns zusätzlich auch noch die weiteren Datenbanken an, die auf dem PostgreSQL-Server eingerichtet sind. Dazu fragen wir die Tabelle “datname” aus der, auf jedem PostgreSQL-Server vorhandenen Datenbank “pg_database” ab. Der Eintrag lautet “1234 UNION SELECT datname, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’ FROM pg_database” und liefert:

Defcon 20 CTF 2012 - Grab Bag 400 - sql injection list all databases

Weitere für uns interessante und zur Lösung der Challenge benötigte Datenbanken scheint es also nicht zu geben. Wir konzentrieren uns daher weiter auf die Datenbank “boa_bank”, aus der wir nun alle Tabellen und Spaltennamen enumerieren wollen. Dies tun wir – gemäß dem PostgreSQL-Injection-Handbuch 😉 – mit der Abfrage:

1111 UNION SELECT relname, A.attname,'2','3','4','5' FROM pg_class C, pg_namespace N, pg_attribute A, pg_type T WHERE (C.relkind='r') AND (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE 'public')

und erhalten:

Defcon 20 CTF 2012 - Grab Bag 400 - sql injection table names

Damit sehen wir alle Tabellennamen (links) sowie deren zugeordnete Spaltennamen (rechts) der derzeitigen Datenbank “boa_bank”. Für uns scheint die Tabelle “customer” besonders interessant zu sein, weshalb wir sie mit der Suchanfrage “1111 UNION SELECT username, password, firstname,lastname,’4′,’5′ FROM customer” nun näher beleuchten.

Defcon 20 CTF 2012 - Grab Bag 400 - sql injection all entries

Perfekt! Wir erhalten eine vollständige Übersicht aller Kunden der Bank. Nur leider ist kein “Jeff Moss” darunter – einzig und alleine eine “Trinity Moss” ist Kundin der BoaBank. Eine kurze Suche bei Google bringt uns jedoch zu der Erkenntnis, dass Jeff Moss, den Nicknamen “The Dark Tangent” führt und unter dem Namen “Dark Tangent” (Benutzername “dtangent”) auch tatsächlich ein Kunde mit dem Passwort “erl)<qZsxZ” vorzufinden ist.

Defcon 20 CTF 2012 - Grab Bag 400 - login with extracted credentials

Der Login funktioniert einwandfrei und wir können den Kontostand ganz unproblematisch ablesen.

Defcon 20 CTF 2012 - Grab Bag 400 - solution

Die Antwort dieser, meiner Meinung nach viel zu einfachen und mit 400 Punkten viel zu hoch honorierten Challenge, lautet daher “0.00“.

Leave a Reply

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