Samstag, 10. Januar 2009 |
Wie ein Angreifer SQL-Injection im zum Löschen von Daten verwendeten DELETE-Statement ausnutzen kann und welche Möglichkeiten der zur Verknüpfung der Ergebnisse mehrerer SELECT-Abfragen verwendete UNION-Operator ihm bietet, erfahren Sie in dieser Folge.
DELETE-Statements dienen zum Löschen einer oder mehrerer existierender Zeilen in einer Tabelle. Wie bei UPDATE-Statements wird die zu löschende Zeile über eine WHERE-Klausel ausgewählt, in der sehr wahrscheinlich auch die vom Angreifer manipulierbaren Parameter verwendet werden. Wie beim UPDATE-Statement können Änderungen an der WHERE-Bedingung weitreichende Folgen haben.
DELETE FROM benutzer WHERE name='jo' AND passwort='geheim'
N E U ! Security aktuell
Täglich aktuelle Security-Infos!
löscht die Informationen des Benutzers jo, wenn er das
richtige Passwort eingegeben hat. Wie schon beim Beispiel zum
UPDATE-Statement in About Security
#169
soll SQL-Injection wieder über den Parameter für den
Benutzernamen möglich sein.
Der einfachste Angriff ist ein Denial-of-Service-Angriff durch
Löschen aller Daten, dazu reicht die Eingabe eines Wertes wie z.B.
egal' OR 1=1--
aus:
DELETE FROM benutzer WHERE name='egal' OR 1=1--' AND passwort='was'
löscht alle Zeilen der Tabelle benutzer. Wie schon beim
UPDATE-Statement festgestellt, kann ein unvorsichtiger Test
äußerst unangenehme Folgen haben. Als Fortsetzung des letzten
Beispiels in About Security
#169
könnte die Webanwendung nach einem erfolgreichen Login den Parameter
für den Benutzernamen verwenden, um in einer Tabelle mit
Protokollinformationen alte Einträge zu löschen:
DELETE FROM verlauf WHERE name='jo' ORDER BY timestamp DESC LIMIT 10;
Wurde die Passwortabfrage durch Eingabe von
' OR 1=1--
umgangen, ergibt das
DELETE FROM verlauf WHERE name='' OR 1=1--' ORDER BY timestamp DESC LIMIT 10;
und löscht die gesamte Verlaufstabelle. Einen Angreifer freut das vielleicht sogar, da dabei auch eventuell vorhandene verräterische Spuren gelöscht werden, auf jeden Fall wird es ihn nicht weiter stören. Für den Betreiber der Webanwendung kann das je nach Verwendung der Daten aber ziemlich ärgerlich sein. Darum führt man solche Experimente auch besser an einem Testsystem durch.
Nachdem die am häufigsten verwendeten SQL-Statements vorgestellt wurden, kommt nun der für SQL-Injection-Angriffe wichtigste Operator: UNION.
Der UNION-Operator wird zur Verknüpfung der Ergebnisse von zwei oder mehr SELECT-Statements zu einem einzigen Ergebnis verwendet. Ist SQL-Injection in ein SELECT-Statement möglich, kann oft eine zweite, von der vorhandenen Abfrage vollkommen unabhängige Abfrage durchgeführt und das Ergebnis über den UNION-Operator mit dem vorhandenen Ergebnis verknüpft werden. Wird das Ergebnis an den Benutzer zurückgeliefert, kann ein Angreifer so beliebige Daten aus der Datenbank abfragen. Als Beispiel soll wieder die Bücher-Datenbank aus About Security #166 dienen:
SELECT Autor, Titel, Jahr FROM Buchdatenbank WHERE Verlag = 'entwickler.press'
Die könnte z.B. folgendes Ergebnis als Teil der Ergebnis-Webseite liefern:
| Autor | Titel | Jahr |
| Carus | Ethical Hacking | 2008 |
| Eilers | Ajax Security | 2008 |
| Wussow | Sichere Webanwendungen | 2007 |
Wie über SQL-Injection in dieser Abfrage die gesamte Bücher-Datenbank ausgelesen werden kann, wurde bereits in About Security #166 beschrieben. Für den Angreifer viel interessanter wäre es aber, z.B. die Benutzertabelle zu lesen. Das ist über eine weitere SELECT-Anweisung und den UNION-Operator möglich:
entwickler.press' UNION SELECT benutzername, passwort, id FROM benutzer--
als Eingabe führt zu folgender SQL-Abfrage:
SELECT Autor, Titel, Jahr FROM Buchdatenbank WHERE Verlag = 'entwickler.press'
UNION
SELECT benutzername, passwort, id FROM benutzer--'
Diese Abfrage liefert das bereits bekannte Ergebnis, gefolgt vom Inhalt der Benutzertabelle:
| Autor | Titel | Jahr |
| Carus | Ethical Hacking | 2008 |
| Eilers | Ajax Security | 2008 |
| Wussow | Sichere Webanwendungen | 2007 |
| admin | 12geheim34 | 0 |
| alice | abc123 | 1 |
Werden die Ergebnisse von SELECT-Abfragen mit dem UNION-Operator
miteinander verknüpft, erhält das Gesamtergebnis die gleichen
Spaltennamen wie die der ersten SELECT-Abfrage. Das ist für einen
SQL-Injection-Angriff auch zwingend notwendig, da die Webanwendung
natürlich nur die ihr bekannten Spalten ausgibt. Wird eine Zeile des
Ergebnis z.B. im Array zeile[] gespeichert, werden die
einzelnen Spalten für die Ausgabe über
zeile['Autor'], zeile['Titel'] und
zeile['Jahr'] angesprochen. Da die Webanwendung die
Spaltennamen benutzername, passwort und
id nicht kennt, würde sie sie im Gesamtergebnis der
verknüpften SQL-Abfragen ignorieren. Da darin aber alle Spalten die
Namen der ersten SELECT-Abfrage erhalten, gibt die Webanwendung alle Zeilen
des Gesamtergebnis aus, ohne zu erkennen, dass sich darunter Daten aus einer
anderen Tabelle befinden.
Welche Voraussetzungen für die Verwendung des UNION-Operators bestehen und wie ein Angreifer die erreichen 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!