Dienstag, 2. Dezember 2008

News

präsentiert von: entwickler.com
Donnerstag, 4. September 2008

About Security #171: Schwachstellen-Suche: SQL-Injection mit UNION (2)

Die Verwendung des in About Security #170 vorgestellten UNION-Operators ist an zwei Voraussetzungen geknüpft. Welche das sind und wie ein Angreifer erreichen kann, dass sie erfüllt sind, erfahren Sie in dieser Folge.

Voraussetzungen

Bei der Verwendung des UNION-Operators müssen zwei Voraussetzungen erfüllt sein:

  1. Um überhaupt mit einer weiteren Abfrage auf Daten zugreifen zu können, muss der Angreifer die Namen der Datenbanktabelle und ihrer Spalten kennen. Die verraten ihm die Fehlermeldungen der Datenbank oder ein Angriff auf die Systemtabellen, in denen diese Informationen gespeichert sind (siehe unten).
  2. Die Ergebnisse alle Abfragen müssen die gleiche Struktur, d.h. die gleiche Anzahl Spalten mit den gleichen oder kompatiblen Datentypen in der gleichen Reihenfolge, haben.
Struktur der Abfrage ermitteln

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

Die Struktur der Abfrage erfährt er oft durch die Fehlermeldungen der Datenbank: Immer, wenn ein Angriffsversuch fehl schlägt, sagt die ihm, woran er gescheitert ist. Aber auch wenn die Datenbank-Fehlermeldungen von der Webanwendung abgefangen werden, ist er nicht hilflos. Zum einen kann er erkennen, ob ein Angriff erfolgreich war: Die zusätzlichen Informationen erscheinen automatisch in der Ausgabe. Zum anderen gibt es zwei Punkte, die ihm den Angriff erleichtern:

  • Die Datentypen in den verknüpften Abfragen müssen nicht identisch, sondern nur kompatibel, d.h. in den richtigen Datentyp umwandelbar sein. Wie bereits zu sehen war, werden Zahlen bei Bedarf automatisch in Strings umgewandelt. Außerdem kann der Wert NULL in jeden beliebigen Datentyp umgewandelt werden. Ist der Datentyp einer Spalte nicht bekannt, kann dafür in der SELECT-Anweisung immer NULL eingegeben werden, ohne zu einem Fehler zu führen.
  • Meist reicht es, in der originalen Abfrage ein Feld mit Datentyp String zu identifizieren. Danach können beliebige SQL-Abfragen eingeschleust werden, die eine einzelne Spalte mit String-Werten zurückgeben. Der Angreifer kann dann systematisch eine Spalte nach der anderen lesen, er ist nicht darauf angewiesen, alle Spalten auf einmal abzufragen.
Spaltenanzahl ermitteln

Um die Anzahl der zurückgelieferten Spalten zu ermitteln, kann der Angreifer ausnutzen, dass NULL in jeden beliebigen Datentyp umgewandelt werden kann. Er gibt so lange Abfragen mit unterschiedlicher Spaltenanzahl ein, bis die Abfrage ausgeführt wird:

nix' UNION SELECT NULL--
nix' UNION SELECT NULL, NULL--
nix' UNION SELECT NULL, NULL, NULL--
...

Auch wenn keine Datenbank-Fehlermeldungen ausgegeben werden, erkennt er, wenn die Abfrage erfolgreich ausgeführt wurde: Das Ergebnis enthält eine zusätzliche Zeile, in der das Wort NULL oder ein leerer String steht. Die zuletzt eingegebene Abfrage enthielt dann die korrekte Spaltenzahl.

Alternativ kann eine 'ORDER BY'-Klausel in die originale Abfrage eingeschleust und der Index der Spalte solange erhöht werden, bis es einen Fehler ergibt:

nix' ORDER BY 1--
nix' ORDER BY 2--
nix' ORDER BY 3--
...

Durch den eingeschleusten Code ändert sich in den ersten Fällen nur die Reihenfolge der Zeilen im Ergebnis. Kommt es zu einem Fehler, wurde eine ungültige Spaltennummer angegeben, die tatsächliche Anzahl an Spalten ist also um 1 geringer.

Spalte mit Datentyp String suchen

Wurde die korrekte Anzahl der Spalten ermittelt, sucht der Angreifer nach einer Spalte, deren Datentyp String ist. Dafür wird wieder eine Reihe von Abfragen nach NULL verwendet, nur dass diesmal der Reihe nach für eine Spalte ein String eingegeben wird. Für eine Abfrage mit drei Spalten ergibt das folgende Abfragen:

nix' UNION SELECT 'geschafft', NULL, NULL--
nix' UNION SELECT NULL, 'geschafft', NULL--
nix' UNION SELECT NULL, NULL, 'geschafft'--
About Security: Die komplette Serie

Wird die Anfrage ausgeführt, erscheint in der Ausgabe eine zusätzliche Zeile mit dem Wert 'geschafft' darin. Über die so ermittelte Spalte können dann die Daten aus der Datenbank gelesen werden. Um zu testen, ob ein Angriff wirklich funktioniert, kann z.B. die Version der Datenbank abgefragt werden. Hat die Abfrage drei Spalten, von denen die zweite Strings enthält, gibt folgende SQL-Injection unter MySQL und MS-SQL die Datenbankversion aus:

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

Nachdem die Datenbankversion bekannt ist, kann nach bekannten Schwachstellen darin gesucht werden. Meist macht der Angreifer aber mit dem Lesen von Informationen aus der Datenbank weiter.

Datenbanksystem ermitteln

Die verschiedenen Datenbanksysteme verwenden alle etwas unterschiedliche SQL-Dialekte, sodass der Angreifer für manche Angriffe erst einmal wissen muss, mit welchem System er es denn zu tun hat. Eine einfache Methode, um die verschiedene Datenbanken zu unterscheiden, ist deren Art, Strings miteinander zu verbinden:

Oracle: 'ver'¦¦'binden'
MS-SQL: 'ver'+'binden'
MySQL:  'ver' 'binden' (zwischen beiden Teilen befindet sich ein Leerzeichen)

Die Version, die zum richtigen Ergebnis führt, identifiziert dann die Datenbank. Danach kann der Angreifer dann datenbankspezifische Anweisungen nutzen oder deren Systemtabellen ausspionieren. Darin sind z.B. auch die vom Benutzer definierten Tabellen und Spalten gespeichert - eine Information, die der Angreifer für den Zugriff auf diese Tabellen benötigt.

Um SQL-Injection zu verhindern, werden die Benutzereingaben geprüft und gefiltert. Welche Möglichkeiten es dafür gibt und wie ein Angreifer die Filter eventuell austricksen kann, 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

Ihre Meinung ist uns wichtig!
Mobile Computing Heute & Morgen!
Nehmen Sie an unserer Umfrage zum Thema Mobile Computing in Deutschland teil und nutzen Sie die Chance eine Casio Exilim EX-Z1050-Digitalkamera zu gewinnen!

Konferenzen

BASTA! Spring 2009

BASTA! Spring 2009

23.-27. Februar 2009
Maritim Rhein-Main Hotel Wissenschaftsstadt Darmstadt

BASTA! Italia 2009

BASTA! Italia 2009

16.-18. März 2009
Holiday Inn EUR Parco dei Medici, Roma

PHPCon Italia 2009

PHPCon Italia 2009

18.-20. März 2009
Holiday Inn EUR Parco dei Medici, Roma

JAX 09

JAX 09

20.-24. April 2009
Rheingoldhalle Mainz

webinale 09

webinale 09

25.-27. Mai 2009
Berlin

Werbung
Top-Jobs

Software & Support Verlag GmbH

Redakteur (m/w), Vollzeit

Signsoft GmbH

Java-Entwickler (m/w)

Endress+Hauser GmbH+Co. KG

Entwickler Datenbanksysteme (m/w)

Software & Support Verlag GmbH

Lektor (m/w), Vollzeit

Software & Support Verlag GmbH

Volontär (w/m) Redaktion, Vollzeit
JAX 09

Magazine

Entwickler Magazin - Enterprise Technologies & Business Solutions

Entwickler Magazin

Enterprise Technologies & Business Solutions

dot.net magazin - die unabhängige Quelle für .NET-Technologien

dot.net magazin

Die Quelle für .NET-Technologien

Eclipse Magazin

Eclipse Magazin

Weltweit erstes Magazin für Eclipse-Entwickler

Java Magazin - Internet & Enterprise Technology

Java Magazin

Internet & Enterprise Technology

CREATE OR DIE - Ein Leben für die Kreativität

CREATE OR DIE

Ein Leben für die Kreativität

Business Technology - Management Magazin

Business Technology

Management Magazin

PHP Magazin - Professional PHP Development

PHP Magazin

Professional PHP Development

Bücher


hosted by HostEurope