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

Einige Schwachstellen von Web-Ressourcen mit SQL


Die Notiz diskutiert die Anfälligkeit von SQL, bezogen auf das Eindringen in den Körper der Anfrage.

Das Wesen der Verwundbarkeit

Betrachten Sie den Betrieb eines einfachen Systems mit WEB-Schnittstelle, mit dem Benutzer auch speichern können, um Informationen über sich selbst zu ändern. Solche Systeme sind eine der häufigsten im Netzwerk. Es kann auch ein Gästebuch sein, auch ein Chatroom, auch eine Fotogalerie und ein Postdienst.

Die generierte Abfrage an die Datenbank ist gezwungen, das Login des Benutzers 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 Anforderung zeigt der DB die Informationen über den Benutzer an, die das PHP-Skript in Form von HTML erstellt, auch an den Benutzer zurück.

Schauen wir uns ein ziemlich typisches PHP-Skript-Fragment an, das die SQL-Abfrage verwendet, um auf die Datenbank zuzugreifen:

<? Php
$ Result = mysql_db_query ("database", "select * from userTable wo login = '$ userLogin' und password = '$ userPassword'");
Während ($ row = mysql_fetch_array ($ result)) {
Echo $ row ["fullname"];
Echo $ row ["email"];
Echo $ row ["Passwort"];
}
Mysql_free_result ($ result);
?>

Wie wir beobachten, ist die Anmeldung auch das vom Benutzer eingegebene Passwort in den Variablen $ userLogin auch $ userPassword enthalten . Der Inhalt dieser Variablen wird in die Abfrage eingefügt, um Informationen über diesen Benutzer herauszufiltern. Der Filter wird mit der where- Option des Befehls select SQL angegeben. In diesem Fall sieht die Abfrage wie folgt aus : select * from userTable wo login = '$ userLogin' und password = '$ userPassword' wobei userTable der Name der Tabelle mit den erforderlichen Informationen ist. Wenn die Login-Änderung auch die vanya- Werte auch vasya enthält , wird die von der Datenbank gesendete Abfrage folgendes Formular ausfüllen : select * from userTable wo login = 'vanya' und password = 'vasya' . Es ist klar, dass, wenn es einen Eintrag in der Datenbank gibt, wo die Anmeldung vanya ist, dann ist das Passwort vasya , bis die Anforderung keine einzige Zeile aus der Datenbank sendet und das Skript nichts zurückgibt . Somit bietet das obige System Zugriff auf Informationen nur für einen Benutzer, der ein fehlerfreies Passwort auch mit einem Login 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, impliziert, dass die vom Benutzer eingegebene Anmeldung auch ein Kennwort enthält, das in einzelnen Anführungszeichen enthalten ist, die im Anforderungskörper hartcodiert sind. Allerdings sehen wir, was passiert, wenn das Passwort, das vom Benutzer eingegeben wurde, ein Anführungszeichen enthält. Lassen Sie ihn den Wert von vas'ya besitzen , während die Abfrage so aussieht: select * from userTable wo login = 'vanya' und password = 'vas'ya' . Bei der Ausführung einer solchen Anforderung wird es sicherlich einen Fehler geben, da das Zitat aus dem Passwort, das offene Anführungszeichen aus der Abfrage geschlossen hat, auch das Ende des Passwortes ya ' ' hängt 'außerhalb des bedingten Ausdrucks.

Und wenn Sie die folgende Zeile als das Passwort einfügen: 'oder 1 = 1' , wird die Abfrage :: select * von userTable, wobei login = 'vanya' und password = '' oder 1 = 1 '' auch keine Syntaxfehler hat . Aber der logische Ausdruck wird identisch sein, auch im Einwand dieser Abfrage wird SQL die gesamte Benutzerdatenbank ausgeben 8-).

So können wir mit dem Apostroph-Symbol auch in den Körper der SQL-Abfrage gelangen, um sicherzustellen, dass die Testbedingung wahr ist. Wenn wir an einem bestimmten Benutzer Vanya interessiert sind, dann um Informationen über ihn zu erhalten, ist es erlaubt, eine solche Passwort-Zeile zu verwenden: 'oder login =' vanya . Die Abfrage wird: select * from userTable wo login = 'vanya' und password = '' oder login = 'vanya' . Wie Sie verstehen, erhalten wir so Informationen über Vanya .

Die beschriebene Sicherheitsanfälligkeit von Diensten, die auf SQL basieren, beschränkt sich nicht auf den unbefugten Empfang von Informationen. Da solche Systeme in der Regel MySQL verwenden, ist es möglich, nicht nur den bedingten Ausdruck im select-Befehl zu ändern, sondern auch über diesen Befehl hinauszugehen und auch einen weiteren Datenbankbefehl auszuführen. Weil MySQL mehrere Befehle in einer Abfrage erlaubt, getrennt ; , Dann können wir einen dieser Befehle ausführen, indem wir den folgenden Code im Passwortfeld eingeben: '; <Command> SQL> an welcher Stelle als <command SQL> erlaubt ist, einen gültigen Befehl anzugeben. So zum Beispiel dieser Code: '; Drop-Tabelle 'userTable zerstört einfach die UserTable- Tabelle aus der Datenbank.

Praktische Anwendung der Anfälligkeit

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

Beachten Sie in diesem Kopf die folgenden Probleme, die bei der Verwendung der beschriebenen Schwachstelle auftreten:
  • Ermittlung der Verwendung von SQL im System.
  • Identifizieren Sie die Existenz einer Verwundbarkeit. Aufklärung der Reaktion des Skripts auf Fehler
  • Definieren Sie die Namen der Felder in der Tabelle.
  • Identifizieren Sie die Namen der vorhandenen Tabellen.

    Diese Sicherheitsanfälligkeit ist in allen SQL-Abfragen unabhängig, unabhängig vom Skript oder dem Programm, von dem sie aufgerufen werden. Dennoch werden wir Systeme betrachten, die auf PHP basieren. Dies liegt daran, dass der PHP-Fehlerstrom als Standort (standardmäßig) an den Endbenutzer gesendet wird. Während Perl- oder Exe-Anwendungen den Benutzer in der Regel nicht über die Art der Fehler informieren.

    Ermittlung der Verwendung von SQL im System.

    Bei der Erforschung eines bestimmten Systems müssen Sie zunächst herausfinden, ob es SQL verwendet.
    Diese Tatsache kann entweder indirekt identifiziert werden (indem man sich die Namen der verwendeten Dateien, Links zu den verwendeten Tools usw.) oder direkt ansieht, indem sie SQL veranlasst, sich selbst zu beweisen. Wenn wir mit PHP arbeiten, dann gibt es nur einen Weg, um die eindeutige Verwendung von SQL zu bestimmen - das verursacht einen Fehler in seiner Ausführung. Wenn während der Ausführung der Anforderung ein Fehler auftritt, wird das PHP-Skript in keiner Weise fehlerhaft korrigiert, die Meldung über den Fehler von PHP wird direkt auf die Seite des Benutzers ausgegeben.
    Wie ein Fehler bei der Ausführung einer SQL-Abfrage verursacht wird, hängt von dem jeweiligen System des betreffenden Systems ab. In den meisten Fällen darf der Fehler durch Eingabe falscher Daten in das System verursacht werden.

    Identifizieren Sie die Existenz einer Verwundbarkeit. Aufklärung der Reaktion des Skripts auf Fehler

    Die einfachste Möglichkeit, das Vorhandensein einer Sicherheitsanfälligkeit zu erkennen, aber auch die Tatsache der Verwendung von SQL, ist folgendes: In jedem Feld, das angeblich an der Bildung einer SQL-Abfrage beteiligt ist (z. B. das Login- oder Passwort- Feld), geben Sie das Ein-Zeichen-Zeichen ein. Wir füllen die verbleibenden Felder mit korrekten Daten aus (oder lassen Sie es leer, wenn dies vom System erlaubt ist). Nach dem Versenden der Formulardaten betrachten wir die Reaktion des Systems. Wenn also das PHP-Skript uns den SQL-Fehler gibt, dann können wir uns gratulieren: Das System verwendet SQL und das Skript filtert nicht das einfache Anführungszeichen. So lautet das System die Anfälligkeit.
    Ein SQL-Abfragefehler sieht dann so auf der Seite aus:

    Eingabeformular:


    Infolgedessen ist ein SQL-Abfragefehler:


    Wenn es keinen SQL-Fehlercode auf der Seite gibt, könnte dies Folgendes bedeuten:
    1) Das System enthält eine Schwachstelle, aber das PHP-Skript behandelt Fehler. In diesem Fall darf das System hacken, aber du musst "touch" handeln, weil wir nicht wissen, wann die Syntax von SQL korrekt ist, aber zu welcher Zeit es nicht ist.
    2) Das Skript filtert auch das Anführungszeichen, also gibt es keinen Fehler. In diesem Fall enthält das System keine Schwachstellen.
    3) Das System verwendet kein SQL in irgendeiner 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 Anfrage festlegen (zB um die Anmeldung des Benutzers einzustellen). Dennoch müssen Sie den Namen der entsprechenden Felder kennen. Direkt, um diese Namen zu finden, gibt es keine Möglichkeit. Deshalb ist es notwendig, nach einer bestimmten Methode nach den gegebenen Namen zu suchen. Diese Namen können mit den Namen der Felder in dem Formular übereinstimmen, das an den Server gesendet wird, und kann auch nicht in irgendeiner Weise übereinstimmen. Es ist eine gute Sache, dass die Namen der Felder als eine Position Standard sind, und es gibt nicht so viele Varianten, sie zu schreiben. Zum Beispiel ist der Name des Feldes für den Benutzernamen wahrscheinlich einloggen, entweder Benutzer oder Nick . Es ist ähnlich für das Passwort: Passwort entweder pwd oder pass .
    Um die Existenz eines bestimmten Feldes zu bestimmen, schlagen wir eine einfache Methode vor: Wir wollen überprüfen, ob es ein Feld pwd in der Tabelle gibt. Wir stellen in jedem Feld der Form einen solchen String 'pwd =' vor . Wenn das pwd- Feld in der Tabelle existiert, dann wird SQL die Anforderung korrekt verarbeiten, wenn es kein solches Feld gibt, dann wird es einen Fehler der SQL-Ausführung wieder geben. Wenn wir also verschiedene Werte für Feldnamen ersetzen, auch das Ergebnis der Beendigung der Abfrage untersuchen, können wir herausfinden, welche Felder in der Tabelle vorhanden sind, aber welche nicht.

    Identifizieren Sie die Namen der vorhandenen Tabellen.

    Ähnlich wie bei der Methode, die Namen von Feldern in Tabellen zu finden, können auch die Namen der vorhandenen Tabellen in der Datenbank gesucht werden. Mal sehen, ob es eine adminList- Tabelle in der Datenbank gibt. Um dies zu tun, geben wir in das Formularfeld das Formular '; select * from adminList . Wenn infolge des Fehlers SQL überhaupt nicht gestartet wird, dann ist die adminList- Tabelle vorhanden. Für die Korrektheit dieses Tests ist es notwendig, diese Zeile in das Feld einzugeben, das in der endgültigen SQL-Abfrage erscheint. Dies ist notwendig, um sicherzustellen, dass der Syntaxfehler nicht aufgrund des verbleibenden "Schwanzes" der ursprünglichen Abfrage verursacht wird, der später vorhanden ist . Wählen Sie * aus adminList . Beachten Sie, dass, wenn das Formular für die Abfrage im Besitz eines Paares von Login- Feldern auch Passwort ist , dann wahrscheinlich das Passwort-Feld in der Abfrage zuletzt angezeigt wird.

    PS

    Mit dieser Sicherheitsanfälligkeit wurde die Website http://www.bigmir.net (genauer gesagt ihre Fotogalerie auch chatten) gehackt. Wir schrieben über die Anfälligkeit der Besitzer der Website. Das Loch wurde fixiert. Aber jetzt haben wir noch einmal das Anmeldeformular des Chats überprüft. Plus fand all das selig anfällig 8-).