Prompt Injection
Andrea Hauser
So nutzt man eine SQL-Injection aus
Dass es sich bei Injections im Allgemeinen, aber auch bei SQL-Injections, immer noch um ein Problem handelt, zeigt sich mit der Positionierung in der OWASP Top 10 2017 Liste, wo sich Injections in den letzten Jahren stetig an erster Stelle befinden. Die Auswirkungen einer erfolgreichen SQL-Injection können vielfältig sein:
Es existieren unterschiedliche Arten von SQL-Injections. Dabei handelt es sich um die folgenden:
Die am einfachsten zu findenden SQL-Injections sind error-basierte SQL-Injections. Dabei reicht im einfachsten Fall das Einfügen eines Semikolons ;
oder Hochkommas '
, um ein SQL-Statement so zu verändern, dass es zu einem Fehler führt. Wenn die Eingabe des Benutzers nicht gefiltert wird und die Fehlerausgabe nicht verhindert wird, erhält ein Angreifer so meist weitreichende Einsicht in das SQL-Statement.
Ein auf SQL-Injection anfälliges SQL-Statement könnte wie folgt aussehen:
"SELECT name FROM articles WHERE articleId = ' " + userDefinedArticleId " ';"
Mit einem nicht gefilterten '
wird daraus folgendes Statement, welches zu einer Fehlermeldung führt:
SELECT name FROM articles WHERE articleId = ' ' ';
Dank dieser Einsicht wird es für einen Angreifer möglich, ein erweitertes gültiges SQL-Statement zu kreieren, welches dann zurückgegeben und in der Webseite dargestellt wird.
Bei union-basierten SQL-Injections wird der Operator UNION
aus SQL ausgenutzt, um das Ergebnis von mehreren SELECT-Statements in ein Resultat zu kombinieren, das dann zurückgegeben wird. Damit können die Daten von anderen Tabellen innerhalb der Datenbank abgefragt werden.
Um das Beispiel von oben zu erweitern, könnte ein Angreifer folgenden Angriff versuchen:
1' UNION SELECT 'password' FROM users WHERE username = 'admin'
und damit potenziell das Passwort des administrativen Benutzers auslesen, wenn die Tabellen so bestehen und der Benutzername übereinstimmt.
In vielen Fällen werden die Fehlermeldungen, die durch die Datenbank generiert werden, unterdrückt. Damit ist das Problem allerdings noch nicht behoben. Es bestehen unterschiedliche Techniken, wie SQL-Injections ausgenutzt werden können, auch wenn keine Fehlermeldungen zurückgegeben werden.
Bei boolean-based blind SQL-Injections wird ein SQL-Statement so verändert, dass entweder eine wahre oder eine falsche Aussage entsteht. Wenn sich die Antworten zu einer dieser Aussagen verändert, kann durch eine Serie von Anfragen die Datenbank Zeichen für Zeichen ausgelesen werden. Dabei handelt es sich um einen Angriffsweg, der von Hand schnell sehr aufwändig wird. Es bestehen allerdings gute Tools, wie zum Beispiel sqlmap, die bei der Extrahierung von Daten unterstützen können.
Um das Beispiel von oben weiter zu ziehen, falls keine Fehlermeldungen zurückgegeben werden, würde ein Angreifer folgendes versuchen:
1' UNION SELECT 'a' WHERE 1=1--
und
1' UNION SELECT 'a' WHERE 1=2--
wenn sich die beiden Antworten unterscheiden, kann damit auf wahre und falsche Aussagen geschlossen werden. Danach wird der Angriff erweitert, um zum Beispiel das Passwort des admin Benutzers abzufragen.
1' UNION SELECT 'a' FROM users WHERE username = 'admin' and SUBSTRING(password, 1, 1) > 'm'--
Auch hier wurden einige Annahmen getroffen, wie die Namen der Tabellen und des Benutzers. Diese könnten allerdings auch durch ähnliche wahr oder falsch Abfragen herausgefunden werden.
Normalerweise werden SQL-Queries synchron verarbeitet. Dementsprechend kann durch das Verzögern bzw. Verlängern der Ausführungszeit von diesen im Normalfall auch die HTTP-Response verzögert werden. Bei time-based blind SQL-Injections werden SQL-Statements injected, die bei einer wahren Aussage verzögern und bei einer falschen Aussage sofort Antworten. Damit kann wieder Zeichen für Zeichen der Datenbank ausgelesen werden. Auch hier wird das Extrahieren der Daten von Hand schnell mühsam und die Unterstützung eines Tools oder selbst geschriebenen Skripts wird notwendig.
Das Auslösen einer Verzögerung kann durch die Injection von einem sleep-Statement geschehen, im Falle einer MySQL-Datenbank würde die Injection wie folgt aussehen:
1' UNION SELECT sleep(10)
Sollten alle bisherigen Versuche auf SQL-Injection zu testen fehlgeschlagen sein, kann mit der out-of-band blind SQL-Injection ein letzter Versuch gestartet werden, um SQL-Injections durchzuführen. In diesem Szenario wird versucht eine Netzwerkinteraktion mit einem durch den Angreifer kontrollierten System herzustellen. Dabei wird in den meisten Fällen versucht eine DNS-Abfrage auszulösen, da ausgehende DNS-Anfragen im Normalfall nicht verhindert werden.
Bei einem Microsoft SQL Server würde die Injeciton wie folgt aussehen:
'; exec master..xp_dirtree '//sqlinjectionconfirmed.scip.ch/test'--
Nicht unerwähnt bleiben soll allerdings auch die Möglichkeit SQL-Injection-Schwachstellen via Source Code Analyse zu identifizieren. Für eine Einführung ins Thema Source Code Analyse, eine effektive Methode, um SQL Injection Schwachstellen aufdecken zu können, wird auf den Beitrag Source Code Analyse – Eine Einführung verwiesen.
Bis anhin wurde nur die Möglichkeit des Auffindens von SQL-Injection Schwachstellen besprochen. Weiterführend wird aufgezeigt, wie diese verhindert werden können.
Durch das Verwenden von Prepared Statements wird es möglich eine Trennung zwischen dem SQL-Statement und den eingegebenen Daten herzustellen. Damit wird sichergestellt, dass Benutzereingaben nicht als SQL interpretiert werden. Beispiele für spezifische Programmiersprachen können im SQL Prevention Cheat Sheet von OWASP gefunden werden.
Prepared Statements sind allerdings nicht auf sämtliche Bereiche einer SQL-Abfrage anwendbar. Wenn zum Beispiel der Tabellenname oder eine ORDER BY Klausel dynamisch erstellt werden muss, muss eine Eingabeüberprüfung anhand einer Whitelist durchgeführt werden. Nur falls weder Prepared Statements noch eine Eingabeüberprüfung anhand einer Whitelist sinnvoll durchführbar sind, sollte auf das Escaping von Sonderzeichen zurückgegriffen werden, da es sehr schwierig korrekt umzusetzen ist und die Gefahr für übersehene Lücken besteht, die dennoch eine SQL-Injection erlauben. Es ist allerdings durchaus sinnvoll Prepared Statements mit einem Whitelist- und einem Escaping-Ansatz zu ergänzen, um einen sekundären Schutz aufzubauen.
SQL-Injections sind leider immer noch ein Problem. Auch wenn keine offensichtlichen Schwachstellen bestehen können durch blind SQL-Injection Techniken weitere Schwachstellen aufgedeckt werden. Das Beheben von SQL-Injection-Schwachstellen ist möglich durch Prepared Statements.
Unsere Spezialisten kontaktieren Sie gern!
Andrea Hauser
Andrea Hauser
Andrea Hauser
Andrea Hauser
Unsere Spezialisten kontaktieren Sie gern!