Zum Inhalt springen
Startseite » SQL Injection 1 – Basics

SQL Injection 1 – Basics

Dies ist der erste Beitrag in der Kategorie Tools und Techniken und ich möchte hier mit einer kleinen Reihe zur SQL-Injection Technik beginnen. Im ersten Teil der Reihe geht es um das grundlegende Prinzip des Angriffs.
In den folgenden Teilen werde ich versuchen, einige Spezialfälle zu behandeln. Beispielsweise werde ich euch die Blind SQL Injection erläutern und ein paar Möglichkeiten zur Mitigation vorstellen – also Angriffe zu verhindern bzw. abzumildern.

Ich habe ein Git-Repository mit einer Docker-basierten Trainingsumgebung für SQL Injections erstellt. Damit könnt ihr die Schritte dieses Artikels Schritt für Schritt nachvollziehen, wenn ihr möchtet. Wenn ihr also Docker und Git installiert habt, könnt ihr mit git clone https://github.com/bugninja-de/SQL-injection-practice-course.git das Repository clonen und direkt los legen.

Worum handelt es sich bei der SQL-Injection?

Bei der SQL Injection geht es darum, schadhaften SQL-Code in eine Anwendung einzuschleusen. Klassischerweise handelt es sich bei der angegriffenen Applikation um eine Website, jedoch ist potentiell jede Art von Applikation gefährdet, die mit einer SQL-Datenbank kommuniziert und irgend eine Art von Eingaben seitens des Benutzers entgegen nimmt.
Angreifer nutzen dabei zum einen unzureichende Filterung der Benutzerdaten und zum anderen schlechte bzw. veraltete Methoden zur Kommunikation der Applikation mit der Datenbank aus.

Angenommen, wir haben eine Web Applikation mit einer Anmeldeseite:

Web Login From

Im einfachsten Fall würden die Benutzereingaben ungefiltert direkt in eine SQL-Abfrage weiter gereicht werden:

<?php
    $user = $_REQUEST['user'];
    $pass = $_REQUEST['pass'];
    $query = "SELECT id, username, password FROM users WHERE username = '$user' AND password = '$pass'";
    $result = $mysql_db->query($query);
?>

Gibt der User hier seinen Benutzernamen und sein Passwort ein, würde die SQL-Abfrage etwa so aussehen:

$query = "SELECT id, username, password FROM users WHERE username = 'testuser' AND password = 'testpassword'";

Stimmen diese Eingaben mit den in der Datenbank gespeicherten Werten überein, werden seine Id, sein Username und sein Passwort in $result gespeichert. Wenn es zu den Benutzereingaben keine Übereinstimmung gibt, bleibt $result leer.

Doch was passiert, wenn der Benutzer nicht seinen Benutzernamen eingibt, sondern spezielle Zeichen wie ' gefolgt von SQL Befehlen?

' or 1 = 1 #

Das ist ein sehr einfaches Beispiel für eine SQL-Injection. Mit ' wird das „Feld“ für den Benutzernamen geschlossen und mit or 1 = 1 wird dahinter eine SQL-Bedingung eingefügt, die immer wahr ist, also für jeden Datenbankeintrag gilt. Mit dem # – Zeichen wird ein MySQL Kommentar eingeleitet, der die Programmlogik der restlichen mySQL-Abfrage still legt – alles, was nach dem # – Zeichen folgt, wird vom Server also ignoriert. Die SQL-Abfrage sieht somit wie folgt aus:

$query = "SELECT id, username, password FROM users WHERE username = '' or 1 = 1 #' AND password = ''";

Zur Erinnerung: alles nach dem # wird ignoriert. Diese Abfrage liefert uns ein Ergebnis mit Id, Username und Passwort aller in der Tabelle users gespeicherter Benutzer.

Die Anwendung im Docker-Container wertet nur die erste Zeile der von der Datenbank zurückgegebenen Daten aus. Daher sind wir direkt als Admin eingelogt:

Fazit:

Zugegeben, das Beispiel ist sehr simpel, aber ich denke, dass das Prinzip deutlich wird.
Je nachdem, welche Art von SQL-Server von der Anwendung eingesetzt wird muss die Syntax angepasst werden. Beispielsweise gibt es für Kommentare verschiedene Möglichkeiten. Anstatt des # -Zeichens kann bei verschiedenen SQL-Versionen die Zeichenfolge -- einen Kommentar einleiten. Außerderdem kann beispielsweise das Zeichen, das innerhalb der SQL-Abfrage eine Zeichenkette kennzeichnet statt des ' – Zeichens auch ein " – Zeichen sein.

Es kann natürlich auch komplexerer Code Statt des einfachen or 1 = 1 eingeschleust werden. Beispielsweise kann eine UNION Abfrage oft dazu genutzt werden, sensible Daten aus einer Datenbank auszulesen. Außerdem sind nicht nur Formularfelder anfällig. Teilweise übermittelt der Browser Userdaten als GET-Parameter über die URL. Oft speichert eine Applikation Besucherstatistiken in einer Datenbank gespeichert. Dabei wird z.B. der Useragent (der Daten über den verwendeten Browser und das Betriebssystem beinhaltet) abgefragt. Angreifer können diesen aber mit Tools wie Browser-Plugins leicht manipulieren. Auch die in Cookies gespeicherten Werte können in SQL-Abfragen Verwendung finden. Angreifer haben viele Möglichkeiten, Werte zu manipulieren um das System zu kompromittieren.

In der nächsten Folge der SQL-Injektion Reihe wird es darum gehen, wie ein Angriff mit UNION ALL aussehen könnte.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert