Zeitbasierte SQL Injection Attacken


Zeitbasierte SQL Injection Attacken werden häufig dann genutzt, wenn andere Arten von SQLi wenig oder eingeschränkte Ergebnisse vom Zieldatenbanksystem liefern. Diese zeitbasierte Angriffsmethode schleust komplexere Abfragen in das SQL Statement, die wiederum zu Zeitverzögerungen bei den Antworten oder hoher Auslastung am Zieldatenbanksystem führen sollen. Abhängig von der Zeit, die das Datenbanksystem benötigt, um zu antworten ist es möglich einige Informationen daraus zu ermitteln (Inferenzansatz[1], Informationserschließung). Diese Herangehensweise der Deduktion von Informationen ist sehr nützlich für sog. "Blind SQLi"[2] und "Deep Blind SQLi".

SQL Injection mit Zeitverzögerung (Time Delay)


Zeitbasierte Attacken können genutzt werden, um grundlegende Informationen zur Datenbank zu ermitteln oder das Vorhandensein einer Schwachstelle ausfindig zu machen. Es ist keine unübliche Vorgehensweise, wenn ein Angreifer mit einer zeitbasierten "Deep Blind SQLi" Attacke dem Zieldatenbanksystem Informationen entlocken will.[3]

In folgender Tabelle wird exemplarisch aufgezeigt, wie die Ausführung der SQL Anfrage verzögert werden kann anhand einiger Beispiele an unterschiedlichen DBMS Typen:

DBMS Befehl Code-Beispiel Kommentare
MySQL SLEEP(Zeit) SELECT ... SLEEP(60) Die Zeitangabe erfolgt in Sekunden und ist verfügbar ab MySQL Version 5.
MySQL BENCHMARK(Anzahl, Ausdruck) SELECT BENCHMARK(100000000, 'SELECT ...') Führt die Anweisung vielfach aus. Mit der Nutzung einer zu Beginn hohen Zahl ist es möglich eine Verzögerung im Zieldatenbanksystem zu generieren
MS-SQL, Transact-SQL WAITFOR DELAY 'hh:mm:ss' SELECT ... WAITFOR DELAY '00:00:15' SELECT ... Verzögert die Ausführung des Befehls um den angegebenen Zeitraum
MS-SQL, Transact-SQL WAITFOR TIME 'hh:mm:ss' SELECT ... WAITFOR TIME '14:15:00' SELECT ... Verzögert die Ausführung des Befehls und führt diesen fort, wenn der angegebene Zeitpunkt erreicht ist

*Hinweis: Es ist von Vorteil für die Ausführung von zeitbasierten Attacken im Voraus zu wissen um welchen Typ Datenbanksystem es sich bei dem Zielsystem handelt. Sofern dies nicht bekannt ist, ist es möglich unterschiedliche zeitbasierte Anfragen abzusetzen, bis eine Antwort vom Zieldatenbanksystem zurückgegeben wird. Falls keine dieser Möglichkeiten zum gewünschten Ergebnis führt, sollte auf die Ergebnisse von "Enumerieren" und "Fingeprinting" für das Zielsystem zurückgegriffen werden, um den Datenbanktypen zu ermitteln.


Das Identifizieren von Schwachstellen ist nicht der einzige Einsatzzweck zeitbasierter SQLi Attacken. Sofern der Angreifer Verzögerungen in Prozeduren, bzw. Statements mit Bedingungen (z.B. CASE oder IF) integriert, ist es möglich, dass die Zieldatenbank Systeminformationen oder auch Daten preisgibt. Diese Methode basiert auf dem Inferenzansatz oder auch der Informationserschließung.

Vereinfacht dargestellt, wenn ein Angreifer eine Zeitverzögerung in ein Bedingungs-Statement integriert, hat der Angreifer die Möglichkeit geschaffen dem Zieldatenbanksystem eine Ja/Nein Frage zu stellen. Die Antwort des Datenbanksystems hängt somit von diesem Zeitfaktor ab (wäre fallweise ungewöhnlich lang) und lässt den Angreifer ermitteln, ob die Antwort Ja oder Nein war und daraus weiterführende Informationen erschließen.[4][5]

In folgender Tabelle werden exemplarisch für einige Datenbanksysteme beispielhaft Bedingungs-Statements aufgeführt:

DBMS Bedingungs- Anweisung Kommentare
MySQL IF(Bedingung, wenn_wahr, wenn_falsch) Nur innerhalb eines SQL Statements möglich. In einer Prozedur ist die Syntax analog zu der von Oracle-SQL (PL-SQL)
MS-SQL, Transact-SQL IF Bedingung, wenn_wahr [ELSE wenn_falsch] Nur innerhalb einer Prozedur oder Stapelabfrage (Stacked SQL Query) möglich
Oracle, PL/SQL IF Bedingung THEN wenn_wahr [ELSE wenn_falsch] END IF Nur in PL/SQL möglich

Wie ersichtlich wird unterscheiden sich die injizierten Statements geringfügig abhängig vom Zweck der zeitbasierten Attacke. Im Folgenden Abschnitt werden exemplarische Beispiele anhand unterschiedlicher DBMS aufgezeigt.

Zeitbasierte Attacken in MySQL


Eine zeitbasierte SQLi Attacke exemplarisch für den Datenbanksystemtypen MySQL ist simpel durchzuführen. Die Funktionen SLEEP() und BENCHMARK() können in ein entsprechend präpariertes SQL-Statement integriert werden. Das Code-Beispiel unten führt auf wie ein Angreifer eine Schwachstelle eines Parameters auf SQLi Verwundbarkeit prüfen kann. Eine zeitverzögerte Antwort würde bedeuten, dass die Applikation eine MySQL Datenbank nutzt.

MySQL verzögerte Injection "QUERY" mit integrierter "SLEEP" Funktion:
SELECT * FROM table_t WHERE id=1-SLEEP(15)

MySQL verzögerte Injection "QUERY" mit integrierter "BENCHMARK" Funktion:
SELECT * FROM table_t WHERE id=1-BENCHMARK(100000000, rand())


Der Angreifer kann ebenfalls weiterführende Informationen extrahieren, um Folgeannahmen zu bestätigen. Dies kann mit der Integration einer zeitbasierten Abfrage innerhalb eines Bedingungs-Statements geschehen. In MySQL ist dies erneut sehr simpel durchzuführen da eine IF() Funktion / Bedingung vorhanden ist. Folgendes Beispiel macht das Erschließen von Informationen in Kombination mit Zeitbasierten Attacken noch einmal deutlich, um die Datenbankversion zu ermitteln:

MySQL verzögerte Injection um die DB Version zu ermitteln:
SELECT * FROM table_t WHERE id=1-IF(MID(VERSION(),1,1) = '8'-SLEEP(15), 0)


Wenn die Applikation, bzw. der DBMS Server länger als 15 Sekunden für die Antwort benötigt kann von den Annahmen ausgegangen werden, dass es sich um ein MySQL Datenbanksystem in der Version 8 handelt. Im Beispiel wird die Funktion SLEEP() genutzt, es könnte jedoch ebenfalls BENCHMARK genutzt werden.

Zeitbasierte Attacken in Transact-SQL (MS-SQL Server)


Um Zeitverzögerungen in Transact-SQL Abfragen zu integrieren, müssen Stapelabfragen (Stacked SQL Queries) genutzt werden. Dies ist ebenfalls eine einfache Vorgehensweise. Im unten aufgeführten Beispiel prüft ein Angreifer, ob eine Tabelle eines MS-SQL Servers eine Schwachstelle aufweist.

Transact-SQL verzögerte Injection mit integrierter SLEEP Funktion:
SELECT * FROM table_t WHERE id=1; WAIT FOR DELAY '00:00:15'


Mit der Nutzung von Anweisungen mit Bedingungen ist es möglich auch weiteführende Informationen aus dem System zu ermitteln. Statt der Version wird im folgenden Beispiel versucht den Namen des Systemadministrators des DBS zu ermitteln.

Transact-SQL verzögerte Injection um das Vorhandensein des DBS-Admin "sa" zu bestätigen:
SELECT * FROM table_t WHERE id=1; IF SYSTEM_USER='sa' WAIT FOR DELAY '00:00:15'
(*Hinweis: MS SQL-Server haben in der Regel einen Built-In DBS-Administrator mit dem Benutzernamen "sa")


In Transact-SQL wird die Anweisung WAIT FOR TIME seltener genutzt, kann aber sehr hilfreich sein um SQL-Injection Sicherheitssysteme zu umgehen falls diese nur auf die häufiger genutzte WAIT FOR DELAY Anweisung prüfen.

Zeitbasierte Attacken in Oracle PL/SQL


Oracle weist bei zeitbasierten Attacken einige Besonderheiten auf. Die Funktion SLEEP() kann genutzt werden, jedoch muss diese in einer PL/SQL Block Anweisung wie im folgenden Beispiel dargestellt wird integriert werden.

Oracle PL/SQL Block Anweisung mit 15 Sek. Verzögerung:
BEGIN DBMS_LOCK.SLEEP(15); END;


Die Besonderheit bei Oracle ist, dass keine Stapelabfragen (Stacked SQL Queries) unterstützt werden. Die einzige Möglichkeit eine, wie oben aufgeführte Abfrage, an die Datenbank durchzureichen wäre ein SQL Injection Versuch, das Vorhandensein einer Schwachstelle im PL/SQL Quellcode oder in einem anonymen PL/SQL Block ausfindig zu machen. Die Eintrittswahrscheinlichkeit ist jedoch äußerst gering und selten.

Eine Alternative bietet in PL/SQL das Absetzen einer Abfrage die hohe Ressourcen beansprucht statt der SLEEP() Funktion:

Oracle PL/SQL Abfrage, um hohe Last zu erzeugen:
SELECT count(*) FROM all_users A, all_users B, all_users C;


Bei einer kleinen Datenbank würde die oben genannten Abfrage keine hohe Last erzeugen. Sobald man jedoch die Tabellenanzahl in der Abfrage erhöht und die Abfrage gegen eine größere Datenbank ausgeführt wird kann dies erhebliche Last und Zeitverzögerungen erzeugen. Im Vergleich zu anderen Datenbanksystemen sollte von Abfragen die hohe Last erzeugen abgesehen werden, bei Oracle ist dies die einzige Möglichkeit zeitbasierte SQLi Attacken durchzuführen.

Vorteile und Nachteile zeitbasierter SQL Injection Attacken und Bezug auf die IT-Forensik


Zeitbasierte SQL Injection Attacken bieten den Vorteil, dass sehr wenig Ungewöhnliches, bzw. Auffälligkeiten in den Logs des Datenbanksystems ausfindig zu machen sind. Sobald jedoch zeitbasierte SQLi Attacken durchgeführt werden, die sehr ressourcenintensiv für das Datenbanksystem sind kann sich dies in den Protokollen niederschlagen und fällt auch im Nachgang in der Forensik auf.

Die Länge der Zeitverzögerung muss ebenfalls betrachtet werden, insbesondere dann, wenn Web-Anwendungen die Schnittstelle zum Datenbanksystem bilden. Die System- und Netzwerkauslastung können hier Einfluss auf das gewünschte Resultat haben. Sehr genaue Planung und Timing werden in diesem Fall erforderlich damit die gewünschten Ergebnisse hiervon nicht beeinträchtigt werden.

Um zeitbasierte SQL Injection Attacken forensisch zu ermitteln und zu analysieren sind über die Prüfung der datenbankspezifischen Logs hinaus auch die Applikations- und Serverlogs erforderlich um ein so genaues Bild wie möglich zu einer gefundenen Auffälligkeit zu schaffen.

Quellen

  1. SQL Injection Inference Attacks | sqlinjeciton.net (2020). Abgerufen am 06.02.2022
  2. Deep Blind SQL Injection | Ferruh Mavutina (26.02.2008). Abgerufen am 06.02.2022
  3. Types of SQL Injection (SQLi) | Acunetix (15.07.2020). Abgerufen am 07.02.2022
  4. Time based Blind SQL Injection (SQLi) | Beagle Security (05.06.2018). Abgerufen am 07.02.2022
  5. Blind SQL Injection | OWASP Foundation (o.D.). Abgerufen am 07.02.2022 von