Sonntag, 5. Februar 2012


Topthema

Donnerstag, 11. September 2008 | Topthema

About Security #172: Schwachstellen-Suche: SQL-Injection mit Filter

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

Um SQL-Injection zu verhindern, muss man sich nur an den alten Grundsatz "Traue nie dem Client" halten: Alle Benutzereingaben müssen geprüft und gefiltert werden. Welche Möglichkeiten es dafür gibt und wie ein Angreifer die Filter austricksen kann, erfahren Sie in dieser Folge.

Der einfachste Fall: Zahlen

Der einfachste Fall sind Parameter, die nur Zahlen enthalten dürfen. Die Eingaben können dann einfach in Werte aus dem passenden Bereich, z.B. Integer, umgewandelt werden, und eventuell eingeschleuster Schadcode wird eliminiert. Je nach Anwendungsfall muss der sich ergebende Zahlenwert noch auf seine Gültigkeit im Rahmen der Anwendung geprüft werden, um keine unerwünschten Fehlermeldungen zu erzeugen.

Etwas schwieriger: Buchstaben

Auch Parameter, die nur Buchstaben und bestimmte, genau definierte, harmlose Sonderzeichen wie z.B. ein Leerzeichen enthalten dürfen, lassen sich recht einfach prüfen und gegebenenfalls filtern. Über reguläre Ausdrücke kann geprüft werden, ob die Eingabe wirklich nur die gewünschten Zeichen enthält, und alle unerwünschten Zeichen können gelöscht werden.

Gefährlich: Eingaben mit potenziell gefährlichen Sonderzeichen

N E U ! Security aktuell
Täglich aktuelle Security-Infos!

Parameter, die für SQL-Injection verwendbare Sonderzeichen enthalten können, sind schwieriger zu prüfen und zu filtern. Filter, die bestimmte Zeichen löschen oder maskieren, können unter Umständen vom Angreifer ausgetrickst werden. Wie beim Verhindern von Cross-Site-Scripting gilt daher, dass besser eine Positivliste zulässiger Werte verwendet werden sollte. Und ebenso wie für Cross-Site-Scripting gibt es auch für SQL-Injection Cheat-Sheets mit Möglichkeiten, Filter zu umgehen. Die Version von ha.ckers.org enthält zusätzlich eine Kodierfunktion, um ASCII-Text in verschiedene andere Formate umzuwandeln.

Filter umgehen: Erste Beispiele

Wird das einfache Anführungszeichen ' ausgefiltert, verhindert das keine Angriffe in numerische Parameter (About Security #168): Wird der betreffende Parameter für die SQL-Abfrage nicht in ' eingeschlossen, muss der Angreifer auch keine '-Zeichen schließen.

Wird das Kommentarzeichen -- ausgefiltert, mit dem der Angreifer auf seinen eingeschleusten Schadcode folgende Teile der SQL-Abfrage auskommentiert, könnte versucht werden, den eingeschleusten Code so zu formulieren, dass auch ohne Auskommentieren eine gültige SQL-Anweisung entsteht. Statt
nix' or 1=1--
könnte z.B.
nix' or 'a'='a
verwendet werden (About Security #166).

Wird eine einfache Blacklist verwendet, um unerwünschte Schlüsselwörter auszufiltern, reicht oft eine Änderung der Schreibweise oder Codierung, um den Filter zu umgehen. Wird beispielsweise das Schlüsselwort SELECT ausgefiltert, kann stattdessen oft eine Variante wie sElEcT, SELSELECTECT, %53%45%4c%45%43%54 oder %2553%2545%254c%2545%2543%2554 verwendet werden.

Leerzeichen ersetzen

Werden Leerzeichen ausgefiltert, können sie durch Kommentare ersetzt werden. Aus dem Beispiel zur Abfrage der Datenbankversion aus About Security #171,

nix' UNION SELECT NULL, @@version, NULL--

wird dann z.B.

nix'/*bla*/UNION/*bla*/SELECT/*bla*/NULL,/*bla*/@@version,/*bla*/NULL--
About Security: Die komplette Serie

Der SQL-Interpreter behandelt die Kommentare wie Whitespace-Zeichen. In MySQL können Kommentare sogar innerhalb von Schlüsselwörtern verwendet werden - für einen Angreifer eine ideale Möglichkeit, um manche Filter zu umgehen:

nix' UNI/*bla*/ON SELE/*bla*/CT NULL, @@version,NULL--

wird von MySQL genauso ausgeführt wie die nicht verunstaltete Abfrage.

Gefilterte Strings tarnen

Werden von der Webanwendung bestimmte Strings ausgefiltert, die für den SQL-Injection-Angriff benötigt werden, können sie dynamisch in der Abfrage zusammengesetzt werden. Wird der für das letzte Beispiel in About Security #170 benötigte String passwort ausgefiltert, kann er in MySQL z.B. als concat('pas','swort') geschrieben werden. Aus

entwickler.press' UNION SELECT benutzername, passwort, id FROM benutzer--

wird dann

entwickler.press' UNION SELECT benutzername, concat('pas','swort'), id FROM benutzer--

Meist stellen die Datenbanken mehrere Funktionen zur Manipulation von Strings bereit, die alle verwendet werden können, um einen gefilterten String an der Prüffunktion vorbeizuschleusen.

Filter durch dynamische Ausführung unterlaufen

Erlaubt die Datenbank die dynamische Ausführung von SQL-Anweisungen, indem eine Funktion mit einem die SQL-Anweisung darstellenden String aufgerufen wird, können auch darüber Filter umgangen werden. In MS-SQL wird dafür die Funktion exec() verwendet, z.B. so:

exec('select * from benutzer')

In MS-SQL können Strings über + miteinander verbunden werden. Eine Blacklist, die Schlüsselwörter wie SELECT oder unerwünschte Strings wie den Tabellennamen benutzer enthält, könnte also durch Eingabe von exec('se'+'lect * from ben'+'utzer')umgangen werden.

In der nächsten Folge erfahren Sie, wieso das oft zur Verhinderung von SQL-Injection-Angriffe verwendete Escapen von Sonderzeichen wie dem ' nicht zwingend zum Erfolg führt.

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

Folgende Links könnten Sie auch interessieren