CInsects/Protokolle/CInsects:Treffen-2010-10-19

Aus Fachschaft_Informatik
Zur Navigation springen Zur Suche springen

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

Im dritten Beispiel, welches wir, verwendet haben, hatte eine weitere Schwierigkeit: Das SQL Kommando geht über mehrere Zeilen, so das man nicht einfach den Rest der Zeile auskommentieren konnte. Man musste also etwas einfügen und darauf achten das das gesammte Kommando noch Syntaktisch richtig ist.

   ' OR 1=1 OR ' '='

ist ein möglicher angriffsstring.

UNION SELECT

Mit UNION SELECT lassen sich die daten eines 2. SELECTS an das erste anhängen. Das wichtige dabei ist dass beim 1. und 2. Select gleich viele Zeilen ausgewählt werden. Zum beispiel also:


  SELECT user_ID, name FROM user WHERE name='Alice' UNION SELECT name, passwort FROM admin # AND passwort.... (rest des orginalen Strings)

An diesem Beispiel kann man wieder sehen das über eine ähnliche Lücke wie bei den vorherigen Beispielen angegriffen wurde. Mithilfe der Strukturtabellen von MySQL kann man darüber auch die Struktur der anderen Tabellen abgeruffen werden. Dann lautet der Angriffsstring:

 Bob' UNION SELECT column_name,table_name FROM INFORMATION_SCHEMA.columns

wird zu dem Befehl:


 SELECT user_ID, name FROM user WHERE name='Bob' UNION SELECT column_name,table_name FROM INFORMATION_SCHEMA.columns

und gibt die spalten zu allen Tabellen die es gibt aus. ACHTUNG: die tabellen können sich in anderen Datenbanken befinden, dann muss anders darauf zugegriffen werden. Auch die Datenbank lässt sich über das INFORMATION_SCHEMA ermitteln.

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