CInsects/Protokolle/CInsects:Treffen-2010-10-19
Heute haben wir uns überwiegend mit SQL-Injections beschäftigt.
Ablauf
Wir haben erstmal eine kurze Vorstellungsrunde gemacht, wer wir jeweils sind und was unsere Erwartungen an die CInsects sind. Danach haben wir Kleingruppen von 2-3 Leuten gebildet die jeweils welche enthielten, der schon Kenntnisse von SQL hatten und welche die noch keine Vorkenntnisse hatten. In den Kleingruppen wurden dann Grundkenntnisse von SQL nochmal wiederholt. Daraufhin gab es im Plenum kurze Einfuehrung, was SQL-Injections eigentlich sind. Die Hackits wurden dann in Kleingruppen geloest und nach einer Zeit dann immer im Plenum vorgestellt.
SQL-Injections
Algemeines zu SQL
Ein einfacher SQL befehl hat die struktur:
SELECT * FROM tabelle WHERE spalte='text'
mit AND und OR können mehrere bedingungen verknüft werden.
Wenn unsere Datenbank z.B. eine Tabelle user enthält in welcher die Daten zu den Usern gespeichert sind, und der Name des Users in der Spalte 'username' steht, kann man z.B. mit
SELECT * FROM user WHERE username='Bob'
alle verfügbaren Informationen zu Bob abgeruffen werden. Die anführungszeichen um Bob sind ganz wichtig da MySQL es sonst nicht als Zeichenkette sondern als nahmen einer Spalte versteht. Wenn man jetzt noch ein Passwort überprüfen will und als rückgabe nur die ID des Users braucht sieht das so aus:
SELECT userID FROM user WHERE username='Bob' AND password='blub'
Erste Angriffe
Unser erstes Angriffsziel war ein einfaches, ungesichertes Loginscript welches als eingabe den Usernamen und ein Passwort abfragt. Beim Anmeldeversuch wurde, um den angriff zu vereinfachen der verwendete SQL-Befehl angezeigt. Wenn anstat eines Passwortes ein Hochkomma (') eingegeben wurde konnte man gleich sehen das dies zu einem Fehler führt. Das liegt daran das durch die Eingabe im SQL am ende 3 hochkomata sind. Die Zeichenkette des Passwortes geht dann bis zum zweiten ' das einzelne ' am ende ist zuviel und wird nicht wieder geschlossen. Außerdem darf an dieser stelle keine Zeichenkette mehr stehen da sie "Frei im raum" schwebt. Die Kunst des angriffes besteht jetzt darin die Eingabe so zu wählen das dass SQL noch Korrekt ist, uns aber trotzdem einen User zurückliefert so dass wir eingeloggt werden. Am einfachsten ist es am ende einen Wahren vergleich mit OR anzuhängen damit die ganze bedingung wahr wird. Da wir am Ende noch ein ' der Orginalen Abfrage öberhaben ist es am einfachsten z.B. 'a' zu nehmen. Daher geben wir bei Passwort
' OR 'a'='a
ein. Das wird vom Server dann zu
SELECT user_ID FROM user WHERE username=' ' AND passwort=' ' OR 'a'='a'
was immer ein ergebnis zurückgiebt (solange es überhaubt einen User gibt) da a=a immer whar ist, und durch das OR der rest dann egal wird.
Ein weiterer Angriff
Das Formular welches wir für den zweiten Angriffsversuch benutzt haben, sah auf den ersten blick sehr gleich zu unserem Ersten ziel aus. Wenn man daten eingegeben hat (z.B. Bob und Blub) Wird der SQL-Befehl:
SELECT user_ID FROM user WHERE username='Bob' AND passwort='4567RFGHZUr578f6578GFUZI76875edut'
hier können wir sehen das aus dem Passwwort Blub eine verschlüsselte Zeichenkette wird, wir können es also nicht für unseren angriff benutzen. Also muss der Username herhalten. Wenn wir jezt wieder mit dem gleichen Angriff wie bei dem ersten verwenden wollen, gibt es ein problem da am ende noch ein AND steht mit dem passwort dahinter. Jetzt währe es gut wenn wir den rest der Zeile einfach Ignorieren können, dann brauchen wir uns um das ende keine gedanken mehr zu machen. in MySQL bedeutet das zeichen # das der rest der Zeile ein Kommentar ist. Damit können wir einen neuen Angriff formulieren:
' OR 1=1#
Das wird jetzt zu einem SQL befehl:
SELECT user_ID FROM user WHERE username =' ' OR 1=1# ' AND passwort='dr67uue456zre456ugf'
Alles nach dem # wird ignoriert. 1=1 ist immer wahr und da es mit OR verknüpft ist ist die ganze bedingung immer wahr und die Datenbank liefert ergebnisse. wenn wir uns jetzt als ein spezieller User einloggen wollen dann geht es mit:
Bob'#
das wird zu:
SELECT user_ID FROM user WHERE username='Bob' # AND passwort='...'
die ganze bedingung ist also das der username Bob ist, der rest wird ignoriert, wir haben also das Passwort umgangen.
Etwas schweriger
auch hier werde ich die Tage weiterschreiben
UNION SELECT
Schreibe ich die Tage --Nils 21:11, 20. Okt. 2010 (CEST)
Sonstiges
- Der nächste Termin wird noch bekanntgegeben
- Für Kekse ist gesorgt
- Wir werden uns die nächsten paar Wochen mit Websicherheit beschäftigen
- Nächstes mal werden wir Blind SQL-Injection machen
Links
- Testumgebung laueft nur, wenn man vorher 8pridoeh anschreibt.
- SQL Injection Cheat Sheet Tipps und Tricks zu SQL Injections
- Datei:Sqlinj.tar.gz Hackits die wir ausprobiert haben (gruseliger PHP-Code)