In this Walkthrough, we will be hacking the machine Sauna from HackTheBox.
We will start with some domain specific enumeration with no credentials, hunting for anonymous access. An anonymous LDAP search will reveal our first user ‘hsmith’. Unable to AS-REP roast the user, we’ll continue enumeration on the HTTP server.
Enumerating the website running on the HTTP server, we find a list of team members, which provides us with our second valid user ‘fsmith’. Unlike ‘hsmith’, the user ‘fsmith’ is AS-REP roastable and we are able dump / crack their AS-REP hash. Once cracked, we use the password to access the DC over WinRM.
Once a foothold has been established, we will continue with more domain specific enumeration. After a few unsuccessful checks as well as discovering a kerberoasting rabbit hole, we’ll load up Bloodhound and find that the optimal path to pwn the DC will require access to the service account ‘svc_loanmgr’.
After mapping out the next steps of the attack, we will need to hunt locally for the password to the service account, which we will find in the AutoLogon registry key. Once a password for the service account has been discovered, we’ll log into the account over WinRM and then perform a DCSync attack using Invoke-Mimikatz.ps1 to dump the Domain Administrator account’s NTLM hash.
Armed with the Administrator hash, we own the DC and a simple pass-the-hash attack grants us shell access to the DC so that we can grab the flags.
— nmap TCP full —
nmap -A -sV -sC -T4 10.10.10.175 -p- -oN full_tcp.nmap
— gobuster – port: 80 —
gobuster dir -u http://10.10.10.175 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x asp,aspx,php,txt -t 80 > gobuster.txt
— nikto – port: 80 —
nikto -h http://10.10.10.175 > nikto.txt
Review of Open Ports
Lots of interesting TCP ports open; and it was observed that this is an AD machine, and even more specifically a Domain Controller (DC).
- Port 53 is open and is hosting a DNS service over TCP – version: Microsoft DNS 6.1.7601 (1DB15D39)
- Port 80 is open and is hosting an HTTP server – Microsoft IIS httpd 10.0 – Egotistical Bank :: Home
- 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 open and hosting the LDAP/S services respectively
- Port 464 is open are hosting a Kerberos password change service, typically seen on DCs and generally not of much interest.
- Ports 593 and 5722 are open and are hosting RPC services.
- Port 5985 is hosting the WinRM service, which will be good if credentials are found.
- Port 9389 is hosting the .NET Message Framing service.
- Ports 49xxx are hosting the high port RPC services.
From the nmap scan we can see this is a Domain Controller with a hostname of Sauna and that this is the DC for the domain Egotistical-bank.local.
Message signing is also enabled on the DC; however, we will not be doing any lateral movement in the example so, that will not be important.
Enumeration and Initial Exploit
Since this is a Domain controller, enumeration will be split into two sections: domain specific service enumeration and regular service enumeration.
Enumerating Services Specific to a Domain Controller
Enumeration will begin by attempting to get a Zone Transfer from the DNS server.
dig @10.10.10.175 AXFR Egotistical-bank.local
The zone transfer attempt was unsuccessful, so next I will move on to the kerberos service.
Targeting the Kerberos service, I tested for a quick No-Preauth win without supplying a username.
GetNPUsers.py Egotistical-bank.local/ -dc-ip 10.10.10.175
Finding User ‘hsmith’ with an Anonymous LDAP Search
Unable to find much from Kerberos without any credentials, I will move on to the LDAP service and see if I can dump information from an anonymous session.
ldapsearch -x -H ldap://10.10.10.175 -b "dc=Egotistical-bank,dc=local"
Dumping all the domain objects, I can see I found a username! Well, it actually looks more like the users name rather than their NTID.
I also checked for the Certification Authorities object to try and get a quick win with CVE-2022-26925. However, this machine does not appear to have AD CS running.
CVE-2022-26925 should be part of your no credentials (anonymous access) checks. The attack requires AD CS to be turned on. Details about the vulnerability can be found here.
When it comes to assigning usernames, most companies use standard naming conventions like <first initial><lastname>.
Knowing this, I started a users.txt file and added the user’s name as an NTID using a few different common conventions.
Next, I tried running this list through kerbrute.py to see if I got a valid username.
kerbrute.py -users ./users.txt -dc-ip 10.10.10.175 -domain Egotistical-bank.local
Cool! I got a valid username. Unfortunately, the user does not have “NOT PREAUTH” so they aren’t AS-REP roastable.
This means I will need to keep looking for more usernames and/or passwords.
Continuing Domain Enumeration
Next, I attempted to enumerate the RPC service and SMB shares using an anonymous session.
rpcclient 10.10.10.175 -N smbclient -L 10.10.10.175 -N
Starting with RPC client, anonymous access was denied. However, SMB did allow anonymous access, but it did not show the shares.
Since the shares were not listed, I tried to list them using the following nmap script. Unfortunately, there were no custom shares and anonymous access to all of the shares was denied.
nmap 10.10.10.175 --script=smb-enum* -p445
The script failed, so it doesn’t look like SMB will provide anything until valid credentials are found.
Moving ahead, I have exhausted my “no credentials” enumeration and also found that the one username I did find was not AS-REP roastable.
At this point I can start trying to password spray the user I did find; however, I would rather pause on the domain enumeration and check out the HTTP server on port 80.
HTTP Server Enumeration
Earlier I ran gobuster and nikto scans against the web server running on port 80, but I got nothing good from either scan.
Since the scans came up dry, I navigated to the home page of the website in the browser to have closer look and do some manual enumeration.
Right away I spot 3 places that could potentially reveal more employees names.
Checking the About Us page first, I scrolled through and at the bottom, I hit the jackpot! Six more potential users.
Armed with the knowledge of the NTID naming convention from earlier, I took all of these names and added their usernames to the users.txt file.
Navigating the pages on the website for a bit, I did not come across much of interest, so I decided it was time to take my findings and see if I found more valid users.
Now that I have more users in my users.txt file, I checked which ones are valid with kerbrute.py again.
kerbrute.py -users ./users.txt -dc-ip 10.10.10.175 -domain Egotistical-bank.local
Amazing! Although, only one of the six usernames was valid… it has “NOT PREAUTH”, which mean means this account is AS-REP roastable!
AS-REP Roasting User ‘fsmith‘
Since I found an AS-REP roastable user, I can now request the user’s hash and crack it!
GetNPUsers.py Egotistical-bank.local/fsmith -dc-ip 10.10.10.175 -request -no-pass
This is not a standard NTLM hash, so I will need to crack it, so I copied it in full and pasted it into a file named hash.txt.
Now that I have the hash in a file and it’s ready for cracking, I will use hashcat to crack it.
To learn more about AS-REP roasting, check out my post on the topic here.
Cracking an AS-REP Hash with Hashcat
I used hashcat first to find the cracking mode for this hash type, and then proceeded to crack it.
hashcat -h | grep -i "AS-REP" hashcat -m 18200 ./hash.txt /usr/share/wordlists/rockyou.txt -o cracked.txt
And after only 8 short seconds, the password is cracked!
Checking the output file, I recover the password for user fsmith.
fsmith : Thestrokes23
Next, I can runt these credentials through kerbrute.py and see if they are actually valid.
kerbrute.py -user 'fsmith' -password 'Thestrokes23' -dc-ip 10.10.10.175 -domain Egotistical-bank.local
Seeing the “Stupendous” message here tells me these are valid credentials.
Great! With a valid set of credentials, I can now perform much deeper enumeration with an authenticated session to services like kerberos, LDAP, SMB, and WinRM.
Domain Enumeration Continued with Valid Credentials
First, I want to test access on SMB and WinRM to see if there is a foothold opportunity.
crackmapexec smb 10.10.10.175 -u "fsmith" -p "Thestrokes23" -d Egotistical-bank.local crackmapexec winrm 10.10.10.175 -u 'fsmith' -p 'Thestrokes23' -d Egotistical-bank.local
Amazing! Not only does this show me that I can access the SMB shares with this user, but the user also has WinRM access, which means I can either go straight to a foothold or continue to enumerate externally.
Gaining a Foothold as fsmith Using evil-winrm
Since I can remote into the host over WinRM, I decided to grab a shell using evil-winrm
evil-winrm -i 10.10.10.175 -u fsmith -p Thestrokes23
Post Exploitation Enumeration and Privilege Escalation
Just like the initial enumeration, because this is a Domain controller, post-exploitation enumeration will be split into two sections: domain specific enumeration and regular enumeration.
95% of the time the privilege escalation technique used in a domain will be domain-based.
Domain Specific Post-Exploitation Enumeration
Before really diving into the domain specific enumeration, I like to quickly get information on the system (OS version) and the current users privileges.
systeminfo | findstr /B /C:"Host Name" /C:"OS Name" /C:"OS Version" /C:"System Type" /C:"Hotfix(s)"
Looks like I do not have permission to run systeminfo.exe.
Moving on to current user privileges…
Not much to work with in terms of permissions.
Alright, now that I tried to get info on the system and the current users privileges, now I can proceed with domain specific enumeration.
First, I grabbed a list of all the domain users with the following command:
net user /domain
Apart from the two users I have already enumerated, I have found the built-in Administrator, the kerberos ticket granting krbtgt account, and service account svc_loanmgr.
I updated my users.txt file with my findings and then continued to enumerate the current user.
net user fsmith /domain
No interesting domain or local group memberships. I can see Remote Management Users but that is what allows this user access over WinRM.
Kerberoasting Fail Against User ‘hsmith’
Moving on, I want to check for kerberoastable users, so I will upload a copy of rubeus.exe onto the victim using evil-winrm’s builtin upload feature.
With Rubeus on the victim, I executed a kerberoasting attack with the following command:
Rubeus was able to find that the account hsmith was kerberoastable; however, when trying to request the SPN it had an error stating no credentials are available.
To confirm this was not working, I also tried uploading Invoke-Kerberoast.ps1 and executing it, but that too failed.
To see various ways to perform kerberoasting, check out my post on it here.
Since I did not check the SMB shares yet, I decided to head back to my attacker machine and see what share files are available.
smbclient -L 10.10.10.175 -U "Egotistical-bank.local/fsmith"
The custom share looks interesting ‘RICOH Aficio SP’. SYSVOL is interesting if this is a version of Windows Server that uses the Groups.xml file.
Testing access to the custom share first…
smbclient "\\\\10.10.10.175\\RICOH Aficio SP 8300DN PCL 6" -U "Egotistical-bank.local/fsmith"
I gained access; however I was not able to view anything, so I tried SYSVOL next.
smbclient \\\\10.10.10.175\\SYSVOL -U "Egotistical-bank.local/fsmith"
After gaining access, I ran the same commands as I did when accessing the custom share, which allow me view all files and folders in the share recursively and to not prompt me when I perform a “get” request.
recurse on prompt off ls
Looking over the share, there is only standard policy files and nothing of interest here.
Finding the Shortest Path to Pwn the DC with Bloodhound
Continuing with domain enumeration, the next thing I want to do is use bloodhound to view what paths are available to admin.
I uploaded SharpHound.exe onto the victim and then executed it to collect all of the domain info.
Next I used the built-in download feature of evil-winrm to download the ZIP file onto my attacker machine.
Once on my attacker machine, I extracted the ZIP and then started up neo4j and bloodhound.
After confirming that all of the JSON files were created, I fired up both the neo4j and bloodhound consoles and uploaded the JSON files into the graphing system to get a good look at the rights and relations in the domain.
sudo bloodhound sudo neo4j console
Once uploaded, I utilized the pre-built queries under the Analysis tab to find information about the domain.
Right away I like to scroll down and check the “Shortest Paths to High Value Targets” query.
This is interesting! It tells me that the user svc_loanmgr can perfrom a DCSync attack against the domain and has the rights to PSRemote into the DC.
Using a few more of the built-in queries, I did not see any interesting information about the current user so I will need to find a way to get access as svc_loanmgr.
Manually Hunting for svc_loanmgr’s Password Locally
Since I did not find much that I could do with user fsmith on the domain, I want to enumerate the DC locally to try and find credentials for the service account.
First I checked if there are any stored credentials on the DC.
Nothing was found, so I decided to check the PowerShell history file.
The PowerShell history file does not exist, which indicates the user never used PowerShell before.
Moving on, I checked the AutoLogon registry key with the following command:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon"
BOOM! The credentials for the service account were found in the AutoLogon registry!
EGOTISTICALBANK\svc_loanmanager : Moneymakestheworldgoround!
To learn more about manual password hunting, check out this post here.
Getting a Shell as ‘svc_loanmgr’
Armed with the service account credentials, and I know this account can perform a DCSync attack and PSRemote onto the DC, I will get a shell using evil-winrm and then upload Invoke-Mimikatz.ps1 onto the victim to perform this attack.
evil-winrm -i 10.10.10.175 -u 'svc_loanmgr' -p 'Moneymakestheworldgoround!'
Dumping the Administrator NTLM Hash using Invoke-Mimikatz.ps1
Now that I have a shell, I can upload Invoke-Mimikatz.ps1 and then load it into my current session with dot sourcing.
Once Mimikatz is loaded into the current session, I can run the following command to dump the built-in domain Administrator accounts hash using a DCSync attack:
Invoke-Mimikatz -Command '"lsadump::dcsync /domain:Egotistical-bank.local /user:Administrator"'
Administrator : 823452073d75b9d1cf70ebdf86c7f98e
NOTE: To dump all hashes in the domain, replace the ‘/user:’ switch with ‘/all’.
Now I can take these credentials and perform a pass-the-hash attack and get a shell as the domain Admin.
evil-winrm -i 10.10.10.175 -u Administrator -H 823452073d75b9d1cf70ebdf86c7f98e
To learn more about pass-the-hash attack’s, check out my post on the topic here.