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

Einige Schwachstellen von Webressourcen, die SQL verwenden


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

Das Wesen der Verletzlichkeit

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

Die generierte Abfrage an die Datenbank ist gezwungen, die Benutzeranmeldung auch über das vom Benutzer eingegebene Passwort zu führen. 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 an, die das PHP-Skript in Form von HTML erstellt, und gibt dem Benutzer ebenfalls Informationen.

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

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

Wie wir beobachten, ist der Login auch das vom Benutzer eingegebene Passwort in $ userLogin Variablen enthalten, auch $ userPassword . Der Inhalt dieser Variablen wird in die Abfrage eingefügt, um Informationen über diesen Benutzer herauszufiltern. Der Filter wird mit der where- Option des select SQL-Befehls angegeben. In diesem Fall sieht die Abfrage wie folgt aus : select * from userTable wobei login = '$ userLogin' und password = '$ userPassword' wobei userTable der Name der Tabelle ist, die die erforderlichen Informationen enthält. Wenn die Änderung im Login- Namen des Passworts auch die vanya- Werte enthält, dann vasya, dann wird die von der Datenbank gesendete Anfrage das folgende Formular annehmen : 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, das Passwort vasya ist , bis die Anfrage keine einzelne Zeile aus der Datenbank sendet und das Skript nichts zurückgibt . Somit stellt das obige System den Zugang zu Informationen nur für den Benutzer bereit, der ein fehlerfreies Passwort hat, auch ein Login.

Es scheint, dass ein solches System keine Fehler enthält. In der Klasse selbst ist dies nicht der Fall. Die Logik der Programmierer, die das obige Beispiel erstellt haben, impliziert, dass die vom Benutzer eingegebene Anmeldung auch ein Passwort ist. Sie werden in einfachen Anführungszeichen enthalten sein, die im Anforderungshauptteil fest codiert sind. Sehen wir uns an, was passiert, wenn das vom Benutzer eingegebene Passwort selbst ein Anführungszeichen enthält. Lassen Sie ihn den Wert von vas'ya besitzen , während die Abfrage wie folgt aussieht: Wählen Sie * aus userTable, wo login = 'vanya' und password = 'vas'ya' ist . Wenn Sie eine solche Anfrage ausführen, wird es sicherlich einen Fehler geben, weil das Zitat aus dem Passwort das Eröffnungsangebot aus der Anfrage geschlossen hat und auch das Ende des Passworts, das Sie außerhalb des Bedingungsausdrucks aufgehängt haben.

Und wenn Sie die folgende Zeile als Passwort einfügen: 'oder 1 = 1' , wird die Abfrage :: select * von userTable, wo login = 'vanya' und password = '' oder 1 = 1 '' auch keine Syntaxfehler . Aber der logische Ausdruck ist identisch wahr, auch in einem Einwand gegen diese Abfrage, wird SQL die gesamte Benutzerdatenbank 8-) ausgeben.

Mit dem Apostroph-Symbol können wir also priknjut im Hauptteil der SQL-Abfrage auch so einstellen, dass die geprüfte Bedingung wahr ist. Wenn wir an einem bestimmten Benutzer von Wanja interessiert sind, dann, um Informationen über ihn zu erhalten, ist es erlaubt, eine solche Passwortzeile zu verwenden: 'oder login =' wanja . Die Abfrage wird: select * von userTable wo login = 'vanya' und password = '' oder login = 'vanya' . Wie Sie verstehen, erhalten wir Informationen über Wanja .

Die beschriebene Anfälligkeit von Diensten, die auf SQL basieren, ist nicht auf den unerlaubten Empfang von Informationen beschränkt. Da MySQL in solchen Systemen verwendet wird, ist es möglich, nicht nur den bedingten Ausdruck im select-Befehl zu ändern, sondern auch diesen Befehl zu überspringen und einen anderen Datenbankbefehl auszuführen. Da 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 dem als <SQL-Befehl> ein gültiger Befehl angegeben werden darf. So zum Beispiel ein solcher Code: '; drop table 'userTable zerstört einfach die userTable- Tabelle aus der Datenbank.

Praktische Nutzung der Schwachstelle

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

Berücksichtigen Sie in diesem Abschnitt die folgenden Probleme, die bei der Verwendung der beschriebenen Sicherheitsanfälligkeit auftreten:
  • Bestimmen der Verwendung von SQL im System.
  • Identifizieren Sie das Vorliegen einer Sicherheitsanfälligkeit. Aufklärung der Skriptantwort auf Fehler.
  • Definieren Sie die Namen der Felder in der Tabelle.
  • Definieren der Namen vorhandener Tabellen

    Diese Sicherheitsanfälligkeit ist unabhängig von dem Skript oder dem Programm, von dem sie aufgerufen werden, in allen SQL-Abfragen enthalten. Wir werden jedoch Systeme betrachten, die auf PHP basieren. Dies liegt daran, dass der PHP-Fehlerstrom 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.

    Bestimmen der Verwendung von SQL im System.

    Wenn Sie ein bestimmtes System untersuchen, müssen Sie zuerst herausfinden, ob es SQL verwendet.
    Diese Tatsache kann entweder indirekt (durch Betrachten der Namen der verwendeten Dateien, Links zu den verwendeten Tools usw.) oder direkt erkannt werden, indem SQL dazu veranlasst wird, sich selbst zu beweisen. 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 der Ausführung. Tritt während der Ausführung der Anfrage ein Fehler auf, ist das PHP-Skript jedoch nicht explizit fehlerhaft, 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 vom jeweiligen System des betreffenden Systems ab. In den meisten Fällen kann der Fehler durch Eingabe fehlerhafter Daten in das System verursacht werden.

    Identifizieren Sie das Vorliegen einer Sicherheitsanfälligkeit. 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 jedem Feld, das angeblich an der Bildung einer SQL-Abfrage beteiligt ist (z. B. das Feld Login oder Passwort ), geben Sie das einfache Anführungszeichen ein. Wir füllen die restlichen Felder mit 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 uns das PHP-Skript daher den SQL-Fehler gibt, können wir uns gratulieren: Das System verwendet SQL, und das Skript filtert das einfache Anführungszeichen nicht. Das heißt, das System enthält eine Sicherheitslücke.
    Ein SQL-Abfragefehler sieht dann folgendermaßen aus:

    Eingabeform:


    Infolgedessen ein SQL-Abfragefehler:


    Wenn auf der Seite kein SQL-Fehlercode vorhanden ist, 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 Sie müssen "berühren", weil wir nicht wissen, zu welcher Zeit die Syntax von SQL korrekt sein wird, aber zu welchem ​​Zeitpunkt dies nicht der Fall ist.
    2) Das Skript filtert auch das Anführungszeichen, so dass kein Fehler vorliegt. In diesem Fall enthält das System keine Schwachstellen.
    3) Das System verwendet SQL in keiner Weise.
    In den letzten beiden 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 bestimmen (z. B. um die Benutzeranmeldung festzulegen). Sie müssen dennoch den Namen der entsprechenden Felder kennen. Direkt diese Namen zu finden, ist nicht möglich. Deshalb ist es hier notwendig, nach den angegebenen Namen durch eine Suchmethode zu suchen. Diese Namen können mit den Namen der Felder in dem an den Server gesendeten Formular übereinstimmen und dürfen auch nicht in irgendeiner Weise übereinstimmen. Eine gute Lektion ist, dass die Namen der Felder als Position Standard sind und es nicht so viele Varianten gibt, sie zu schreiben. Beispielsweise ist der Name des Feldes für den Benutzernamen wahrscheinlich Login, entweder Benutzer oder Nick . Es ist ähnlich für das Passwort: Passwort entweder pwd oder übergeben .
    Um die Existenz eines bestimmten Feldes zu bestimmen, bieten wir eine einfache Methode an: Wir wollen überprüfen, ob in der Tabelle ein Feld pwd existiert. Wir führen in jedem Feld der Form eine solche Zeile 'pwd =' ein . Wenn das pwd- Feld in der Tabelle vorhanden ist, verarbeitet SQL die Anfrage korrekt, falls kein solches Feld vorhanden ist, wird der Fehler der SQL-Ausführung erneut auftreten. Durch Ersetzen verschiedener Werte für die Feldnamen, die das Ergebnis der Abfrage beenden, können wir herausfinden, welche Felder in der Tabelle vorhanden sind, welche nicht.

    Definieren der Namen vorhandener Tabellen

    Ähnlich der Methode zum Auffinden der Feldnamen in Tabellen ist es auch möglich, nach den Namen vorhandener Tabellen in der Datenbank zu suchen. Mal sehen, ob es eine Tabelle adminList in der Datenbank gibt. Dazu tragen wir in das Formularfeld das Formular '; select * von adminList ein . Wenn SQL aufgrund des Fehlers ü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 letzten SQL-Abfrage angezeigt wird. Dies ist notwendig, um sicherzustellen, dass der Syntaxfehler nicht aufgrund des verbleibenden " Endes " der ursprünglichen Abfrage verursacht wird, die später anwesend sein wird * aus adminList auswählen . Beachten Sie, dass das Passwortfeld in der Anfrage zuletzt angezeigt wird, wenn das Formular für die Anforderung von einem Paar des Felds Login registriert wird.

    PS

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