SQL-Injection: Teamwork unter Parametern macht’s möglich

Home / Blog / SQL-Injection: Teamwork unter Parametern macht’s möglich

Eine Einführung ins Thema SQL-Injections findet ihr in unserem vorherigen Beitrag.

SQL-Injections sind vermutlich genauso alt wie die ersten Datenbanken. Trotz ihrer Bekanntheit und bewährten Gegenmaßnahmen stoßen wir aber immer wieder auf diese Schwachstelle.

SQL-Injections entstehen, wenn Benutzereingaben direkt in Datenbankabfragen verwendet werden. Dies kann ausgenutzt werden, um die Abfrage (fast) beliebig anzupassen, um so beispielsweise an Daten zu gelangen, die eigentlich nicht zugreifbar sein sollten.

Vergleichen kann man das mit einem Blankoscheck. Der Aussteller gibt die Kontrolle über die eingetragene Summe ab. Der Empfänger kann einen (fast) beliebigen Geldbetrag eintragen und diesen vom Aussteller-Konto abheben. In vertrauensvollen Hände ist das bequem – in den falschen Händen kann das aber fatale Folgen haben.

Die Ausgangslage

In unseren Pentests sehen wir im Wesentlichen 3 Fälle, wenn es um das Vorbeugen von SQL-Injection-Schwachstellen geht:

  1. Das Thema wurde nicht bedacht, d.h. es gibt keinen Schutz. Dann ist die Ausnutzung in der Regel einfach.
  2. Es werden vorgefertigte parametrisierten Abfragen korrekt verwendet, die vor SQL-Injection-Schwachstellen schützen, mehr dazu unten.
  3. Vor der Verwendung von Benutzereingaben werden eigene Versuche unternommen, die im Wesentlichen auf 2. abzielen, aber leider meist Lücken enthalten.

Im Folgenden geht es um den 3. Fall und den kreativen Prozess, an den eingebauten Hürden vorbei zur Ausnutzung der Schwachstelle zu kommen.

Die Abbildung zeigt genau so einen Versuch. In Zeile 6 werden Wörter und Zeichen definiert, die häufig in SQL-Injection-Angriffen verwendet werden.

In Zeile 7 werden in den empfangenen Benutzereingaben, in diesem Fall username und password, die definierten Wörter entfernt. Die resultierenden Werte werden dann in Zeile 10 in die Datenbankabfrage eingesetzt und ausgeführt.

Fehlerhafter Filter zur Vorbeugung von SQL-Injections.

Typische Schwächen in implementierten Filtern

Der obige implementierte Filter ist nicht so effektiv, wie er auf den ersten Blick scheinen mag. Mehrere „Tricks“ können kombiniert werden, um schlussendlich eine erfolgreiche SQL-Injection durchzuführen.

Groß- und Kleinschreibung
Groß- und Kleinschreibung ist bei Datenbankabfragen in der Regel egal. SELECT kann also einfach durch select ersetzt werden. Der implementierte Filter beachtet aber die unterschiedlichen Schreibweisen nicht. Übrigens akzeptiert eine Datenbank auch eine gemischte Schreibweise, wie etwa SeLEct.

Verhalten des Filters einbeziehen
In manchen Fällen wird die Groß- und Kleinschreibung korrekt beachtet. Oft wird das Ersetzen der gefährlichen Wörter und Zeichen aber nur genau einmal angewendet. Was passiert also, wenn die Eingabe beispielsweise SELSELECTECT enthält? Nach dem Entfernen des Inneren SELECT bleibt selbiges übrig und passiert den Filter ungehindert, da dieser nicht erneut auf das Ergebnis angewendet wird.

Anführungszeichen escapen
Eine weitere Hürde im implementierten Filter ist das Ausschließen des einfachen Anführungszeichens (‚). Dieses wird in der Regel benötigt, um aus einem String-Kontext in der Datenbankabfrage auszubrechen, um so die eingeschleusten SQL-Schlüsselwörter zur Ausführung zu bringen. Die beiden vorherigen Tricks lassen sich auf das Anführungszeichen nicht anwenden.

Trotzdem lässt sich der Filter umgehen, indem man einen Backslash (\) nutzt, um das Anführungszeichen zu escapen. Der Backslash wird vom Filter nicht beachtet und bleibt in der Benutzereingabe deshalb erhalten. Escapen bedeutet, dass ein Zeichen als tatsächlich dieses Zeichen betrachtet wird und nicht als Teil der SQL-Abfrage interpretiert wird, um beispielsweise einen String-Kontext zu beenden. Der Text 'You\'re welcome.' wird von der Datenbank also als String You're welcome. verwendet.

Der Trick

Wie lässt sich mit den erläuterten Schwächen nun aber der implementierte Filter umgehen, sodass man eine manipulierte Datenbankabfrage ausführen kann?

Die Datenbankabfrage aus dem Beispiel hat die folgende Struktur:

SELECT * FROM users WHERE name = '<username>' AND password = '<password>'

Beim Aufruf des obigen Codes wählen wir die Parameter wie folgt:

username: MindBytes\
password:  or 1=1 -- comment

Der implementierte Filter erkennt den Backslash (\) und das or nicht und fügt beides in die Datenbankabfrage ein:

SELECT * FROM users WHERE name = 'MindBytes\' AND password = ' or 1=1 -- comment'

Für die Datenbank hat diese Abfrage jedoch die folgende Struktur:

SELECT * FROM users WHERE name = 'MindBytes\' AND password = ' or 1=1 -- comment'

Da das Anführungszeichen hinter MindBytes escapt wird, bekommt die WHERE-Bedingung eine unerwartete Form. Der Parameter password wird dann genutzt, um die Datenbankabfrage zu manipulieren. Hier muss man den SQL-Injection-Filter bedenken und beispielsweise die fehlende Erkennung von Groß- und Kleinschreibung zum eigenen Vorteil nutzen. Weiterhin wird das Ende der vordefinierten Datenbankabfrage durch einen Kommentar (–) unwirksam gemacht.

Die Datenbankabfrage gibt so alle Einträge aus der Tabelle users aus, da wir eine OR-Bedingung einfügen konnten, welche dazu führt, dass die WHERE-Bedingung immer wahr ist.

Über die gleichzeitige Manipulation der beiden Parameter username und password sind wir also am Filter vorbeigekommen.

Die Auswirkung

Mit einer SQL-Injection lassen sich unterschiedliche Dinge erreichen. Oftmals sind neben den enthaltenen Informationen in der Datenbank auch weitere Funktionen der Datenbanken selbst interessant. Mögliche Ziele eines Angreifers können sein:

  • Manipulation von Abläufen, bspw. Login ohne gültige Zugangsdaten.
  • Unbefugter Zugriff auf Daten innerhalb derselben Datenbank oder weiteren verfügbaren Datenbanken.
  • Je nach Art der verwundbaren Datenbankabfrage können Daten verändert oder gelöscht werden.
  • Überlasten der Datenbank, beispielsweise durch Ressourcen-hungrige Abfragen, um die Verfügbarkeit zu stören.
  • Je nach Konfiguration und Berechtigungen des Datenbankbenutzers können Datenbank-Funktionen missbraucht werden, welche das Lesen oder Schreiben von Dateien auf dem Dateisystem, das Ausführen von Betriebssystem-Befehlen oder das Stellen von Netzwerk-Anfragen, beispielsweise an interne Systeme, ermöglichen.

Die Lösung: Parametrisierte Abfragen

SQL-Injections sind ein generelles Problem mit einer generellen Lösung: Parametrisierte Abfragen und Prepared Statements. Ein selbst entwickelter Filter ist also gar nicht nötig. Hier besteht die Gefahr, dass man Schlüsselwörter oder Zeichen nicht beachtet – wie oben demonstriert.

Parametrisierte Abfragen sind für die gängigen Datenbanken verfügbar und deren Verwendung werden von den geläufigen Programmiersprachen unterstützt. Dabei wird es der Datenbank selbst überlassen, die Benutzereingaben richtig zu verarbeiten.

Zunächst wird die Struktur der Datenbankabfrage definiert. An Stellen, an denen Benutzereingaben verwendet werden sollen, müssen Platzhalter eingefügt werden. Diese werden typischerweise durch Fragezeichen in der Datenbankabfrage dargestellt (Zeile 6). Eine solche Form der Abfrage wird auch parametrisierte Abfrage genannt.

Die parametrisierte Abfrage wird von der Datenbank intern zu einem sogenannten Prepared Statement umgewandelt und für die anschließende (mehrfache) Ausführung bereitgestellt. Die Struktur der Abfrage kann nun nicht mehr verändert werden. Bei der Ausführung des Prepared Statements werden die Benutzereingaben als Parameter für die definierten Platzhalter an die Datenbank übergeben (Zeile 7).

Nutzung von Prepared Statements zum verhindern von SQL-Injections.
Die Datenbank verwendet die Benutzereingaben in einer Art und Weise, in welcher sie keinen Einfluss mehr auf die Struktur der Datenbankabfrage nehmen können. SQL-Injections können so nicht mehr durchgeführt werden. Entwickler und Entwicklerinnen können sich an dieser Stelle also ganz auf erprobte Gegenmaßnahmen von der Datenbank selbst verlassen.

Bereit für mehr IT-Sicherheit?

Dann nutze unseren Konfigurator, um ein passendes Angebot anzufordern oder schreibe uns, um ein individuelles Angebot zu erhalten.