SQL Injection
Last updated
Last updated
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
RootedCON ist die relevanteste Cybersicherheitsveranstaltung in Spanien und eine der wichtigsten in Europa. Mit der Mission, technisches Wissen zu fördern, ist dieser Kongress ein brodelnder Treffpunkt für Technologie- und Cybersicherheitsprofis in jeder Disziplin.
Eine SQL-Injection ist ein Sicherheitsfehler, der Angreifern ermöglicht, Datenbankabfragen einer Anwendung zu beeinflussen. Diese Schwachstelle kann Angreifern ermöglichen, Daten anzuzeigen, zu ändern oder zu löschen, auf die sie keinen Zugriff haben sollten, einschließlich Informationen anderer Benutzer oder aller Daten, auf die die Anwendung zugreifen kann. Solche Aktionen können zu dauerhaften Änderungen an der Funktionalität oder dem Inhalt der Anwendung führen oder sogar zu einer Kompromittierung des Servers oder einem Denial of Service.
Wenn eine Website anfällig für SQL-Injection (SQLi) erscheint, aufgrund ungewöhnlicher Serverantworten auf SQLi-bezogene Eingaben, ist der erste Schritt, zu verstehen, wie man Daten in die Abfrage injiziert, ohne sie zu stören. Dies erfordert die Identifizierung der Methode, um wirksam aus dem aktuellen Kontext zu entkommen. Dies sind einige nützliche Beispiele:
Dann müssen Sie wissen, wie Sie die Abfrage so reparieren, dass es keine Fehler gibt. Um die Abfrage zu reparieren, können Sie Daten eingeben, damit die vorherige Abfrage die neuen Daten akzeptiert, oder Sie können einfach Ihre Daten eingeben und ein Kommentarsymbol am Ende hinzufügen.
Beachten Sie, dass diese Phase einfacher wird, wenn Sie Fehlermeldungen sehen oder Unterschiede feststellen können, wenn eine Abfrage funktioniert und wenn nicht.
Eine zuverlässige Methode zur Bestätigung einer SQL-Injection-Schwachstelle besteht darin, eine logische Operation auszuführen und die erwarteten Ergebnisse zu beobachten. Wenn beispielsweise ein GET-Parameter wie ?username=Peter
identische Inhalte liefert, wenn er auf ?username=Peter' oder '1'='1
geändert wird, deutet dies auf eine SQL-Injection-Schwachstelle hin.
Ebenso dient die Anwendung von mathematischen Operationen als effektive Bestätigungstechnik. Wenn der Zugriff auf ?id=1
und ?id=2-1
dasselbe Ergebnis liefert, ist dies ein Hinweis auf SQL-Injection.
Beispiele, die die Bestätigung durch logische Operationen demonstrieren:
Diese Wortliste wurde erstellt, um SQL-Injektionen auf die vorgeschlagene Weise zu bestätigen:
In einigen Fällen werden Sie keine Änderung auf der Seite bemerken, die Sie testen. Daher ist eine gute Möglichkeit, blinde SQL-Injektionen zu entdecken, die DB Aktionen ausführen zu lassen, die einen Einfluss auf die Zeit haben, die die Seite zum Laden benötigt. Daher werden wir in der SQL-Abfrage eine Operation concatenieren, die viel Zeit in Anspruch nehmen wird:
In einigen Fällen werden die Sleep-Funktionen nicht erlaubt sein. Statt diese Funktionen zu verwenden, könnten Sie die Abfrage komplexe Operationen durchführen lassen, die mehrere Sekunden in Anspruch nehmen. Beispiele für diese Techniken werden separat für jede Technologie kommentiert (sofern vorhanden).
Der beste Weg, das Back-end zu identifizieren, besteht darin, Funktionen der verschiedenen Back-ends auszuführen. Sie könnten die Sleep Funktionen des vorherigen Abschnitts oder diese hier verwenden (Tabelle von payloadsallthethings:
Auch wenn Sie Zugriff auf die Ausgabe der Abfrage haben, könnten Sie die Version der Datenbank ausgeben lassen.
In der Fortsetzung werden wir verschiedene Methoden zur Ausnutzung verschiedener Arten von SQL-Injection besprechen. Wir werden MySQL als Beispiel verwenden.
Wenn Sie die Ausgabe der Abfrage sehen können, ist dies der beste Weg, um sie auszunutzen. Zunächst müssen wir die Anzahl der Spalten herausfinden, die die ursprüngliche Anfrage zurückgibt. Dies liegt daran, dass beide Abfragen die gleiche Anzahl von Spalten zurückgeben müssen. Zwei Methoden werden typischerweise zu diesem Zweck verwendet:
Um die Anzahl der Spalten in einer Abfrage zu bestimmen, passen Sie schrittweise die Zahl in den ORDER BY- oder GROUP BY-Klauseln an, bis eine falsche Antwort zurückgegeben wird. Trotz der unterschiedlichen Funktionen von GROUP BY und ORDER BY innerhalb von SQL können beide identisch verwendet werden, um die Spaltenanzahl der Abfrage zu ermitteln.
Wählen Sie immer mehr Nullwerte aus, bis die Abfrage korrekt ist:
You should use null
values as in some cases the type of the columns of both sides of the query must be the same and null is valid in every case.
In den nächsten Beispielen werden wir den Namen aller Datenbanken, den Tabellennamen einer Datenbank und die Spaltennamen der Tabelle abrufen:
Es gibt einen anderen Weg, um diese Daten in jeder verschiedenen Datenbank zu entdecken, aber die Methodik bleibt immer gleich.
Wenn die Ausgabe einer Abfrage sichtbar ist, aber eine union-basierte Injektion unerreichbar scheint, deutet dies auf das Vorhandensein einer versteckten union-basierten Injektion hin. Dieses Szenario führt oft zu einer blinden Injektionssituation. Um eine blinde Injektion in eine union-basierte zu verwandeln, muss die Ausführungsabfrage im Backend erkannt werden.
Dies kann durch die Verwendung von Techniken zur blinden Injektion zusammen mit den Standardtabellen, die spezifisch für Ihr Ziel-Datenbankverwaltungssystem (DBMS) sind, erreicht werden. Um diese Standardtabellen zu verstehen, wird empfohlen, die Dokumentation des Ziel-DBMS zu konsultieren.
Sobald die Abfrage extrahiert wurde, ist es notwendig, Ihr Payload so anzupassen, dass die ursprüngliche Abfrage sicher geschlossen wird. Anschließend wird eine Union-Abfrage an Ihr Payload angehängt, um die Ausnutzung der neu zugänglichen union-basierten Injektion zu ermöglichen.
Für umfassendere Einblicke verweisen Sie auf den vollständigen Artikel unter Healing Blind Injections.
Wenn Sie aus irgendeinem Grund die Ausgabe der Abfrage nicht sehen können, aber die Fehlermeldungen sehen können, können Sie diese Fehlermeldungen verwenden, um Daten aus der Datenbank zu exfiltrieren. Indem Sie einem ähnlichen Ablauf wie bei der Union-basierten Ausnutzung folgen, könnten Sie es schaffen, die DB zu dumpen.
In diesem Fall können Sie die Ergebnisse der Abfrage oder die Fehler nicht sehen, aber Sie können unterscheiden, wann die Abfrage eine wahre oder eine falsche Antwort zurückgibt, da es unterschiedliche Inhalte auf der Seite gibt. In diesem Fall können Sie dieses Verhalten ausnutzen, um die Datenbank Zeichen für Zeichen zu dumpen:
Dies ist der gleiche Fall wie zuvor, aber anstatt zwischen einer wahr/falsch-Antwort aus der Abfrage zu unterscheiden, können Sie zwischen einem Fehler in der SQL-Abfrage oder nicht unterscheiden (vielleicht weil der HTTP-Server abstürzt). Daher können Sie in diesem Fall jedes Mal einen SQL-Fehler erzwingen, wenn Sie das Zeichen richtig erraten:
In diesem Fall gibt es keine Möglichkeit, die Antwort der Abfrage basierend auf dem Kontext der Seite zu unterscheiden. Aber Sie können die Seite länger laden lassen, wenn das erratene Zeichen korrekt ist. Wir haben diese Technik bereits zuvor verwendet, um eine SQLi-Schwachstelle zu bestätigen.
Sie können gestapelte Abfragen verwenden, um mehrere Abfragen nacheinander auszuführen. Beachten Sie, dass während die nachfolgenden Abfragen ausgeführt werden, die Ergebnisse nicht an die Anwendung zurückgegeben werden. Daher ist diese Technik hauptsächlich im Zusammenhang mit blinden Schwachstellen nützlich, bei denen Sie eine zweite Abfrage verwenden können, um eine DNS-Abfrage, einen bedingten Fehler oder eine Zeitverzögerung auszulösen.
Oracle unterstützt gestapelte Abfragen nicht. MySQL, Microsoft und PostgreSQL unterstützen sie: QUERY-1-HERE; QUERY-2-HERE
Wenn keine andere Exploitationsmethode funktioniert hat, können Sie versuchen, die Datenbank die Informationen an einen externen Host zu exfiltrieren, der von Ihnen kontrolliert wird. Zum Beispiel über DNS-Abfragen:
Überprüfen Sie das SQLMap Cheatsheet, um eine SQLi-Schwachstelle mit sqlmap auszunutzen.
Wir haben bereits alle Möglichkeiten besprochen, eine SQL-Injection-Schwachstelle auszunutzen. Finden Sie einige weitere Tricks, die von der Datenbanktechnologie abhängen, in diesem Buch:
Oder Sie finden eine Menge Tricks zu: MySQL, PostgreSQL, Oracle, MSSQL, SQLite und HQL in https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
RootedCON ist die relevanteste Cybersicherheitsveranstaltung in Spanien und eine der wichtigsten in Europa. Mit der Mission, technisches Wissen zu fördern, ist dieser Kongress ein brodelnder Treffpunkt für Technologie- und Cybersicherheitsprofis in jeder Disziplin.
Liste zum Versuch, die Anmeldefunktion zu umgehen:
Login bypass ListDiese Abfrage zeigt eine Schwachstelle, wenn MD5 mit true für Rohdaten in Authentifizierungsprüfungen verwendet wird, wodurch das System anfällig für SQL-Injection wird. Angreifer können dies ausnutzen, indem sie Eingaben erstellen, die, wenn sie gehasht werden, unerwartete Teile von SQL-Befehlen erzeugen, was zu unbefugtem Zugriff führt.
Empfohlene Liste:
Sie sollten als Benutzernamen jede Zeile der Liste verwenden und als Passwort immer: Pass1234. &#xNAN;(Diese Payloads sind auch in der großen Liste enthalten, die zu Beginn dieses Abschnitts erwähnt wurde)
WENN ' escaped wird, können Sie %A8%27 verwenden, und wenn ' escaped wird, wird erstellt: 0xA80x5c0x27 (╘')
Python-Skript:
Dazu sollten Sie versuchen, ein neues Objekt mit dem Namen des "Master-Objekts" (wahrscheinlich admin im Falle von Benutzern) zu erstellen, indem Sie etwas ändern:
Benutzer mit dem Namen: AdMIn (Groß- und Kleinbuchstaben)
Benutzer mit dem Namen: admin=
SQL Truncation Attack (wenn es eine Art von Längenbeschränkung im Benutzernamen oder in der E-Mail gibt) --> Benutzer mit dem Namen: admin [viele Leerzeichen] a erstellen
Wenn die Datenbank anfällig ist und die maximale Anzahl von Zeichen für den Benutzernamen beispielsweise 30 beträgt und Sie den Benutzer admin nachahmen möchten, versuchen Sie, einen Benutzernamen mit dem Namen: "admin [30 Leerzeichen] a" und einem beliebigen Passwort zu erstellen.
Die Datenbank wird überprüfen, ob der eingegebene Benutzername in der Datenbank existiert. Wenn nicht, wird sie den Benutzernamen auf die maximal erlaubte Anzahl von Zeichen (in diesem Fall auf: "admin [25 Leerzeichen]") kürzen und dann wird sie automatisch alle Leerzeichen am Ende entfernen und den Benutzer "admin" in der Datenbank mit dem neuen Passwort aktualisieren (einige Fehler könnten auftreten, aber das bedeutet nicht, dass es nicht funktioniert hat).
Weitere Informationen: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref
Hinweis: Dieser Angriff wird in den neuesten MySQL-Installationen nicht mehr wie oben beschrieben funktionieren. Während Vergleiche standardmäßig nachfolgende Leerzeichen ignorieren, führt der Versuch, eine Zeichenfolge einzufügen, die länger ist als die Länge eines Feldes, zu einem Fehler, und die Einfügung schlägt fehl. Für weitere Informationen zu dieser Überprüfung: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation
Fügen Sie so viele ','',''
hinzu, wie Sie für notwendig halten, um die VALUES-Anweisung zu beenden. Wenn eine Verzögerung ausgeführt wird, haben Sie eine SQL-Injection.
Die ON DUPLICATE KEY UPDATE
-Klausel in MySQL wird verwendet, um Aktionen anzugeben, die die Datenbank ausführen soll, wenn ein Versuch unternommen wird, eine Zeile einzufügen, die zu einem doppelten Wert in einem UNIQUE-Index oder PRIMARY KEY führen würde. Das folgende Beispiel zeigt, wie diese Funktion ausgenutzt werden kann, um das Passwort eines Administratorkontos zu ändern:
Beispiel Payload-Injektion:
Eine Injektionspayload könnte wie folgt erstellt werden, wobei versucht wird, zwei Zeilen in die users
-Tabelle einzufügen. Die erste Zeile ist eine Ablenkung, und die zweite Zeile zielt auf die E-Mail eines bestehenden Administrators ab, mit der Absicht, das Passwort zu aktualisieren:
Hier ist, wie es funktioniert:
Die Abfrage versucht, zwei Zeilen einzufügen: eine für generic_user@example.com
und eine andere für admin_generic@example.com
.
Wenn die Zeile für admin_generic@example.com
bereits existiert, wird die Klausel ON DUPLICATE KEY UPDATE
ausgelöst, die MySQL anweist, das Feld password
der vorhandenen Zeile auf "bcrypt_hash_of_newpassword" zu aktualisieren.
Folglich kann die Authentifizierung dann mit admin_generic@example.com
und dem Passwort, das dem bcrypt-Hash entspricht, versucht werden ("bcrypt_hash_of_newpassword" steht für den bcrypt-Hash des neuen Passworts, der durch den tatsächlichen Hash des gewünschten Passworts ersetzt werden sollte).