Series · 3 partsActive Directory Architecture & InternalsPart 2 · You are here
  1. 1Multi-Forest Active Directory Architecture: How Forests, Trusts, DNS, and Tiered Services Actually Work
  2. 2Inside Kerberos Delegation: Why Multi-Tier Windows Apps Need It (and Why It Breaks)You are here
  3. 3Active Directory as a Directed Graph: How Security Descriptors and Object ACLs Actually Work

The Kerberos Double-Hop Problem in Enterprise Architecture

In standard single-hop Kerberos authentication (RFC 4120), a domain client authenticates to the Key Distribution Center (KDC) via an AS-REQ exchange, acquires a Ticket Granting Ticket (TGT), and submits a TGS-REQ for a target service. The application server (such as an IIS web portal on CASTELBLACK at 192.168.56.22) decrypts the resulting Service Ticket (TGS) using its own long-term secret key, establishing the client’s identity through the embedded Privilege Attribute Certificate (PAC).

The architectural failure occurs when that middle-tier application server must interact with an autonomous back-end resource (such as a database server or an SMB file share on WINTERFELL at 192.168.56.11) within the security context of the authenticated user.

Because Kerberos service tickets are strictly encrypted with the intermediate service’s secret key (HTTP/castelblack), CASTELBLACK cannot simply forward the incoming ticket to WINTERFELL. The receiving service would fail to decrypt the ticket and reject the connection. Furthermore, the application server does not possess the caller’s cleartext password or master key, precluding it from initiating an independent AS-REQ or TGS-REQ on the user’s behalf.

To address this double-hop boundary, Microsoft engineered three successive generations of Kerberos delegation. Each iteration attempts to resolve the tension between operational multi-tier functionality and least-privilege boundary enforcement.

THE DOUBLE-HOP PROBLEM · THREE GENERATIONS OF KERBEROS DELEGATION THREE GENERATIONS OF ACTIVE DIRECTORY KERBEROS DELEGATION 1 · Unconstrained (Win2000) UAC: 0x80000 (524288) Client embeds full TGT in AP-REQ TGT cached in LSASS on front-end Risk: Front-end can impersonate anywhere Defense: Protected Users / NO_DELEGATION 2 · Constrained / KCD (2003) msDS-AllowedToDelegateTo Lives on front-end account S4U2Self (Protocol Transition) + Proxy Scoped strictly to explicit target SPNs Requires Domain Admin to configure 3 · Resource-Based (2012) msDS-AllowedToActOnBehalf... Security Descriptor on back-end target Back-end resource owner decides trust GenericWrite on host = Local Admin Works across domain boundaries THE DOUBLE-HOP BOUNDARY · HOW S4U PROTOCOL TRANSITIONS REACH THE TARGET [CLIENT / CALLER] samwell.tarly Domain User · Client Authenticates to web portal Requests HTTP/castelblack Hop 1: TGS Issued Hop 1 [MIDDLE TIER · FRONT-END] CASTELBLACK$ / jon.snow IIS Web Server · 192.168.56.22 Cannot forward client TGS Invokes S4U2Self + S4U2Proxy Mints ticket for CIFS/winterfell Hop 2 [BACK-END TARGET] DC02 · winterfell CIFS / SQL · 192.168.56.11 Validates Delegation ACL Executes as samwell.tarly Access Granted / Enforced EVOLUTION: Unconstrained exposes full TGT ➔ Constrained locks target SPN ➔ RBCD transfers trust to target DACL
The three Kerberos delegation models across the two-hop boundary: Unconstrained forwards a live TGT; Classic Constrained (KCD) restricts outgoing SPNs on the middle-tier object; Resource-Based (RBCD) moves the trust decision onto the back-end resource itself.

1. Generation 1: Unconstrained Delegation (TRUSTED_FOR_DELEGATION)

Windows 2000 implemented delegation by allowing the client to delegate its primary authentication token directly to the intermediate server.

When a computer or user account has the TRUSTED_FOR_DELEGATION bit set (0x80000 / 524288) in its userAccountControl attribute, the KDC inspects this flag during ticket requests.

Querying GOAD via LDAP bitwise matching (1.2.840.113556.1.4.803 for LDAP_MATCHING_RULE_BIT_AND):

$ ldapsearch -x -H ldap://192.168.56.10 -D "[email protected]" -w "Heartsbane" \
    -b "DC=sevenkingdoms,DC=local" "(userAccountControl:1.2.840.113556.1.4.803:=524288)" \
    sAMAccountName dNSHostName userAccountControl | grep -E "^(sAMAccountName|dNSHostName|userAccountControl)"
sAMAccountName: KINGSLANDING$
userAccountControl: 532480
dNSHostName: kingslanding.sevenkingdoms.local

The resulting userAccountControl value 532480 represents 0x80000 (TRUSTED_FOR_DELEGATION) | 0x2000 (SERVER_TRUST_ACCOUNT).

Protocol Mechanics and Exploitation Dynamics

  1. When a client requests a service ticket for an unconstrained host, the KDC sets the OK-AS-DELEGATE flag in the TGS-REP.
  2. The client’s Kerberos Security Support Provider (Kerberos SSP) requests a forwardable TGT (KRB_TGS_REQ with forwardable flag).
  3. The client embeds this delegated TGT inside the KRB_CRED structure within the GSS-API authenticator checksum of the AP-REQ exchange.
  4. Upon decrypting the AP-REQ, the intermediate server extracts the caller’s TGT and caches it directly inside the Local Security Authority Subsystem Service (LSASS) process memory under the caller’s LSA Logon Session.
  5. The intermediate server can now use this cached TGT to request service tickets to any service on any host across the entire Active Directory forest as that caller.

If unconstrained delegation is granted to any non-Domain Controller member server, an attacker with local administrative privileges on that host can execute coercion primitives (such as MS-RPRN RpcRemoteFindFirstPrinterChangeNotificationEx or MS-EFSR EfsRpcOpenFileRaw). Coercing authentication from a Domain Controller machine account (DC01$) forces it to deposit its machine account TGT into the compromised host’s LSASS memory, immediately enabling forest root takeover via DCSync.


2. Generation 2: Classic Constrained Delegation (KCD / [MS-SFU])

Windows Server 2003 introduced the Service for User ([MS-SFU]) protocol extensions to eliminate middle-tier caching of unconstrained TGTs. Under Constrained Delegation, the middle-tier server is restricted to requesting service tickets for a predefined, explicit list of Service Principal Names stored in the msDS-AllowedToDelegateTo attribute.

$ ldapsearch -x -H ldap://192.168.56.11 -D "[email protected]" -w "Heartsbane" \
    -b "DC=north,DC=sevenkingdoms,DC=local" "(msDS-AllowedToDelegateTo=*)" \
    sAMAccountName userAccountControl msDS-AllowedToDelegateTo | grep -E "^(sAMAccountName|userAccountControl|msDS-Allowed)"
sAMAccountName: CASTELBLACK$
userAccountControl: 4096
msDS-AllowedToDelegateTo: HTTP/winterfell.north.sevenkingdoms.local
msDS-AllowedToDelegateTo: HTTP/winterfell

sAMAccountName: jon.snow
userAccountControl: 16842752
msDS-AllowedToDelegateTo: CIFS/winterfell.north.sevenkingdoms.local
msDS-AllowedToDelegateTo: CIFS/winterfell

Protocol Transition (S4U2Self) and Constrained Proxy (S4U2Proxy)

Classic Constrained Delegation operates under two distinct modalities governed by userAccountControl:

  1. Standard Constrained Delegation (Kerberos Only - CASTELBLACK$, UAC = 4096): CASTELBLACK$ possesses WORKSTATION_TRUST_ACCOUNT (0x1000) without protocol transition. It is restricted strictly to S4U2Proxy: it must supply a valid forwardable Kerberos service ticket (evidence ticket) received from an authentic client who logged in over Kerberos.
  2. Constrained Delegation with Protocol Transition (jon.snow, UAC = 16842752): Account jon.snow carries bit 0x1000000 (TRUSTED_TO_AUTH_FOR_DELEGATION). This bit enables Protocol Transition, designed for environments where clients authenticate to web front-ends via NTLM, SAML, or web forms without obtaining a Kerberos ticket:
S4U2SELF + S4U2PROXY PROTOCOL TRANSITION SEQUENCE 1 · Compromised Service jon.snow (UAC: 0x1000000) 2 · KDC (S4U2Self) PA-FOR-USER: Administrator 3 · KDC (S4U2Proxy) TGS → CIFS/winterfell 4 · Target Host WINTERFELL$ as Admin 1-2: S4U2Self mints forwardable evidence TGS · 3-4: S4U2Proxy exchanges it for CIFS/winterfell TGS
Protocol Transition jon.snow invokes S4U2Self (PA-FOR-USER) to obtain a forwardable ticket on behalf of Administrator, then presents it in S4U2Proxy (additional-tickets) to obtain a CIFS/winterfell service ticket.

Attack Vector: SPN Service-Class Substitution (sname Mutation)

Kerberos ticket verification contains an architectural decoupling:

  • In a TGS-REP, the target service identity appears in two locations: the outer unencrypted sname field (Ticket.sname) and the inner PAC signature fields.
  • When Target Host validates an incoming AP-REQ, it decrypts the ticket using its host secret key (WINTERFELL$). Because all services running on winterfell under the machine account (CIFS, HOST, LDAP, HTTP) share the identical machine account key, the ticket decrypts successfully regardless of the service class.
  • Tools such as Rubeus tgssub or impacket-tgssub rewrite the unencrypted outer sname from CIFS/winterfell to LDAP/winterfell. Because the KDC signs the PAC but does not cryptographically bind the outer sname to the service class, the target DC accepts the ticket over LDAP, granting immediate DCSync rights.

3. Generation 3: Resource-Based Constrained Delegation (RBCD)

Classic Constrained Delegation posed a significant administrative challenge: because msDS-AllowedToDelegateTo is an outbound permission configured on the front-end service, establishing delegation required Domain Admin credentials (SeEnableDelegationPrivilege).

Windows Server 2012 reversed the control model with Resource-Based Constrained Delegation (RBCD). Under RBCD, the authorization logic moves entirely to the back-end target computer. The target host defines which front-end services can delegate to it by writing a binary Security Descriptor to its own msDS-AllowedToActOnBehalfOfOtherIdentity attribute.

# Active Directory Machine Account Quota Configuration
$ ldapsearch -x -H ldap://192.168.56.10 -D "[email protected]" -w "Heartsbane" \
    -b "DC=sevenkingdoms,DC=local" -s base ms-DS-MachineAccountQuota | grep ms-DS-MachineAccountQuota
ms-DS-MachineAccountQuota: 10

Protocol Dynamics: The Non-Forwardable Ticket Exception

The critical architectural characteristic of RBCD is how the KDC processes S4U2Self tickets when TRUSTED_TO_AUTH_FOR_DELEGATION is absent:

  1. Any standard computer account (such as one created through ms-DS-MachineAccountQuota) can execute an S4U2Self request impersonating Administrator.
  2. Because the requesting machine account lacks TRUSTED_TO_AUTH_FOR_DELEGATION (0x1000000), the KDC marks the issued service ticket as non-forwardable (forwardable: 0).
  3. Under Classic Constrained Delegation, submitting a non-forwardable ticket into S4U2Proxy fails with KDC_ERR_BADOPTION.
  4. Under RBCD, the KDC inspects the target host’s msDS-AllowedToActOnBehalfOfOtherIdentity DACL. If the caller’s SID is present in the target’s DACL, the KDC explicitly overrides the non-forwardable check, issuing a valid delegated service ticket for the target host.

Consequently, any Active Directory principal possessing GenericWrite, GenericAll, or WriteProperty (msDS-AllowedToActOnBehalfOfOtherIdentity) over a computer object can execute an RBCD attack to achieve local administrator access on that computer.


Telemetry and Defensive Engineering

Delegation Event Telemetry Matrix

Event IDLog ProviderEvent NameTechnical Context
4769SecurityKerberos Service Ticket OperationsService Name matches krbtgt or target SPN; Ticket Options contain 0x40810010 (Constrained Delegation / S4U).
4768SecurityKerberos TGT RequestMonitored for anomalous PreAuthType = 16 or unexpected machine accounts requesting forwardable TGTs.
5136Directory ServiceDirectory Object ModifiedAttribute msDS-AllowedToActOnBehalfOfOtherIdentity or msDS-AllowedToDelegateTo written to directory objects.
4741SecurityComputer Account CreatedMonitors standard user accounts exploiting ms-DS-MachineAccountQuota to provision rogue machine accounts.
// KQL Query: Detect Suspicious RBCD Security Descriptor Modifications
SecurityEvent
| where EventID == 5136
| where AttributeLDAPDisplayName =~ "msDS-AllowedToActOnBehalfOfOtherIdentity"
| project TimeGenerated, Computer, SubjectUserName, ObjectDN, AttributeValue

Remediation and Hardening Protocols

  1. Disable Machine Account Quota: Set ms-DS-MachineAccountQuota to 0 across all domains to prevent standard users from provisioning machine accounts.
  2. Apply Protected Users Security Group: Place administrative accounts in CN=Protected Users,CN=Users,DC=.... Members of this group cannot be delegated via unconstrained or constrained delegation (bForwardable is enforced to false).
  3. Configure NOT_DELEGATED Flag: Set the Account is sensitive and cannot be delegated flag (userAccountControl bit 0x100000) on all Tier-0 service and user accounts.
  4. Audit Cross-Service SPN Delegation: Eliminate wildcard or DC delegation paths (CIFS/winterfell) in msDS-AllowedToDelegateTo.

Delegation Models Comparison

Delegation ArchitectureGoverning LDAP Attribute / FlagConfiguration PermissionExploitation VectorHardening Protocol
UnconstraineduserAccountControl: 0x80000Domain Admin (SeEnableDelegationPrivilege)Coerce DC authentication via MS-RPRN/MS-EFSR, dump TGT from LSASS.Strip TRUSTED_FOR_DELEGATION on all non-DCs; enroll admins in Protected Users.
Constrained (Kerberos Only)msDS-AllowedToDelegateToDomain Admin (SeEnableDelegationPrivilege)Service ticket sname substitution via tgssub (HTTP to LDAP).Prohibit delegation to DC SPNs; enforce AES-only Kerberos encryption.
Constrained with Protocol TransitionmsDS-AllowedToDelegateTo + UAC: 0x1000000Domain Admin (SeEnableDelegationPrivilege)Arbitrary identity impersonation via unauthenticated S4U2Self.Strip TRUSTED_TO_AUTH_FOR_DELEGATION; mark privileged accounts as sensitive.
Resource-Based (RBCD)msDS-AllowedToActOnBehalfOfOtherIdentityPrincipal with GenericWrite on target computerCombine MAQ=10 with target DACL injection to mint delegated tickets.Set ms-DS-MachineAccountQuota = 0; remove non-default DACL write rights on hosts.

Evidence and limits

The LDAP attributes, ticket transitions, and exploitation examples were checked in the GOAD domains used by the surrounding walkthroughs. The article uses Microsoft protocol specifications for the parts the lab alone cannot prove: ticket flag semantics, S4U request structure, and the KDC’s delegation rules. Command output is evidence of this configuration, not a substitute for those protocol definitions.

The post does not claim every delegation entry is exploitable. Account sensitivity, service-class behavior, patch level, SPN ownership, encryption types, and reachable services all change the result. Detection fields also depend on audit policy and log collection; the listed event IDs are starting points that must be validated in the defender’s own environment.

References

Sources & freshness

How current is this note?

Sources checkedNovember 3, 2026

The latest source-review, content-update, or publication date is shown.

ReviewPublic sources reviewed

Primary public records were checked. Environment-specific behavior remains outside the claim unless separately reproduced.