Starting the box
Link to the box: https://app.hackthebox.com/machines/darkzero
Port Scan
We start off the box by running a port scan on the provided IP.Attacker Linux
Terminal Output
- Port 88 is open, which means this is likely a Windows Domain Controller (DC).
- Port 1433 is open, which is the usual port for MSSQL
- Port 5985 is open, which is the usual port for WinRM.
Edit the Hosts file
As always, we edit the/etc/hosts file to add the hostname:
Attacker Linux
Nano Interface
Initial User
As is common in real life pentests, you will start the DarkZero box with credentials for the following account john.w / RFulUtONCOL!
Attacker Linux
- NLTM authentication is allowed.
- Only default shares are present.
Enumerating Active Directory Environment
Running Bloodhound
Let’s fix our clock synchronization before doing any AD enumerations:Attacker Linux
Attacker Linux
- No outbound control from
john.w. No special groups too. - Only 3 domain users -
john.w, administrator, and krbtgt.
Checking ADCS Attacks
Let’s check if there are any vulnerable ADCS templates:Attacker Linux
- No vulnerable template for our controlled user.
Enumerating MSSQL
Since Port 1433 (MSSQL) is open, we can try our credentials on it to see if our user has access to the MSSQL server:Attacker Linux
MSSQL Client
Trying NTLM coercion with MSSQL
Let’s do force authentication (coercion attacks) to our controlled server withxp_dirtree in MSSQL to see if the obtained hash is crackable.
We’ll use impacket’s smbserver.py to capture the hash:
Attacker Linux
xp_dirtree to list the directory of our SMB server, forcing a NLTM authentication to our server:
MSSQL Client
SMBServer.py
Attacker Windows
- The rockyou.txt was exhausted. Let’s move on to other attack vectors.
Enumerating Linked Servers
Let’s check if there is any linked servers with our MSSQL instance.MSSQL Client
MSSQL Client
- This indicates that we will be authenticated as
dc01_sql_svcwhen interacting withDC02.darkzero.ext.
dc01_sql_svc is sysadmin on DC02.darkzero.ext:
MSSQL Client
Using Linked Server
Using the Linked Server on DC02:
From theimpacket-MSSQL client menu, we can see that there is a use_link procedure.
MSSQL Client
- We are in
DC02now.
MSSQL Client
Enabling XP_CMDSHELL:
Since we are the sysadmin, we have to privilege to enablexp_cmdshell, which would allow us to execute system commands as the MSSQL server.
MSSQL Client
whoami to check which user is running this MSSQL service. It looks like we have a service account.
MSSQL Client
Starting a reverse shell from MSSQL:
Let’s try to run a base64-encoded PowerShell reverse shell payload. However, it was not working properly here and it returned a broken shell.MSSQL Client
MSSQL Client
Enumerating DC02
We first run a quick WinPEAS to see if there is anything interesting. While there was no output that stood out, we can still try to crack the NetNTLMv2 hash of our controlled user regardless. We tried with Hashcat and it cannot be cracked. Let’s move on.WinPEAS Output
WinPEAS Output
Running Ligolo to access the internal network
The easiest way to enumerate the internal network is to run Ligolo on our controlled machine. We will first start the proxy server on our attacker Linux:Attacker Linux
Victim Windows (DC02)
session command in the Ligolo Interface to interact with our connected agent.
Ligolo Interface
Ligolo Interface
add_route command to route our traffic to the corresponding subnet addresses. Here, for example, all traffics on our attacker Linux towards 172.16.20.0/16 will be routed to the victim machine via the ligolo interface, and act as we are on the same subnet as the victim machine.
Ligolo Interface
Running Bloodhound
This time, we will run Bloodhound with the Sharphound Ingestor on the victim Windows machine.Victim Windows (DC02)
Attacker Linux
Victim Windows (DC02)
Running ADCS Enumeration Tools
We will also download theCertify binary on the target Windows.
Victim Windows (DC02)
Enumerate Certificate Authorities:
We will check if the CA on DC02 is vulnerable to ADCS attacks. The output looks normal.Victim Windows (DC02)
Enumerate Vulnerable ADCS Templates:
We will also check if there’re any vulnerable ADCS templates on DC02 is vulnerable. Again, no vulnerable templates were returned.Victim Windows (DC02)
Checking the Policy_Backup.inf file:
We can see that there is a Policy_Backup.inf file in the root directory, which is uncommon.
Victim Windows (DC02)
Policy_Backup.inf file contains the privileges on different accounts:
Policy_Backup.inf Snippet
svc_sql should have SeServiceLogonRight . But running whoami /priv does not return the right.
Our user is also in the S-1-5-6 is the NT AUTHORITY\SERVICE group, but again we are missing the privilege.
Policy_Backup.inf Snippet
whoami /all, we can see that our user is in the NT AUTHORITY\SERVICE group.
Victim Windows (DC02)
NT AUTHORITY\SERVICE has the SID S-1-5-6, in theory our user should have the SeImpersonatePrivilege. However we are missing the privileges. It is likely because our current logon token type has been restricted.
A quick Google on restoring privilege sets for service account returned the following GitHub repo:
This however didn’t work, likely because this was an old way to restore privilege and has likely been patched.
Victim Windows (DC02)
Retrieving NTLM hash of svc_sql
Dumping Cached Kerberos Ticket
After some research, we learn we have restricted privilege as our current token type is in the interactive logon type (2). To restore the service account’s full privilege, we need to login with a service logon type (5) token.- This can be done with a password login using RunasCs.exe to specify the logon type.
- However, we don’t have password now.
klist, we note that we have a cached Kerberos ticket. This is good news since it means that we can likely dump out the ticket for Kerberos authentication.
Victim Windows (DC02)
Changing User Password with NTLM Hash
It is possible to change a user password without knowing the current password. We can do it in two ways:- Using
mimikatz’slsadump::changentlmorlsadump::setntlmmodule on the Victim Windows machine, as long as we know the NTLM hash of the user, and the server accepts NTLM authentication. - Using
impacket’schangepasswd.pytool on the remote Attacker Linux. Works for both Kerberos & NTLM authentication.
We can run
Certify.exe on Windows to extract the valid Kerberos ticket, then either:
- Run
Rubeus.exeon Windows to extract the NTLM hash of the user. - Use the valid ticket to run remote tools like
impacket-changepasswdto directly change the password. In our current scenario, we would also have to run pivoting tools likeLigolo, since the DC is in the unreachable internal network.
Dead-end attempt - Troubleshooting ticket.kirbi from Rubeus (feel free to read along what I did)
Dead-end attempt - Troubleshooting ticket.kirbi from Rubeus (feel free to read along what I did)
Let’s first get Rubeus on the machine.We will dump out the Kerberos ticket in the The KRB-CRED files (Since our reverse shell cannot take the long base64 string, we’ll create the ticket file on Linux, and upload the ticket file to the target system.However, when we try to run Rubeus with the ticket file, the following error was returned:The decoded binary ticket is working now.
Victim Windows (DC02)
.kirbi format.Victim Windows (DC02)
.kirbi) are output as base64 blobs and can be reused with the ptt function, or Mimikatz’s kerberos::ptt functionality.- Here, since the ticket’s LoginType is Service (Type 5), the tickets are non-exportable by default in Service Logon token. Therefore, even though we used the
/outfileflag, no file was generated.
Victim Windows (DC02)
Attacker Linux
Victim Windows (DC02)
Victim Windows (DC02)
- From LLM: This ASN.1 “value overflow” error typically means the ticket you’re feeding into
changepwis not a validKRB_CREDstructure, even if it looks like a ticket.
.kirbi file by itself. We have to decode it into the raw binary:Attacker Linux
Victim Windows (DC02)
Running Certify.exe to request a valid login certificate:
Regardless, we can use Certify.exe to use the current cached ticket on Windows to request for a valid login certificate. We will run theenum-cas module to check the name of the CA, which is darkzero.ext\darkzero-ext-DC02-CA.
Victim Windows (DC02)
Victim Windows (DC02)
Certify.exe output with --out-file:
Victim Windows (DC02)
Victim Windows (DC02)
Victim Windows (DC02)
asktgt module to extract the user’s NTLM hash using the /getcredentials flag. We have now extracted the svc_sql user’s NTLM hash, and we will use that to obtain a cleartext password for changing our logon type.
Victim Windows (DC02)
Changing svc_sql’s password with NTLM
We can usemimikatz’s lsadump::changentlm module to change our password using NLTM auth: changentlm | The Hacker Tools.
Victim Windows (DC02)
mimikatz console
Logging in with Logon Type 5 (Service)
With the new password, we can now useRunasCs.exe:
Victim Windows (DC02)
--bypass-uac to spawn the process without token limitations. This will essentially give us back our privileges.
Victim Windows (DC02)
Victim Windows (DC02)
Escalating to SYSTEM with SeImpersonatePrivilege
Getting GodPotato on the victim machine
With theSeImpersonate privilege, we can escalate our privilege to system using potato exploits. Here we’ll use GodPotato:
Victim Windows (DC02) - New Shell from RunasCs.exe
.NET version of the GodPotato binary has to match with the .NET version installed on the target machine. We can check that with the following command.
Victim Windows (DC02) - New Shell from RunasCs.exe
Running God Potato
While you can do things like starting a reverse shell, I prefer adding a new administrator user, sinceGodPotato often cannot run stable reverse shells.
Victim Windows (DC02) - New Shell from RunasCs.exe
Switching to the admin shell
We will run the reverse shell with our new administrator user usingRunasCs.exe again.
Victim Windows (DC02) - New Shell from RunasCs.exe
Victim Windows (DC02) - System Shell from RunasCs.exe
Unintended Path (CVE_2024_30088)
Exploiting Unpatched Windows Kernel Vulnerability
There is also an unintended privilege escalation path that exploits a kernel vulnerability. This can be discovered via Metasploit’slocal_exploit_suggester module.
We first generate a Meterpreter reverse shell payload for Windows. We then upload the generated payload to DC02.
Attacker Linux
msfconsole
windows/x64/shell_reverse_tcp as the payload and set up a non-Meterpreter listener to make things easier.
msfconsole
Victim Windows (DC02)
Privilege Escalation
There is a
cleanup.ps1 file in the Documents folder of the darkzero.ext admin.
- Nothing of special interest. Just for cleaning up the box.
Dumping Administrator NTLM hash from DC02
Extracting SAM hive & System
With the system shell, we can dump the SAM hive locally to extract NTLM hashes. We will then use the same file transfer method to copy the dumped hives to our SMB share.Victim Windows (DC02)
impacket’s secretsdump.py.
Attacker Linux
mimikatz’s lsadump::sam module.
Victim Windows (DC02)
NetExec’s LDAP module. Note that we are directly authenticating to DC01 with the administrator credentials of DC02.
Attacker Linux
Enumerating Forest Trust
Since we are in a forest environment, we should enumerate the trust relationships & potential delegations between domains.Searching for Unconstrained Delegation with NetExec
We can useNetExec’s built-in module to enumerate delegation (https://www.netexec.wiki/ldap-protocol/unconstrained-delegation). As we can see, the DC01$ machine has the flag TRUSTED_FOR_DELEGATION set.
Attacker Linux
Enumerating Domain Trust with NetExec
We can also useNetExec’s built-in module to enumerate domain trust (https://www.netexec.wiki/ldap-protocol/dc-list). We can read more about Domain Trust here: Trusts | The Hacker Recipes.
Attempting to request for login certificate as Administrator
Since we have cross-forest trust, maybe we can directly request for a domain administrator TGT? The answer is no, and this will fail since this is not how cross-domain trust works. Our DC02 admin credentials do not grant us domain administrator rights on DC01.Attacker Linux
Attacker Linux
Abusing Unconstrained Delegation
After some Googling, we came across a great article on explain how we can abuse cross-forest trusts. Essentially, in a two-way (bidirectional) trusted forest, users from one forest can authenticate to another forest’s resource. Kerberos TGT issued by either forest can also flow between forest.- If we controlled one of the forest, and a privileged user of the other forest authenticate to our controlled forest with their TGT due to the trust relationship, we can capture and dump their ticket.
- With the privileged ticket, we can then authenticate to the original forest as the privileged user.
- Combining this with coercion attacks, we can essentially force the Domain Controller of target forest to authenticate to our controlled forest DC, and capture the TGT of the DC machine.
Rubeus.exe on DC02 in an elevated shell (i.e. system shell).
Victim Windows (DC02) - System Shell
SpoolSample.exe on another shell on DC02. Unfortunately this didn’t work, as the printspooler service was not running on the machine.
Victim Windows (DC02)
Check if the target is vulnerable to Force Authentication
Luckily,NetExec has a module that can perform all coerce attacks. While DC02 is not vulnerable to the printer bugs, it is vulnerable to the other coercion attacks.
Attacker Linux
Running the Force Authentication attack
Again, on our System shell of DC02, we can run Rubeus’s monitor module to capture any incoming authentication to capture their TGT.Victim Windows (DC02) - System Shell
-o flag is used to specify the module options. Here, we have to set the L= for the target listener, i.e., where the victim machine will be authenticating to.
Attacker Linux
Using the Captured TGT
We successfully got our TGT on the Rubeus monitor after triggering the coercion attacks. This is the Base64 encoded blob of the TGT ofDC01$.
Rubues Output
DC02$).
Victim Windows (DC02) - System Shell
klist command:
Victim Windows (DC02) - System Shell
Dumping Credentials with DCSync
Lastly, with the injected DC01$ machine TGT, we can perform a DCSync attack on DC01 usingmimikatz. Remember to run privilege::debug to ensure we have enough privileges. We have successfully dumped NTLM hash of the Administrator of DC01.
Victim Windows (DC02) - System Shell
NetExec.
Attacker Linux
Key Learning
1. Enumerate MSSQL Linked Servers
There is a built-in function,use_link in impacket’s mssqlclient.py, which makes interaction with linked servers way easier.
2. Always look for cached Kerberos tickets
The cached tickets can be dumped out be used on Linux, or to retrieve the NTLM hash if it belongs to a service account.3. Retrieve NTLM hash with Kerberos Ticket
Using the “UnPAC the hash” technique, we can retrieve the NTLM hash of a controlled service account by retrieve its Kerberos ticket (either by dumping or requesting), request a client-authentication certificate, and request a TGT to extract the NTLM hashes within the ticket. We can achieve this by Certify.exe + Rubeus.exe on Windows.Victim Windows (DC02)
- The cached ticket is used automatically if we are running this on the machine.
Victim Windows (DC02)
Victim Windows (DC02)
/getcredentials flag:
Victim Windows (DC02)
4. Using Regex with Certify & Rubeus Output to extract Base64 values
We can use Regex to extract only the Base64 value from the output:Victim Windows (DC02)
Victim Windows (DC02)
5. Changing Password with NTLM using Mimikatz
We can usemimikatz’s lsadump::changentlm module to change our password using the NLTM hash: changentlm | The Hacker Tools
Victim Windows (DC02)
6. Enumerate Windows Kernel Local Privilege Escalation (LPE) vulnerabilities
With Meterpreter shell, we can runpost/multi/recon/local_exploit_suggester to check for all local privilege escalation vulnerabilities in Metasploit.
7. Unconstrained Delegation
For 2-way Cross Forest Trusts, we can abuse Unconstrained Delegation to obtain the TGT of another domain’s DC.- Basically we run a listener on our controlled DC, and force the target DC in the other forest to authenticate to our controlled DC. Since 2-way cross forest trusts are established, the target DC will authenticate to us using the same TGT that it will be using in it’s own forest. By capture the TGT, we can authenticate to the target forest as the target DC.

