Von Steffen Broßler auf Dienstag, 05. April 2022
Kategorie: IT-Security

(SQL)Injection – Hier gibt der Angreifer die Richtung vor

Sowohl in den „OWASP Top Ten", als auch bei den „SANS Top 25 Most Dangerous Software Errors" taucht die Schwachstelle der Injection auf. Deren bekanntester Vertreter ist wohl die SQL-Injection,. Allerdings lassen sich auch andere Befehle oder Code-Schnipsel in anfällige Anwendungen injizieren. Doch welche Schwachstelle steckt eigentlich hinter dieser Art der Angriffe, wie funktionieren sie und welche Gegenmaßnahmen sollten dagegen ergriffen werden? Diese Fragen werden wir im Rahmen dieses Beitrags klären!

Befehle statt Anfragen

Klären wir zuerst die Frage, was man unter „Injection-Angriffen" versteht. Vereinfacht gesagt, kann der Angreifer spezielle Zeichenketten erstellen, die er durch die Eingabemasken an das Programm übergibt. Diese Zeichenketten führen dazu, dass das Programm Befehle auf den dahinterliegenden Systemen ausführt, die der Angreifer durch die Wahl der Zeichenketten definiert.

Beginnen wir mit einem einfachen Beispiel:

Angenommen in unserem Unternehmen existiert ein Web-Tool, mit dem beliebige Hostnamen via nslookup aufgelöst werden können. (Die Notwendigkeit des Tools hinterfragen wir an dieser Stelle nicht). Der Benutzer trägt in der Eingabezeile den Hostnamen ein, das Programm führt anschließend auf der Befehlszeile den Befehl „nslookup [hostname]" aus und liefert das Ergebnis an den Benutzer zurück.

Bei normaler Verwendung des Programms funktioniert alles ohne weitere Probleme und in einem normalen Test würden vermutlich keine Fehler gefunden. Wenn der Angreifer nun den Hostnamen „Server123 && ls" auflösen lässt, wird auf dem System der Befehl „nslookup Server123 && ls" ausgeführt. Infolgedessen erhält der Angreifer nicht nur das Ergebnis des nslookup-Befehls zurück, sondern auch ein Dateisystemlisting des aktuellen Verzeichnisses.

Der Fehlerteufel steckt im Detail

Dem erfahrenen Linux-Admin ist schon klargeworden, warum hier eine mögliche Sicherheitslücke entstanden ist. Für alle Anderen die Erklärung: Durch das doppelte „&"-Zeichen wird der Befehl „nslookup 123" mit dem Befehl „ls" verknüpft, und beide Kommandos direkt hintereinander ausgeführt.

Die Schwachstelle hierbei entsteht dadurch, dass durch die Manipulation der Eingabe durch den Angreifer aus einem Übergabeparameter ein weiterer Befehl entsteht, welcher durch den Hacker frei gewählt und anschließend auf dem System mit den Rechten des angegriffenen Tools ausgeführt werden kann. Man spricht hierbei von einer „Command Injection", da der Angreifer Befehle einfließen lassen kann.​

Etwas komplizierter, aber sehr weit verbreitet sind die „SQL-Injection"-Angriffe. Bei dieser Sorte werden statt Befehle auf der OS-Ebene, Befehle via SQL direkt auf der Datenbank ausgeführt.

​Auch dazu ein kleines Beispiel:​

Ein Unternehmen bietet seinen Vorgesetzten die Möglichkeit, via Webservice zu jedem Mitarbeiter zusätzliche Informationen zum Werdegang und dessen Erfahrungen abzufragen. Dazu wurde der Webservice so gebaut, dass der eingegebene Benutzername des Mitarbeiters in das folgende SQL-Statement eingesetzt und dieses anschließend auf der Datenbank ausgeführt wird.​

SELECT Name, Werdegang, Erfahrungen FROM Mitarbeiter WHERE NAME LIKE '%input';

​Auch hier gibt es fachlich gesehen keine Probleme und bei der korrekten Eingabe des Benutzernamens werden die angefragten Informationen ausgelesen. Gibt ein Angreifer in dieses Tool allerdings folgenden „Namen" ein, werden zuerst die Informationen zum Mitarbeiter „Meier" ausgelesen und anschließend die komplette Tabelle Mitarbeiter geleert!​

Meier'; TRUNCATE TABLE Mitarbeiter;--

​Warum? Weil durch das zusammenbauen der Eingaben in das Statement folgender Befehl ausgeführt wird:​

SELECT Name, Werdegang, Erfahrungen FROM Mitarbeiter WHERE NAME LIKE 'Meier'; TRUNCATE TABLE Mitarbeiter;--';

​Durch das Aufschlüsseln der einzelnen Teile des Angriffs wird auch klar, warum der Angriff so funktioniert:​
​Eingabe ​Effekt
​Meier'; Meier: Der Name des abgefragten Mitarbeiters, könnte auch weggelassen werden.
' : Schließt den String mit dem Namen im SQL-Statement ab
; : Schließt das komplette SQL-Statement ab
​TRUNCATE TABLE Mitarbeiter; --TRUNCATE TABLE Mitarbeiter;: Hierbei handelt es sich um einen (beliebigen) SQL-Befehl welcher im Anschluss an das Ursprüngliche Statement ausgeführt wird, durch das „;" wird der Befehl SQL-Konform geschlossen.
-- : Der doppelte Bindestrich ist in den meisten Datenbanksystemen das Kommentarzeichen, folglich wird alles was darauf folgt beim Ausführen des Statements nicht weiter beachtet.

Deine Eingabe prüfen, du musst!

Im vorausgegangenen Kapitel wurden nur zwei möglich Beispiele für „Injection"-Angriffe dargestellt, wobei das grundlegende Vorgehen immer gleichbleibt – der Angreifer kann (beliebige) Befehle an das Programm übergeben, welche im Anschluss ausgeführt werden. Doch was kann man nun dagegen tun?

Die einfachste und in einem Großteil der Fälle auch wirksamste Gegenmaßnahme ist die Prüfung der Eingabe. Die meisten Hostnamen werden keine doppelten „&"-Zeichen in ihrem Namen haben, und dass Mitarbeiter ein Hochkomma und ein Semikolon im Namen haben, ist auch eher ungewöhnlich. Werden die Eingaben auf solche Steuer- oder Befehlszeichen serverseitig (!) gefiltert und entweder vor der Ausführung entfernt oder die Befehle daraufhin überhaupt nicht ausgeführt, können die meisten Angriffe bereits vermieden werden.

Auf der einen Seite gibt aber es sicherlich Sonderfälle, in denen eine solche Prüfung nicht das gewünschte Ergebnis erzielt und auf der anderen Seite ist es auch nicht immer einfach die korrekten Filter zu finden und wirklich alle entsprechenden Zeichen (in jeglichen Zeichensätzen) korrekt zu identifizieren. Daher lohnt es sich häufig andere Lösungen zu verwenden. Die meisten verbreiteten Frameworks und Plattformen haben bereits einen guten Schutz gegen SQL-Injection, sodass man bei der Eigenentwicklung das Rad nicht neu erfinden muss, sondern auf bestehende Lösungen aufbauen sollte. Ist es dennoch unabdingbar selbst SQL-Statements zu schreiben, sollten diese als sog. „Prepared Statements" auf den Datenbanken vor dem Zusammensetzen mit der Benutzereingabe geparst werden. Denn dann wird der „neue" Befehl nicht mitgeparst, sondern wirklich als Name an die Datenbank weitergereicht.

Zusammenfassung

Jede Eingabe in ein Programm stellt ein potenzielles Risiko dar. Beispielsweise könnte ein Angreifer dadurch Befehle an das Programm oder das dahinterliegende Backend geben. Dabei kann es sich um Befehle handeln, die anschließend auf Betriebssystem-Ebene ausgeführt werden, oder auch um SQL-Kommandos um die Datenbank zu manipulieren. Um dem entgegenzuwirken bietet es sich an, die Eingaben vor der Verwendung im Programm genau zu prüfen und ggf. zu bereinigen. Außerdem bieten etablierte Frameworks und Prepared Statements einen guten und zuverlässigen Schutz auf der technischen Ebene.​

Wenn Sie noch weitere Fragen haben oder sich über weitere Angriffsmethoden informieren möchten, dann sprechen Sie uns an oder schauen Sie auf unserer Webseite vorbei. Auch zum Thema Datenbanksicherheit werden Sie bei uns fündig. Auf unserem Blog finden Sie außerdem weitere spannende Beiträge zum Thema IT-Security.​
Kommentare hinterlassen