Mittwoch, 23. November 2011


Topthema

Mittwoch, 24. September 2008 | Topthema

About Security #174: Schwachstellen-Suche: SQL-Injection 2. Ordnung

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/045287)
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share

Außer den bisher beschriebenen SQL-Injection-Angriffen gibt es weitere Möglichkeiten, wie ein Angreifer seinen SQL-Code an die Datenbank schicken kann. Eine solche Möglichkeit ist die SQL-Injection 2. Ordnung, die in dieser Folge beschrieben wird.

To Escape or not to Escape

Wie bereits in den vorherigen Folgen zu sehen war, müssen einfache Anführungszeichen maskiert werden, wenn sie als Bestandteil der Eingabe benötigt werden. Es spricht also nichts dagegen, alle einfachen Anführungszeichen in der Eingabe zu verdoppeln. Das kann unter Umständen aber zu Problemen führen, wenn die gleichen Daten in mehreren SQL-Abfragen verwendet und dabei erst in die Datenbank geschrieben und danach draus gelesen werden. Das lässt sich am einfachsten an einem Beispiel verdeutlichen. Dazu soll die SQL-Anweisung zur Registrierung eines Benutzers dienen, die in About Security #169 beschrieben wurde:

INSERT INTO benutzer (name,    passwort, ID,  admin)
              VALUES ('$name', '$pass',  $id, $admin)

Meldet sich ein Benutzer mit dem Benutzernamen test'sql an, wird das Anführungszeichen verdoppelt, um es als solches zu maskieren. Die sich ergebende SQL-Anweisung lautet also

INSERT INTO benutzer (name,         passwort, ID,  admin)
              VALUES ('test''sql', 'g3he1m', 123, 'n')

Security aktuell
T�glich aktuelle Security-Infos!

Diese Anweisung ist korrekt und die Daten werden in der Datenbank gespeichert. Die Änderung des Passworts ist nur nach erfolgreicher Authentifizierung möglich, aus Sicherheitsgründen muss dabei aber auch das bisherige Passwort erneut eingegeben werden. Um eingegebenes und gespeichertes Passwort miteinander zu vergleichen, fragt die Webanwendung zuerst den Benutzernamen in der Datenbank ab:

SELECT name FROM benutzer WHERE ID = 123

liefert test'sql. Die doppelten Anführungszeichen werden nur für das Eintragen des Parameters in die Datenbank verwendet, gespeichert wird der eigentlich eingegebene String. Danach wird das Passwort für den so ermittelten Benutzernamen abgefragt:

SELECT passwort FROM benutzer WHERE name = 'test'sql'

Dadurch, das die Webanwendung den in der Datenbank gespeicherten String in einer weiteren SQL-Abfrage verwendet, wird SQL-Injection möglich: Gibt der Angreifer bei der Registrierung SQL-Code als Teil des Benutzernamens ein, wird er zwar nicht beim Eintragen in die Datenbank ausgeführt, dafür aber beim Ändern des Passworts. Zugegeben, dieses Beispiel ist sehr konstruiert, i.d.R. wird man die Abfrage von Benutzername und Passwort wie im Beispiel in About Security #169 beschrieben in einer SQL-Abfrage zusammenfassen, es zeigt aber das grundsätzliche Problem der SQL-Injection 2. Ordnung: Der Angreifer spielt sozusagen über Bande - der Schadcode wird nicht direkt nach der Eingabe ausgeführt, sondern erst später.

SQL-Injection für Fortgeschrittene

Bisher wurden Angriffe beschrieben, bei denen die Daten direkt ausgegeben wurden, z.B. indem sie über den UNION-Operator an eine vorhandene Abfrage und damit die zugehörige Ausgabe angehängt wurden. Wie in About Security #171 zu sehen war, reicht es dafür aus, das in der Ausgabe der Datentyp einer einzigen Spalte String ist. Aber auch wenn nur numerische Werte zurück geliefert werden, können darüber Daten ausgespäht werden. Sie müssen lediglich in numerische Daten umgewandelt werden. Dazu werden im wesentlichen zwei Funktionen verwendet:

  • SUBSTRING() liefert einen Teilstring der Eingabe
  • ASCII() liefert den ASCII-Code eines eingegebenen Zeichens, also einen numerischen Wert

Beide Funktionen zusammen können verwendet werden, um ein einzelnes Zeichen aus einem String in einen numerischen Wert umzuwandeln:

SUBSTRING('abcde',1,1) liefert a
ASCII('a') liefert 97
und
ASCII(SUBSTRING('abcde',1,1)) liefert demnach ebenfalls 97.

About Security: Die komplette Serie

Der Angreifer kann so einen String in einzelne Zeichen zerlegen und die wiederum als numerische Werte ausgeben. Das lässt sich auch über ein Skript automatisieren, was die Verarbeitungsgeschwindigkeit deutlich erhöht.

Indirekte Ausgabe

Werden die Zahlen nicht direkt ausgegeben, sondern als Identifier für weitere Daten verwendet, kann der Angreifer zuerst für alle zu erwartenden Werte die entsprechenden Daten abfragen und dann darüber die später ausgegebenen Zahlen identifizieren. Werden die Zahlen z.B. verwendet, um Profile einer Benutzerdatenbank auszugeben, könnte das so aussehen: Die Ausgabe für die ID 97 ist das Profil von Max Mustermann, dementsprechend bedeutet später im Rahmen des Angriffs die Ausgabe des Profils von Max Mustermann, das ein a ausgegeben wurde.

SQL-Injection ohne direkte Ausgabe

SQL-Injection ist auch dann möglich, wenn das Ergebnis des eingeschleusten SQL-Codes nicht ausgegeben wird Der einfachste Fall ist das Umgehen der Authentifizierung, wie es in About Security #167 beschrieben wurde: Das Ergebnis der SQL-Abfrage ist dem Angreifer egal, ihn interessiert nur, das er danach angemeldet ist. Weiter gehende Angriffe, die ohne Ausgabe des Ergebnisses auskommen, werden als Blind SQL-Injection bezeichnet. Was es damit auf sich hat, erfahren Sie in der nächsten Folge.

Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!

Carsten Eilers

About Security - Übersicht zum aktuellen Thema:

Kommentare

Gravatar Dave84620 29.09.2008
um 15:51 Uhr
Finde die Themen super! Nur was ist, wenn Escaping nicht mit einem doppelten Hochkomma, sondern mit einem vorgestellten Backslash realisiert wird, wie es bei PHP der Fall ist?Gr��e und weiter so! #zitieren
Gravatar Jammer 30.09.2008
um 14:28 Uhr
Weiter so, find ich auch gut! #zitieren
Gravatar Carsten Eilers 01.10.2008
um 14:31 Uhr
Hallo,

vielen Dank!


Dave84620:
Finde die Themen super! Nur was ist, wenn Escaping nicht mit einem doppelten Hochkomma, sondern mit einem vorgestellten Backslash realisiert wird, wie es bei PHP der Fall ist?Gr��e und weiter so!


Es kommt nur darauf an, was in der Datenbank gespeichert wird.

Wird das Escape-Zeichen nicht mit gespeichert, ist der beschriebene Angriff m�glich. Wie das Escape-Zeichen aussieht, ist dann egal.

Das Escape-Zeichen ist nur von Bedeutung, wenn es mit gespeichert wird. Dann kommt es darauf an, wie die aus der Datenbank gelesenen Daten vor der neuen SQL-Abfrage bearbeitet werden. Werden die Escape-Zeichen entfernt, ist wieder SQL-Injection m�glich. �blicher ist es in so einem Fall aber, den String unver�ndert f�r die neue Abfrage zu verwenden, und dann kann nichts passieren.

MfG
Carsten Eilers
#zitieren

Folgende Links könnten Sie auch interessieren