Was bedeutet SQL-Injektion?

SQL-Injektion (engl. SQL Injection) bezeichnet das Ausnutzen einer Sicherheitslücke in Zusammenhang mit SQL-Datenbanken. Diese entsteht bei mangelnder Maskierung oder Überprüfung von Funktionszeichen in Benutzereingaben. Der Angreifer versucht über die Anwendung, die den Zugriff auf die Datenbank bereitstellt, eigene Datenbankbefehle einzuschleusen. Sein Ziel ist es dabei Daten in seinem Sinne zu verändern oder Kontrolle über den Server zu erhalten.

Für SQL-Injektionen nutzbare Fehler treten auf, wenn eine Applikation SQL-Abfragen an den Server weiterreicht, ohne die vom Benutzer eingegebenen Parameter ausreichend zu prüfen und etwaig enthaltene Funktionszeichen zu maskieren, um ihnen so die Sonderfunktion zu nehmen. Funktionszeichen in SQL sind zum Beispiel der umgekehrte Schrägstrich, der Apostroph oder das Semikolon. Diese Zeichen können durch Voranstellen des Maskierungszeichens, einem umgekehrten Schrägstrich, als Text gekennzeichnet werden. Dieser Vorgang wird auch „Escapen“ genannt. Ein Beispiel: Die vom Benutzer eingegebene Zeichenfolge „Mit '\n' wird ein Zeilenumbruch erzeugt“ wird korrekt maskiert als „Mit \'\\n\' wird ein Zeilenumbruch erzeugt“ an die Datenbank übergeben. Außerdem muss sichergestellt werden, dass Datentypen eingehalten werden; so dürfen zum Beispiel Zahlen nur aus Ziffern und dem Dezimaltrennzeichen bestehen.

Oft zu finden sind solche Lücken in CGI-Scripten und auch in Programmen, die Daten wie Webseiteninhalte oder E-Mails in SQL-Datenbanken eintragen. Nimmt ein solches Programm die Maskierung nicht korrekt vor, kann ein Angreifer durch den gezielten Einsatz von Funktionszeichen weitere SQL-Anforderungen einschleusen oder die Abfragen so manipulieren, dass zusätzliche Daten ausgegeben werden. In einigen Fällen besteht auch die Möglichkeit, Zugriff auf eine Shell zu erhalten, was im Regelfall die Möglichkeit zur Kompromittierung des gesamten Servers bedeutet.

Stored Procedures sind in diesem Zusammenhang sicherer. Dabei werden die Benutzereingaben in einem Programm an die Stored Procedures übergeben. Erst dort wird die SQL-Abfrage erzeugt und ausgeführt, wodurch die Injektion weiterer SQL-Befehle in Benutzereingaben verhindert wird.

Veränderung von Daten

Auf einem Webserver findet sich das Script find.cgi zum Anzeigen von Artikeln. Das Script akzeptiert den Parameter „ID“, welcher später Bestandteil des SQL-Befehls wird. Folgende Tabelle soll dies illustrieren:

  Erwarteter Aufruf
Aufruf http://webserver/cgi-bin/find.cgi?ID=42
Erzeugtes SQL SELECT author, subjekt, text FROM artikel WHERE ID=42
  SQL-Injektion
Aufruf http://webserver/cgi-bin/find.cgi?ID=42;UPDATE+USER+SET+TYPE="admin"+WHERE+ID=23
Erzeugtes SQL SELECT author, subjekt, text FROM artikel WHERE ID=42; UPDATE USER SET TYPE="admin" WHERE ID=23

Wie man erkennen kann, wird dem Programm ein zweiter SQL-Befehl untergeschoben, der die Benutzertabelle modifiziert.
Das Verbinden zweier Anweisungen in einer Abfrage wird aber meistens unterbunden!

Datenbank-Server verändern

Auf einem Webserver findet sich das Script search.aspx zum Suchen nach Webseiten. Das Script akzeptiert den Parameter „keyword“, welcher später Bestandteil des SQL-Befehls wird. Folgende Tabelle soll dies illustrieren:

  Erwarteter Aufruf
Aufruf http://webserver/search.aspx?keyword=sql
Erzeugtes SQL SELECT url, title FROM myindex WHERE keyword LIKE '%sql%'
  SQL-Injektion
Aufruf http://webserver/search.aspx?keyword=sql'+;GO+EXEC+cmdshell('format+C')+--
Erzeugtes SQL SELECT url, title FROM myindex WHERE keyword LIKE '%sql' ;GO EXEC cmdshell('format C') --%'

Hier wird der eigentlichen Abfrage ein weiterer Befehl angehängt. Die zwei Bindestriche (--) kommentieren das Hochkomma als Überbleibsel der eigentlichen Anfrage aus. Der Befehl ermöglicht das Formatieren der Festplatte, aber auch Downloads oder Ähnliches lassen sich dadurch erzeugen (am Beispiel Microsoft SQL Server).

Auf manchen SQL-Implementationen ist die UNION-Klausel verfügbar. Diese erlaubt es, mehrere SELECTs gleichzeitig abzusetzen, die dann eine gemeinsame Ergebnismenge zurückliefern. Durch eine geschickt untergeschobene UNION-Klausel kann man beliebige Tabellen und Systemvariablen auslesen.

  Erwarteter Aufruf
Aufruf http://webserver/cgi-bin/find.cgi?ID=42
Erzeugtes SQL SELECT author, subjekt, text FROM artikel WHERE ID=42
  SQL-Injektion
Aufruf http://webserver/cgi-bin/find.cgi?ID=42+UNION+SELECT+login,+password,+'x'+FROM+user
Erzeugtes SQL SELECT author, subjekt, text FROM artikel WHERE ID=42 UNION SELECT login, password, 'x' FROM user

Erlangen von Administratorrechten

Bei bestimmten Datenbankservern, wie dem Microsoft SQL Server, werden Stored Procedures mitgeliefert, die unter anderem dazu missbraucht werden können, einen neuen Benutzer auf dem angegriffenen System anzulegen.

Diese Möglichkeit kann dazu benutzt werden, um zum Beispiel eine Shell auf dem angegriffenen Rechner zu starten.

Blinde SQL-Injektion

Von einer blinden SQL-Injektion spricht man, wenn ein Server keine deskriptive Fehlermeldung zurückliefert, aus der hervorgeht, ob der übergebene Query erfolgreich ausgeführt wurde oder nicht. Anhand verschiedenster Kleinigkeiten wie etwa leicht unterschiedlicher Fehlermeldungen oder auch charakteristisch unterschiedlicher Antwortzeiten des Servers kann ein versierter Angreifer häufig dennoch feststellen, ob ein Query erfolgreich war oder einen Fehler zurückmeldet.

Generell ist die Webanwendung für die korrekte Prüfung der Eingabedaten verantwortlich, zum Beispiel das eine Postleitzahl nur Ziffern enthält und ein Name keine Sonderzeichen. Geeignete Schutzmaßnahmen sind in erster Linie dort zu implementieren.

Hat ein Betreiber eines Webservers keine Kontrolle über die Anwendungen kann durch Einsatz von Web Application Firewalls (WAF) zumindest teilweise verhindert werden, dass SQL-Injektion-Schwachstellen ausgenutzt werden können.

Es ist nicht schwer, bestehende Programme so umzubauen, dass SQL-Injektionen nicht mehr möglich sind. Das hauptsächliche Problem der meisten Programmierer ist fehlendes Wissen über diese Art von Angriffen. Nachfolgend einige Beispiele, um die Angriffe abzuwehren.

Die Verwendung von Prepared Statements ist Stored Procedures vorzuziehen. Außerdem sollten nicht benötigte Stored Procedures aus dem Datenbanksystem entfernt werden. Es sollte auch geprüft werden, ob der Einsatz unter einem Datenbank-Account mit eingeschränkten Zugriffsrechten möglich ist, was in der Regel der Fall sein dürfte.

Hier gibts noch mehr Email-Adressen