Constrained delegation lets an account request service tickets for a user, but only to a fixed list of SPNs named in its msDS-AllowedToDelegateTo attribute. If you compromise such an account (its password, hash, or AES key), you can impersonate arbitrary users to those listed services, and often to more than the list literally allows.
The abuse with protocol transition#
When the account is configured for protocol transition (TRUSTED_TO_AUTH_FOR_DELEGATION), it can call S4U2self to mint a ticket to itself as any user with no involvement from that user, then S4U2proxy to turn it into a ticket for the allowed back-end service as that user:
# Impacket: impersonate Administrator to an allowed SPN, using the delegating account's hash
getST.py -spn cifs/target.example.local -impersonate Administrator \
-hashes :<delegating-acct-hash> example.local/delegating-acct
export KRB5CCNAME=Administrator.ccache
Without protocol transition, S4U2self still works but the resulting ticket is not forwardable, so S4U2proxy is supposed to refuse it. In practice the ticket can often still be used, and self/U2U tricks can produce a usable one.
The SPN-substitution trick#
S4U2proxy constrains the service class loosely: the returned ticket's service name can be swapped to another SPN (the KDC does not bind the ticket tightly to the exact SPN string). The catch is the key: the ticket is encrypted with the back-end account's key, so the substituted SPN only works if it is registered to that same account. In practice a host's own service SPNs (cifs/, host/, http/, ldap/ on a DC, and so on) are all backed by the computer account, so delegation allowed to one of them can be swapped to the others on that host, turning a limited-looking delegation into full control of that machine. It does not reach an SPN registered to a different, dedicated service account, because that account's key cannot decrypt the ticket.
Exploitation notes#
- Impersonate a privileged user (Domain Admin) to a
cifs/orhost/SPN on the target to get file access or code execution as that user on that host. - The SPN-substitution trick means the listed SPN matters less than the target account: delegation to one computer-account SPN is effectively delegation to all of that machine's own services, though not to SPNs held by separate service accounts on the same host.
- You need the delegating account's secret; recover it by cracking (it is often a service account) or dumping, then drive S4U with its hash or AES key.
- Accounts marked "sensitive, cannot be delegated" and members of Protected Users cannot be impersonated this way.
Tools#
- Impacket (
getST.pywith-impersonate): S4U2self/S4U2proxy and SPN substitution. - Rubeus (
s4u): on-host constrained-delegation abuse. - findDelegation.py (Impacket): enumerate accounts configured for delegation.
References#
- The Hacker Recipes: constrained delegation
- Microsoft: S4U2self, S4U2proxy, and protocol transition