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

Einige Schwachstellen von Web-Ressourcen mit SQL


In der Anmerkung wird die Sicherheitsanfälligkeit von SQL im Zusammenhang mit dem Eindringen in den Hauptteil der Anforderung erläutert.

Das Wesen der Verwundbarkeit

Betrachten Sie den Betrieb eines einfachen Systems mit WEB-Schnittstelle, das es Benutzern ermöglicht, auch Informationen über sich selbst zu speichern. Solche Systeme sind eine der häufigsten im Netzwerk. Es kann auch ein Gästebuch, ein Chatraum, eine Fotogalerie und ein Postdienst sein.

Die generierte Abfrage an die Datenbank ist gezwungen, die Benutzeranmeldung auch das vom Benutzer eingegebene Passwort zu haben. Für diese Felder muss die Datenbank den entsprechenden Eintrag in der Tabelle finden. Nach Beendigung der Abfrage zeigt die Datenbank die Informationen über den Benutzer, die das PHP-Skript in Form von HTML erstellt, auch dem Benutzer an.

Betrachten wir ein ziemlich typisches PHP-Skriptfragment, das die SQL-Abfrage verwendet, um auf die Datenbank zuzugreifen:

<? php
$ result = mysql_db_query ("Datenbank", "select * from userTable wobei login = '$ userLogin' und password = '$ userPassword'");
while ($ row = mysql_fetch_array ($ result)) {
echo $ row ["fullname"];
echo $ row ["email"];
echo $ row ["Passwort"];
}
mysql_free_result ($ result);
?>

Wie wir sehen, ist das Login auch das vom Benutzer eingegebene Passwort in $ userLogin Variablen auch $ userPassword enthalten . Der Inhalt dieser Variablen wird in die Abfrage eingefügt, um Informationen über diesen Benutzer herauszufiltern. Der Filter wird mit der Option wo des SQL-Befehls select angegeben . In diesem Fall sieht die Abfrage folgendermaßen aus: select * from userTable wobei login = '$ userLogin' und password = '$ userPassword' Dabei ist userTable der Name der Tabelle, die die erforderlichen Informationen enthält. Wenn die Änderung des Login- Namens des Passworts auch die Vanya- Werte enthält, dann vasya, dann wird die von der Datenbank gesendete Abfrage die folgende Form annehmen : Wählen Sie * aus userTable wobei login = 'vanya' und password = 'vasy' . Es ist klar, dass, wenn es einen Eintrag in der Datenbank gibt, bei dem die Anmeldung vanya ist, das Passwort vasya ist , bis die Anfrage keine einzige Zeile von der Datenbank sendet und das Skript nichts zurückgibt . Somit stellt das obige System den Zugriff auf Informationen nur für den Benutzer bereit, der ein fehlerfreies Passwort auch bei der Anmeldung hat.

Es scheint, dass ein solches System keine Fehler enthält. In der Klasse selbst ist dies nicht der Fall. Die Logik der Programme, die das obige Beispiel erstellt haben, setzt voraus, dass die eingegebene Anmeldung des Benutzers auch ein Kennwort ist, das in einfachen Anführungszeichen enthalten ist, die im Anforderungstext fest codiert sind. Sehen wir uns jedoch an, was passiert, wenn das vom Benutzer eingegebene Passwort selbst ein Anführungszeichen enthält. Lassen Sie ihn den Wert von vasya besitzen , während die Abfrage wie folgt aussieht: Wählen Sie * aus userTable, wobei login = 'vanya' und password = 'vas'ya' . Wenn Sie eine solche Anfrage ausführen, wird es sicherlich einen Fehler geben, weil das Zitat aus dem Passwort, das Anfangszitat aus der Anfrage geschlossen hat, auch das Ende des Passwortes , das Sie 'hängen' haben, um außerhalb des bedingten Ausdrucks zu hängen.

Und wenn Sie die folgende Zeile als Passwort eingeben: 'oder 1 = 1' , wird die Abfrage zu :: select * von userTable, wobei login = 'vanya' und password = '' oder 1 = 1 '' ebenfalls keine Syntaxfehler aufweist . Aber der logische Ausdruck wird identisch wahr sein, auch in einem Einspruch gegen diese Abfrage wird SQL die gesamte Benutzerdatenbank 8-) ausgeben.

Mit dem Apostroph-Symbol können wir also im Körper der SQL-Abfrage auch priknjut machen, so dass die geprüfte Bedingung wahr ist. Wenn wir an einem bestimmten Benutzer von Vanya interessiert sind, können wir, um Informationen über ihn zu erhalten, eine solche Passwortzeile verwenden: 'or login =' vanya . Die Abfrage wird zu: select * from userTable wobei login = 'vanya' und password = '' oder login = 'vanya' . Wie Sie verstehen, erhalten wir als Ergebnis Informationen über Vanya .

Die beschriebene Sicherheitslücke von auf SQL basierenden Diensten ist nicht auf den unbefugten Empfang von Informationen beschränkt. Da MySQL in solchen Systemen verwendet wird, ist es möglich, nicht nur den bedingten Ausdruck im Befehl select zu ändern, sondern auch über diesen Befehl hinauszugehen und einen weiteren Datenbankbefehl auszuführen. Weil MySQL mehrere Befehle in einer Abfrage erlaubt, getrennt ; , dann können wir einen dieser Befehle ausführen, indem Sie den folgenden Code in das Passwortfeld eingeben: '; <SQL-Befehl> an welcher Stelle als <SQL-Befehl> darf ein beliebiger gültiger Befehl angegeben werden. Also zum Beispiel solchen Code: '; drop table 'userTable zerstört einfach die userTable- Tabelle von der Datenbank.

Praktische Anwendung der Sicherheitsanfälligkeit

Trotz der Einfachheit ist die praktische Verwendung von SQL-Abfragefehlern sehr schwierig.

Berücksichtigen Sie in diesem Fall die folgenden Probleme, die beim Verwenden der beschriebenen Sicherheitsanfälligkeit auftreten:
  • Ermitteln der Verwendung von SQL im System.
  • Identifizieren Sie das Vorhandensein einer Sicherheitslücke. Aufklärung der Skriptantwort auf Fehler.
  • Definieren Sie die Namen der Felder in der Tabelle.
  • Definieren der Namen vorhandener Tabellen

    Diese Sicherheitsanfälligkeit ist in allen SQL-Abfragen unabhängig von dem Skript oder dem Programm, von dem sie aufgerufen werden, enthalten. Wir werden jedoch Systeme in Betracht ziehen, die auf PHP basieren. Dies liegt daran, dass der PHP-Fehlerstream als Speicherort (standardmäßig) an den Endbenutzer gesendet wird. Während Perl- oder Exe-Anwendungen den Benutzer normalerweise nicht über die Art der Fehler informieren.

    Ermitteln der Verwendung von SQL im System.

    Wenn Sie ein bestimmtes System erforschen, müssen Sie zuerst herausfinden, ob es SQL verwendet.
    Diese Tatsache kann entweder indirekt (durch Betrachten der Namen der verwendeten Dateien, Verknüpfungen zu den verwendeten Werkzeugen usw.) oder direkt - durch Verursachen, dass SQL sich selbst beweist, entdeckt werden. Wenn wir mit PHP arbeiten, gibt es nur ein Werkzeug, um die Verwendung von SQL eindeutig zu identifizieren - dies führt zu einem Fehler bei seiner Ausführung. Wenn während der Ausführung der Anfrage ein Fehler auftritt, wird das PHP-Skript jedoch nicht explizit fehlerhaft angezeigt. Die Meldung über den Fehler von PHP wird direkt auf der Benutzerseite ausgegeben.
    Wie ein Fehler bei der Ausführung einer SQL-Abfrage verursacht wird, hängt vom System des jeweiligen Systems ab. In den meisten Fällen kann der Fehler verursacht werden, indem falsche Daten in das System eingegeben werden.

    Identifizieren Sie das Vorhandensein einer Sicherheitslücke. Aufklärung der Skriptantwort auf Fehler.

    Das einfachste Mittel, um das Vorhandensein einer Schwachstelle zu erkennen, ist aber auch die Tatsache, dass SQL verwendet wird: In jedes Feld, das an der Bildung einer SQL-Abfrage beteiligt sein soll (z. B. das Feld Login oder Passwort ), geben Sie das Anführungszeichen ein. Wir füllen die verbleibenden Felder mit den korrekten Daten aus (oder lassen sie leer, wenn dies vom System erlaubt ist). Nach dem Senden der Formulardaten betrachten wir die Reaktion des Systems. Wenn das PHP-Skript daher den SQL-Fehler liefert, können wir uns selbst dazu beglückwünschen: Das System verwendet SQL und das Skript filtert das einfache Anführungszeichen nicht. Das heißt, das System enthält eine Schwachstelle.
    Ein SQL-Abfragefehler sieht dann auf der Seite folgendermaßen aus:

    Eingabeformular:


    Daher ein SQL-Abfragefehler:


    Wenn auf der Seite kein SQL-Fehlercode vorhanden ist, könnte dies Folgendes bedeuten:
    1) Das System enthält eine Sicherheitslücke, aber das PHP-Skript behandelt Fehler. In diesem Fall darf das System hacken, aber Sie müssen "berühren", weil wir nicht wissen, zu welcher Zeit die Syntax von SQL korrekt ist, aber zu welcher Zeit es nicht ist.
    2) Das Skript filtert auch das Anführungszeichen, so dass kein Fehler auftritt. In diesem Fall enthält das System keine Sicherheitslücken.
    3) Das System verwendet SQL in keiner Weise.
    In den letzten paar Fällen ist klar, dass eine weitere Untersuchung von SQL keine Bedeutung hat.

    Definieren Sie die Namen der Felder in der Tabelle.

    Um Informationen aus der Datenbank mit bestimmten Daten zu erhalten, müssen wir die Werte einiger Felder in der Abfrage ermitteln (z. B. um die Benutzeranmeldung festzulegen). Trotzdem müssen Sie den Namen der entsprechenden Felder kennen. Direkt um diese Namen zu finden ist nicht möglich. Deshalb muss man hier nach den gegebenen Namen nach der Suchmethode suchen. Diese Namen können mit den Namen der Felder im Formular übereinstimmen, die an den Server gesendet wurden, und können auch nicht übereinstimmen. Eine gute Lektion ist, dass die Namen der Felder als eine Position Standard sind und es nicht so viele Varianten gibt, sie zu schreiben. Zum Beispiel ist der Name des Feldes für den Benutzernamen wahrscheinlich Login, entweder Benutzer oder Nickname . Ähnliches gilt für das Passwort: Passwort entweder pwd oder pass .
    Um die Existenz eines bestimmten Feldes zu ermitteln, bieten wir eine einfache Methode an: Lassen Sie uns prüfen, ob in der Tabelle ein Feld pwd existiert. Wir führen in jedem Feld des Formulars eine solche Zeile 'pwd =' ein . Wenn das Feld pwd in der Tabelle vorhanden ist, verarbeitet SQL die Anforderung korrekt. Wenn es kein solches Feld gibt, wird der Fehler der SQL-Ausführung erneut auftreten. Wenn also die Feldnamen durch andere Werte ersetzt werden und auch das Ergebnis der Abfrage beendet wird, können wir herausfinden, welche Felder in der Tabelle existieren, welche aber nicht.

    Definieren der Namen vorhandener Tabellen

    Ähnlich wie bei der Suche nach Feldnamen in Tabellen ist es auch möglich, nach den Namen vorhandener Tabellen in der Datenbank zu suchen. Mal sehen, ob es in der Datenbank eine adminList- Tabelle gibt. Um dies zu tun, geben wir in das Formularfeld das Formular ein; wählen Sie * aus adminList . Wenn aufgrund des Fehlers SQL überhaupt nicht gestartet wird, ist die Tabelle adminList vorhanden. Für die Richtigkeit dieses Tests muss diese Zeile in das Feld eingegeben werden, das in der endgültigen SQL-Abfrage angezeigt wird. Dies ist notwendig, um sicherzustellen, dass der Syntaxfehler nicht aufgrund des verbleibenden " Tails " der ursprünglichen Abfrage verursacht wird, die später bei * adminList angezeigt wird . Beachten Sie, dass, wenn das Formular für die Anfrage einem Paar gehört, das Login- Feld auch Passwort ist , dann wird das Passwort-Feld höchstwahrscheinlich in der Anfrage zuletzt erscheinen.

    PS

    Mit Hilfe dieser Sicherheitslücke wurde die Seite http://www.bigmir.net (genauer gesagt die Fotogalerie, auch Chat) gehackt. Wir haben über die Sicherheitslücke der Websitebetreiber geschrieben. Das Loch wurde repariert. Aber jetzt haben wir noch einmal das Registrierungsformular des Chats überprüft. Plus fand alle Blah-Blah-Schwachstelle 8-).