Someone asked me recently what an attacker could do if he had full acess to a computer object in an active directory environment. While i knew from memory it was possible to leverage this into a full compromise through RBCD abuse, I never had to implement the attack in an engagement. Knowing being half the battle, I decided to go through the exploitation step in my laboratory
What's needed - Prerequisites
As an attacker, the only not so frequent thing to have in order to implement the attack is write privileges on a computer AD object. More specifically, we need to have write privilege over the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of a computer object. This can happen, for exemple, if for some reason a group has been set as having full control over a computer.
The other requirement is an account with a SPN. This is actually really handy, as by default any user account can create a computer account with its own SPNs.
The theory under the attack
The first time I came across this attack was while skimming through ” Wagging the dog ” from Shenanigan labs.
To understand the attack, we need to know some things on how Active Directory work. Here’s a quick recap. From more details, see the links referenced at the bottom of the article.
What are services exactly in an AD environment ?
Services, on a broad level, is a logiciel, hosted on a domain computer, that can do something in your domain, and that ‘something’ can be called by anyone from the domain, given that they are authorized to do so. Examples of services are : a SMB share (allows to share file,) a web service (allows to access a web application), etc.
Services are identified by SPN (Service Principle name). As Microsoft itself puts it:
SPNs are unique identifiers for services running on servers. Every service that will use Kerberos authentication needs to have an SPN set for it so that clients can identify the service on the network.
An SPN is registered in Active Directory under a user account as an attribute called Service-Principal-Name. The SPN is assigned to the account under which the service the SPN identifies is running. Any service can look up the SPN for another service. When a service wants to authenticate to another service, it uses that service’s SPN to differentiate it from all of the other services running on that computer.
SPN is composed of three things: the type (also called service class) of service (www for web, CIFS for fileserver), the hostname of the computer hosting the service, and the port over which the service is exposed. The format of a SPN, which is not without reminding URLs, is: service/hostname:port
Furthermore, SPN are associated to domain accounts, either user or computer ones ; the second being the most common by far: after all, SPN are supposed to identify services, and services are usually associated to computer accounts.
Lastly, how do SPN and account ties up together exactly ? From my understanding, if a account A (user or computer) has a SPN (through its Service-Principal-Name attribute), and a user B tries to authenticate to this SPN through Kerberos, it is the NTLM hash of account A that will be used to sign the TGS.
Ressource based constrained delegation
Now, let’s say, you have service A on your domain. Service A has authenticated user A through non-Kerberos means, for example, service A is a web application with it’s own authentication mechanism. Nevertheless, the application needs to interact with service B, let’s say a fileshare, with the privileges of user A.
In this scenario, service A will need to authenticate to service B while impersonating user A, since that user has never authenticated in the Kerberos realm to begin with.
The way to achieve this in an Active Directory domain, is through what Microsoft calls delegation. There’s a few different types of delegations, and while the most recent ones were pushed as being more secure, they in fact are flawed but in other ways.
Ressource Based Constrained Delegation is the most recent way to delegate authentication, and put in simple term, it is a way to say:
” Service B, if Service A authenticates to you, they can impersonate any domain user “.
And the abuse lies in this sentence. What if, because of a misconfiguration, we can configure RBCD for service B ? Then we can tell service B
” Service B, if that service under the attacker control authenticates to you, he can impersonate any domain user “.
Which mean, by authenticating to service B through the service under our control, we will be able to impersonate any user on the domain, even the most privileged ones, and then abuse their rights.
By default, any user can create a computer account with arbitrary SPN, meaning that if we ever encounter an account for which we can configure RBCD, we have – or can create – anything needed to compromise it.
But enough theory, and let’s explore the attack in a practical way.
- The attacker has write privileges over the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of a computer object (SERVICE A). In this lab, we will simply configure the domain users with full control over our targeted server
- The attacker has an account with a SPN under his control (SERVICE B), or create one thanks to the domain level property machineaccountquota, which by default allows an unprivileged user to create up to 10 computer accounts (with SPN)
- The attacker use its access described in step 1 to configure RCBD from SERVICE B to SERVICE A. SERVICE B will be authorized to authenticate to SERVICE A on the behalf of any domain user.
- The attacker use SERVICE B account to authenticate to SERVICE A, targeting a SPN that allows to completly take over the host of SERVICE A.
Preparing the lab to be abused
First, we’ll need to configure our lab with a server for which a unprivileged user can configure RBCD. We’ll do that through the AD users & Computers GUI (don’t forget to check “View -> advanced Features” to access the Security panel).
Now, we access the computer account that will be affected, and give the “Domain Users” group full control over it.
We can use bloodhound and verify that a path exist from a domain user and WIN-SERVER-1.
The first step is to create an account with a SPN. As said multiple times already, by default, any user can do that. From what I could gather, the most popular tool to do just that is Powermad from Kevin Robertson. The New-MachineAccount function can be used to create a computer account with SPNs already set.
The following step is to configure RBCD for the server we want to compromise (WIN-SERVER-1). A large number of tools can be used here, but we stayed loyal to PowerView.
Set-DomainRBCD -Identity WIN-SERVER-1 -DelegateFrom "userownedcomputed" -Credential $credz
Rubeus.exe hash /password:Mdp1234! /user:userownedcomputed /domain:ethicalhackers.local
Let’s digest that a bit.
Kerberos use shared secret to authenticate users. This secret is based on the user’s password, and is different based on the encryption type used.
The possible encryption types are:
So, basically, the output of the previous Rubeus command is the keys that we are able to use in the subsequent Kerberos interactions, for all the encryption types possible.
Rubeus.exe s4u /user:userownedcomputed$ /rc 4:FBE898D06021CC64FAC48F91E1C84B6D /impersonateuser:vagrant /msdsspn:cifs/WIN-SERVER-1 /ptt
And finally, this is where the magic happens.
As show in the screenshot, the exploitation is in three parts:
- We get a TGT for the account under our control (userownedcomputed), for which a SPN exists
- We use that TGT through the S4U2Self kerberos extension, to get a TGS for ourself (userownedcomputed), as is it was asked by a privileged user (here, vagrant). This TGS is set as forwadable and can thus be used to access other services than ourself, if delegation is configured accordingly.
- We use the TGS from the previous step to authenticate to a SPN in WIN-SERVER-1 (here cifs/win-server-1) for which RBCD is configured. This is done through the S4U2Proxy kerberos extension. The KDC verifies that the msDS-AllowedToActOnBehalfOfOtherIdentity attribute is filled with the account making that request (userownedcomputed) and, as we made sure that it was, it sends us a TGS for cifs/win-server-1 with the privileges associated to our admin user (vagrant).