Drücke „Enter”, um zum Inhalt zu springen.

HackTheBox – Node WriteUp | Tipps + Anleitung | htb

0

HackTheBox – Node WriteUp | Tipps + Anleitung | htb

Node ist eine der schwierigeren CTF Challenges von HackTheBox. Grundlegendes Wissen im Bereich Reverse Engineering und Datenbanken wird benötigt.

bewertung

Tipps

Tipp 1

Sieh dir den Seitenquelltext genau an.

Tipp 2

Wenn der Download abbricht, versuche einen anderen Browser, benutze Burp als Proxy oder kopiere den Seitenquelltext.

Tipp 3

ltrace (zum debuggen) und radare2 (zur Analyse des Assembly Codes) können dich an’s Ziel bringen.

Tipp 4

Um an /root/root.txt zu kommen gibt es 3 verschiedene Methoden.

Video

Kurzes Video Walkthrough ohne Erklärungen

Anleitung

Schritt 1

Als erstes machen wir wie gewohnt einen Nmap-Scan.

2 offene Ports  wurden  gefunden. SSH und auf Port 3000 eine Node.js Webseite.

Schritt 2

Wenn wir uns  den Seitenquelltext ansehen, können wir ganz unten Verweise auf Javascripts finden.

Sehen wir uns home.js mal an.

In Zeile 4 wird auf /api/users/latest zugegriffen. Unter 10.10.10.58:3000/api/users/latest sehen wir 3 Benutzer mit ihrer jeweiligen _id, username, password und is_admin. Wobei das password jeweils ein Hash zu seien scheint.

Allerdings ist hier keiner der Benutzer ein Admin. Sehen wir uns darum mal /api/users/ an.

credentials

Hier ist ein Admin Account zu sehen und zwar myP14ceAdm1nAcc0uNT. Kopieren wir uns den Hash und benutzen einen Online Hash Cracker um zu sehen, ob wir das Password herausfinden können. Ich benutze dafür crackstation.net.

Tatsächlich konnte es das Password herausfinden.

Schritt 3

Melden wir uns nun als myP14ceAdm1nAcc0uNT mit dem Passwort manchester an und laden uns das Backup herunter.

backup

Falls der Download bei dir immer wieder abbrechen sollte gibt es 3 Möglichkeiten wie du dieses beheben kannst.

  1. Versuche einen anderen Browser
  2. Benutze Burp als Proxy
  3. Kopiere den Inhalt von view-source:http://10.10.10.58:3000/api/admin/backup

 

Wenn wir uns den Inhalt von myplace.backup ansehen, können wir sehen, dass es mit Base64 enkodiert wurde. Wir können base64 -d benutzen, um es zu dekodieren.

Sehen wir uns nun den Dateityp von der Datei myplace an, mit der Hilfe von file.

Es handelt sich um eine Zip Datei.

Nennen wir myplace zu myplace.zip um.

Allerdings wird ein Passwort benötigt um die Zip Datei zu öffnen.

Schritt 4

Das Password der Zip Datei können wir bruteforcen. Ich benutze dafür fcrackzip und die rockyou Wortliste, welche sich bei Kali Linux standardmäßig unter /usr/share/wordlists/rockyou.txt befindet.

Das Passwort ist also magicword.

Jetzt können mir myplace.zip entpacken.

Sehen wir uns app.js genauer an.

Es wird anscheinend MongoDB und der Nutzername mark mit dem Passwort 5AYRft73VtFpc84k um sich bei MongoDB anzumelden.

Probieren wir diese Anmeldedaten bei SSH aus.

Es hat tatsächlich funktioniert.

Schritt 5
Unter /home sind noch 2 andere Benutzer zu finden. frank und tom.
2 Prozesse gehören tom. Sehen wir uns /var/scheduler/app.js an.
app.js sucht in der Datenbank tasks nach Einträgen (Zeile 15)  und führt den Inhalt in cmd als Shellbefehl aus (Zeile 19-21).

Da wir die Anmeldedaten für die Datenbank haben und somit neue Einträge machen können, können wir dafür sorgen, dass z.B. ein Reverse Shell Skript ausgeführt wird.

Ich benutze dieses NodeJS Reverse Shell Skript dafür.

Als nächstes nur noch NetCat Port 4444 abhören lassen und IP Adresse und Port im Skript dementsprechend ändern.

Unter /tmp/ können wir das Skript dann mithilfe von VI(M) einfügen.

Nun können wir uns mit der Datenbank verbinden.

Wenn du diese Fehlermeldung bekommen solltest benutze folgendes.

So. 2. Versuch.

Durch db.tasks.insert({cmd: „/usr/bin/node /tmp/reverse.js“}) machen wir einen neuen Eintrag in der Datenbank taskscmd bekommt dabei den Wert /usr/bin/node /tmp/reverse.js, welcher dafür sorgt, dass node unser Reverse Shell Skript ausführt. Zeile 4-6 ist die Bestätigung, dass der Eintrag erfolgreich war.

Jetzt nur noch ein wenig warten, bis unser Eintrag ausgeführt wurde und wir haben Zugriff als tom.

Möchtest du benachrichtigt werden, wenn ein neuer Artikel veröffentlicht wurde?

Schritt 6
find / -perm -u=s durchsucht alle Dateien, nach welchen die von jedem Benutzer ausgeführt werden können und dann die effektive UID des Benutzers der Datei haben. Mehr Informationen dazu kannst du hier finden. 2>/dev/null sorgt einfach dafür, dass alle Fehlermeldungen (z.B. bei Zugriff verweigert) zu /dev/null umgeleitet werden. /dev/null verwirft jegliche Daten, die dorthin geschrieben werden.

/usr/local/bin/backup sieht unüblich aus.

/usr/local/bin/backup ist eine ELF Datei.

Laden wir uns die Datei herunter um sie uns genauer ansehen zu können.

Schritt 7

Mit ltrace können wir das Programm debuggen.

Das Programm beendet mit dem Status  1 und macht sonst nichts nennenswertes. Benutzen wir radare2 um uns den Assembly Source Code anzusehen.

Nachdem wir aaa (analysiere alles), afl (liste alle Funktionen auf) und dann vvv (gehe in den Visuellen Modus) eingegeben haben, sehen wir folgendes.

radare2

Wählen wir nun sym.main mit Hilfe der Pfeiltasten aus. Jetzt 2x g drücken und dann Leertaste. Wenn wir nun etwas runtergehen sehen wir folgendes.

radare2

cmp dword [ebx], 3 ( Das Register ebc wird mit dem Wert 3 verglichen )
jg 0x8048a44;[gc] ( Wenn ebx größer oder gleich 3 ist, wird das Programm weiter ausgeführt, ansonsten wird es beendet.)

Eventuell möchte das Programm 3 (oder mehr) Argumente haben.

( Mit q kannst du radare2 wieder beenden )

Schritt 8

Probieren wir nun das Programm mit 3 Argumenten aus.

In Zeile 6 wird das erste Argument mit -q verglichen ( strcmp(„arg1“, „-q“) = 1 ). Testen wir das aus.

In Zeile 18 wird versucht /etc/myplace/keys zu lesen.

Kopieren wir uns den Inhalt und erstellen bei unserer Maschine die Datei /etc/myplace/keys.

Schritt 9

So jetzt erneut das Programm debuggen.

Das zweite Argument wird mit 3 verschiedenen Strings verglichen. Benutzen wir das Argument -s 100 für ltrace um die Länge der anzuzeigenden Strings zu erhöhen.

Das 2. Argument wird also mit den Strings aus /etc/myplace/keys verglichen.

Benutzen wir nun einen der 3 Strings aus /etc/myplace/keys als 2. Argument.

Das 3. Argument gibt also an, von welchem Verzeichnis ( oder welcher Datei ) eine Zip Datei erstellt werden soll. Dafür wird der Befehl system() benutzt. Außerdem wird das 3. Argument mit .. /root ; & ` $ | // und /etc verglichen. Wenn das 3. Argument einen dieser Strings enthält, bekommen wir eine Zip Datei, welche nur ein Trollface enthält.

Schritt 10

Jetzt gibt es verschiedene Methoden wie wir vorgehen können.

1. Wildcards

Das ist die einfachste Methode. Wir wollen an den Inhalt von /root/root.txt, aber /root ist auf der Blacklist. Um diese zu entgehen können wir Wildcards benutzen.

oder

2. Newline

Zuerst ändern wir den Port bei unserem Reverse Shell Skript /tmp/reverse.js. Dann lassen wir NetCat diesen Port abhören.

Jetzt können wir als 3. Argument \n benutzen, damit system() einen weiteren Befehl ausführt. Z.B. unser Skript.

 

3. Buffer Overflow

Es wird mehrmals strcpy aufgerufen, allerdings wird nicht die Begrenzung überprüft. In der displayTarget Funktion tritt dann ein overflow und ein segfault auf. Damit dies passiert müssen folgende 3 Kriterien erfüllt werden.

  1. Das 1. muss ungleich -q sein, damit das Programm nicht im quiet mode gestartet wird.
  2. Das 2. Argument muss einen gültigen Key enthalten
  3. Das 3. Argument enthält einen 508 characters langen String.

Vielen Dank für’s durchlesen. 🙂

Teilen:

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

    neunzehn − 2 =

    Privacy Preference Center