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 na portu
21, - webová aplikace na portu
80, - lokálně spravovaný NSClient++ na portu
8443.
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ů
- Anonymní FTP zde nesloužilo jako přímý vstup, ale jako zdroj informace, která navedla na správný soubor ke čtení přes traversal.
- Webová zranitelnost v NVMS-1000 byla vektorem pro čtení citlivých souborů, ne pro přímý shell. Praktickou hodnotu získala až ve chvíli, kdy odkryla funkční hesla.
- SSH přístup jako
Nadinebyl stabilní mezistupeň, který umožnil pracovat s interní službou na localhostu. - NSClient++ se stal privesc vektorem proto, že chránil výkonné API jen statickým heslem uloženým v lokální konfiguraci.
Co si odnést do praxe
- Veřejně dostupné odkladiště typu anonymní FTP může prozradit víc než samotná aplikace. Interní poznámky, názvy souborů a workflow často stačí k přesnému zacílení dalšího útoku.
- Directory traversal je potřeba hodnotit jako plnohodnotný bezpečnostní incident, i když z něj nevznikne okamžitý shell. Únik konfiguračních a desktopových souborů často vede k heslům a dalšímu přístupu.
- Interní administrační rozhraní nejsou bezpečná jen proto, že naslouchají na
127.0.0.1. Jakmile útočník získá běžný účet, port forwarding z nich udělá normálně dosažitelnou službu. - API, které umí nahrát a spustit vlastní skript, musí být chráněné silněji než jedním heslem v konfiguračním souboru. Jinak se z monitoringu stává vzdálený execution engine.