Resource-based constrained delegation (RBCD)

Resource-based constrained delegation (RBCD)

TL;DR: The msDS-AllowedToActOnBehalfOfOtherIdentity attribute on a target computer enumerates principals allowed to S4U-impersonate any user to that computer. Anyone with write access to the attribute (the computer owner, or via relay/ACL) plus a controlled account with an SPN can pop SYSTEM on the target as any user — including a domain admin.

What it is

RBCD was introduced in Server 2012 to invert classical (account-side) constrained delegation: instead of the delegating account listing “I trust X to act for me,” the resource lists “I will accept S4U requests from these principals.” The attribute is a binary SD; an entry granting Allow to attacker-controlled EVIL$ means EVIL$ can call S4U2self for any user (except those in Protected Users or marked sensitive) and then S4U2proxy to obtain a service ticket against the target as that user.

Preconditions / where it applies

  • Write rights on msDS-AllowedToActOnBehalfOfOtherIdentity of the target computer object (GenericAll, GenericWrite, WriteProperty, or computed via NTLM relay to LDAP)
  • A controlled account with an SPN. Default ms-DS-MachineAccountQuota = 10 lets any domain user create up to ten computer objects — instant SPN holder
  • Network reach to a DC (Kerberos) and to the target service

Technique

  1. Create a sacrificial machine account (uses MachineAccountQuota):
1
2
addcomputer.py -computer-name 'EVIL$' -computer-pass 'Pwn!' \
  -dc-host dc01.corp.local corp.local/alice:Pass
  1. Write the trust attribute on the victim, naming EVIL$ as a permitted delegate:
1
2
rbcd.py -delegate-to 'VICTIM$' -delegate-from 'EVIL$' \
  -action write corp.local/alice:Pass -dc-ip 10.0.0.10
  1. Perform the S4U dance — request a ticket as Administrator to the victim:
1
2
3
4
getST.py -spn cifs/victim.corp.local -impersonate Administrator \
  -dc-ip 10.0.0.10 corp.local/EVIL\$:'Pwn!'
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass victim.corp.local

The S4U2self leg works because RBCD doesn’t require the calling account to have TrustedToAuthForDelegation; the S4U2proxy succeeds because the victim’s SD lists EVIL$. The returned ticket is for cifs/victim as Administrator → SYSTEM shell.

Common trigger paths: relay coerced DC auth to LDAP and write RBCD on a target server (ms-rpc-abuse → ntlmrelayx --delegate-access), or chain a GenericWrite ACL on a computer object discovered via BloodHound.

SPN gotcha: when running Rubeus s4u, the /altservice:cifs,host,http flag rewrites the returned ticket’s sname so a single S4U2proxy call yields tickets for multiple services on the same host — useful when you also want WinRM/WMI from the same impersonation. Watch the SPN format too: requesting cifs/victim (NetBIOS short name) sometimes succeeds where cifs/victim.corp.local (FQDN) fails depending on how the target’s SPN is registered, so try both. The raw security-descriptor string written to msDS-AllowedToActOnBehalfOfOtherIdentity is O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;<SID-of-EVIL$>) — the SID must be the machine account SID, not a user SID, or S4U2proxy will silently return KRB_AP_ERR_BADOPTION.

Detection and defence

  • Set ms-DS-MachineAccountQuota = 0 for non-Tier-0 OUs; users should not be able to manufacture trusted SPN holders
  • Audit changes to msDS-AllowedToActOnBehalfOfOtherIdentity (event 5136 on computer objects) — almost no legitimate workflow writes it
  • Add sensitive accounts to Protected Users and mark them “Account is sensitive and cannot be delegated”
  • Enforce LDAP signing + channel binding to block the relay-to-LDAP variant

References