Giftspritze

Seite 2: Kung Fu

Inhaltsverzeichnis

Durch das Einschleusen eigener Befehle ist es möglich, auf beliebige Tabellen und Daten zuzugreifen und deren Inhalte zu manipulieren, zum Beispiel Kreditkartennummern, die ein Webshop zu Abrechnungszwecken gespeichert hat. Dazu muss ein Angreifer aber die Struktur der Datenbank kennen. Um etwa aus einer Tabelle zu lesen, ist es notwendig, den Tabellennamen anzugeben. Ohne Einblick in den Source-Code muss er raten - oder die Datenbank dazu bewegen, Informationen preiszugeben.

Je nach Plattform und Umgebung, zeigen Web-Applikationen in bestimmten Situationen dem Anwender Fehlermeldungen an. Beispielsweise geben Microsofts Active Server Pages über misslungene Zugriffe auf den MS-SQL-Server Auskunft.

Übergibt man im Web-Frontend als Usernamen

' having 1=1--

an, so erzeugt die Programmzeile

var Query = "SELECT * FROM users WHERE username = '" + username + "'
and password =" ' " + password + "'";

eine Fehlermeldung, da das SQL-Statement HAVING an dieser Stelle eigentlich nichts zu suchen hat. Sinngemäß lautet die Meldung: "Die Spalte users.username ist ungültig, da sie in keiner Funktion enthalten ist und kein GROUP-BY-Argument angegeben ist."

Ein Angreifer weiß nun, dass es in der Tabelle users die Spalte username gibt und kann weitere Versuche starten:

' group by users.username having 1=1--

produziert die Ausgabe: "Die Spalte users.password ist ungültig, da sie in keiner Funktion enthalten ist und kein GROUP-BY-Argument angegeben ist." Zusätzlich kennt er nun den Namen eines weiteren Feldes. Neben HAVING sind auch andere SQL-Befehle möglich, um Fehlermeldungen zu produzieren. Den Variablentyp erfährt der Angreifer durch die Eingabe

' union select sum(username) from users--

Die Applikation meldet einen Fehler, wenn username vom Typ varchar ist: Die Funktion sum() erlaubt nämlich keine varchars als Argument.

Mit vielen provozierten Meldungen kann man sich nach und nach ein Bild vom Aufbau der Datenbank machen. Anschließend ist es dann relativ einfach, eigene Datensätze zu schreiben, zu ändern, zu lesen oder zu sogar zu löschen.

Unterstützt die Datenbank besondere Features, so ist es sogar möglich mit dem darunterliegenden Betriebssystem zu kommunizieren. Für einen MS-SQL-Server auf Windows 2000 und VBScript findet man häufig solche Anweisungen:

var Query = "SELECT * FROM myKunde WHERE card = '" 
& request.form("eingabe") & "'";
Set myDatensatz = myConnection.execute(Query);

Mit dem Befehl lassen sich allen Datensätze anzeigen, in denen die Variable eingabe identisch mit dem Inhalt des Feldes card. Leider hat auch hier der Programmierer darauf vertraut, dass der Bediener keine bösen Absichten hat. Gibt dieser nämlich

' exec master..xp_cmdshell 'net user foo bar /ADD'--

ein, so macht das Skript daraus den Befehl:

SELECT * FROM myKunde WHERE card = '' 
exec master..xp_cmdshell 'net user foo bar /ADD'--'

Der MS-SQL-Server liest den letzten Teil des Kommandos als sogenannte Extended Stored Procedures (ESP), die er auf dem Server ausführt [1]. Die Funktion xp_cmdshell übergibt den sich anschließenden String als Befehl an die DOS-Kommandozeile. Das Beispiel fügt damit dem System, beispielsweise Windows 2000, den User foo mit dem Password bar hinzu. ESPs sind im Prinzip dynamische Bibliotheken, die zur Laufzeit nachgeladen und ausgeführt werden. Neben MS-SQL unterstützen auch andere Datenbankhersteller Extended Stored Procedures, die diverse Funktionen bieten, beispielsweise Registry-Keys lesen und schreiben oder Dienste starten und stoppen [9].