Dienstag, 9. November 2010


Topthema

Donnerstag, 2. Oktober 2008 | Topthema

About Security #175: Schwachstellen-Suche: Blind SQL-Injection

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/045382)

Blind SQL-Injection, manchmal auch als semantikbasierte SQL-Injection bezeichnet, funktioniert genau anders herum als normale SQL-Injection: Während bei einem herkömmlichen SQL-Injection-Angriff die Bedeutung der vorhandenen SQL-Abfrage geändert wird, bleibt sie bei einer Blind SQL-Injection erhalten, lediglich ihr Inhalt wird geändert. Wie das funktioniert und was ein Angreifer damit erreichen kann, erfahren Sie in dieser Folge.

Voraussetzungen

Voraussetzung für Blind SQL-Injection ist, das der Angreifer erkennen kann, ob die eingeschleuste Abfrage korrekt war oder nicht. Dafür reicht es aus, wenn bei einem Fehler eine Standard-Fehlerseite ausgegeben wird, weitergehende Informationen sind nicht notwendig. Wenn der Angreifer zwischen einer richtigen und einer falschen Eingabe unterscheiden kann, kann er der Webanwendung ja/nein- bzw. true/false-Fragen stellen und so z.B. erst die Namen der benutzerdefinierten Tabellen und danach deren Inhalte abfragen. Und das auch dann, wenn das Ergebnis des eingeschleusten SQL-Codes nicht in der Ausgabe erscheint, z.B. weil es ausgefiltert wird.

Ein Beispiel

Security aktuell
T�glich aktuelle Security-Infos!

Für einen Blind SQL-Injection-Angriff werden SQL-Abfragen verwendet, die trotz unterschiedlichem Aufbau zu identischen Ergebnissen führen. Am einfachsten ist das anhand mathematischer Ausdrücke zu sehen. Als Beispiel soll ein Online-Katalog dienen, bei dem die einzelnen Produkte über eine ID ausgewählt werden:

http//www.webshop.example/katalog.cgi?artikel=$artikelnummer

Eine gültige Artikelnummer soll z.B. 12 sein:

http//www.webshop.example/katalog.cgi?artikel=12

liefert dementsprechend eine Artikelbeschreibung. 12 kann auch auf anderen Wegen dargestellt werden. Ist SQL-Injection möglich, ergeben folgende URL alle das gleiche Ergebnis wie die ursprüngliche URL:

http//www.webshop.example/katalog.cgi?artikel=10%2b2
http//www.webshop.example/katalog.cgi?artikel=MOD(12,13)
http//www.webshop.example/katalog.cgi?artikel=0x0C

10%2b2 entspricht 10+2, da ein + in der URL ein Leerzeichen darstellt, muss es URL-kodiert eingegeben werden, damit die Webanwendung es als + erhält (siehe About Security #168), MOD(12,13) gibt das Ergebnis von 12 modulo 13 zurück, und 0x0C ist die Hexadezimale Darstellung von 12.

Werden entsprechende Werte bei der Suche nach einer SQL-Injection-Schwachstelle eingegeben, muss in der Ausgabe nicht nach einer Fehlermeldung, sondern nach zwei Eingaben mit identischer Ausgabe gesucht werden.

Schön - Und wie geht es weiter?

Es ist also möglich, eine bestimmte Katalogseite über verschiedene URL aufzurufen, aber das ist für einen Angreifer ziemlich uninteressant, der möchte ja zumindest für ihn eigentlich nicht zugängliche Daten abrufen. Dafür ist ein bisschen mehr nötig, als 12 durch 10%2b2 oder MOD(12,13) zu ersetzen.

About Security: Die komplette Serie

Wir wissen, das SQL-Injection möglich ist, nur wird das Ergebnis nicht ausgegeben, sondern vorher ausgefiltert. Das einzige, was der Angreifer erkennen kann, ist der Erfolg oder Misserfolg der SQL-Abfrage: Entweder die entsprechende Artikelbeschreibung wird ausgegeben, oder es erscheint eine allgemeine Fehlermeldung wie z.B. "Diesen Artikel gibt es leider nicht". Wenn schon nur ja/nein-Antworten gegeben werden, sollte man es vielleicht mal mit einfachen ja/nein-Fragen probieren, bzw. mit true/false-Fragen:

Wenn für die $artikelnummer

12 AND 1=1

die Artikelbeschreibung und für

12 AND 1=2

die Fehlermeldung ausgegeben wird, hilft das auf den ersten Blick auch nicht viel weiter. Aber wer sagt denn, das da nur 1=1 angehängt werden kann? Wie wäre es mit einer etwas komplizierteren Abfrage? Die vom Benutzer definierten Datenbanktabellen werden in der Tabelle sysobjects gespeichert. Die Namen der Tabellen braucht der Angreifer, um später darauf zugreifen zu können. Einfach den Namen abfragen ist nicht möglich, da die Antwort dann nicht true oder false ist. Stattdessen können aber einzelne Buchstaben abgefragt werden:

(SELECT TOP 1 name FROM sysobjects WHRERE xtype='U')

liefert den Namen der ersten vom Benutzer definierten Tabelle,

SUBSTRING(SELECT TOP 1 name FROM sysobjects WHRERE xtype='U'),1,1)

liefert den ersten Buchstaben davon und

ASCII(SUBSTRING(SELECT TOP 1 name FROM sysobjects WHRERE xtype='U'),1,1))

dessen ASCII-Wert (siehe auch About Security #174).

Liefert

http//www.webshop.example/katalog.cgi?artikel=12 AND 
ASCII(SUBSTRING(SELECT TOP 1 name FROM sysobjects WHRERE xtype='U'),1,1)) = 65

die Artikelbeschreibung, ist der erste Buchstabe des Namens der ersten vom Benutzer definierten Tabelle ein A, gibt es eine Fehlermeldung, ist es ein anderer Buchstabe. Je nach Ergebnis probiert man das nun mit einem B oder mit dem zweiten Buchstaben. So können nach und nach alle Tabellennamen ermittelt werden, danach die Spaltennamen und dann die darin gespeicherten Daten. Das ist zwar eine sehr mühsame Arbeit - aber wozu gibt es denn Computer? Ein Programm, das 'Blind SQL-Injection'-Schwachstellen ausnutzen kann, um Schema und Inhalt einer betroffenen Datenbank zu ermitteln, ist z.B. Absinthe.

Ein weiteres Beispiel

Betrachten wir noch einmal das Beispiel zur Authentifizierung aus About Security #167:

SELECT * FROM Benutzer WHERE Benutzername = '$name' AND Passwort = '$pass'

Das Ergebnis dieser SQL-Abfrage wird nicht ausgegeben, aber je nach Eingaben reagiert die Anwendung unterschiedlich: Bei Eingabe von

admin' AND 1=1--

als Benutzername wird der Angreifer als Administrator angemeldet, bei der Eingabe von

admin' AND 1=2--

schlägt die Anmeldung fehlt, da 1=2 immer false ist.

Genau wie beim obigen Beispiel können nun über true/false-Fragen Tabellen- und Spaltennamen sowie die Inhalte der Tabelle ausgespäht werden.

In der nächsten Folge werden mögliche Gegenmaßnahmen gegen SQL-Injection-Angriffe beschrieben.

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 Torsten 29.10.2009
um 09:25 Uhr
Hehe, genau so ein Problem hatte ich!

Ich habe jetzt '%20' in der URL per httaccess verboten.
#zitieren
Gravatar bla 08.11.2009
um 15:23 Uhr
@Torsten, nur leider kann man das '%20' durch '/**/' oder auch '+' ersetzen ;) #zitieren

Folgende Links könnten Sie auch interessieren