
This article takes a closer look at an important aspect of Active Directory security: Resource-Based Delegation (RBCD). It is a key feature in systems that use the Kerberos authentication protocol, allowing services to act on behalf of other users. It opens up new opportunities for streamlining access processes, but it can also pose a serious threat if used incorrectly.
Disclaimer: We are aware that some photos or articles may contain Russian language captions. But isn’t it great to use their own language against them?
We have already looked at how the mechanisms of unrestricted and constrained delegation work in Active Directory via the Kerberos protocol. Now it is time to move on to the most interesting part – resource-based delegation, which is especially attracting attention when it comes to potential attacks.
Resource-based delegation, or RBCD, first appeared in Windows Server 2012.
If earlier, to configure unrestricted or regular constrained delegation, special privileges at the domain administrator level, such as SeEnableDelegation, were required, then with the advent of RBCD, the situation has changed. Now it is the service that determines who is allowed to act on behalf of other users, which greatly simplifies the configuration process, but at the same time adds certain security risks.
For convenience, we will use the abbreviation RBCD instead of the full name of this type of delegation.
Previously, a responsible person was appointed who determined who could be contacted and on whose behalf. With the advent of the new approach, each service independently decides who to allow access to itself on behalf of other users.
To configure RBCD, you must have the right to make changes to the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the account. This attribute stores the SIDs (security identifiers) in binary format of those accounts that are allowed to act on behalf of other users when accessing a service with a configured RBCD.
Configuration example: Since there is no convenient graphical interface for working with RBCD, you have to use Powershell.
The S4U2Self and S4U2Proxy extensions are used to implement the resource-based delegation mechanism.
To understand how these extensions work in the context of RBCD, consider the following example: Account “Owner B” has delegation configured that allows any service of Account “Owner A” to act on behalf of unsecured users by accessing any of its services.
Let’s consider the RBCD process in points:
It doesn’t matter how User authenticated to Service A, let’s say using the NTLM protocol, which is different from Kerberos.
Service A contacts the domain controller to obtain a TGS ticket “for itself” on behalf of the user User.
The domain controller checks that the account “Owner A” has the TRUSTED_TO_AUTH_FOR_DELEGATION flag active. The specified flag is not active, so a regular nonforwardable TGS ticket without the right to transfer User to Service A is sent in response. Thus, S4U2Self works in the same way as in the case of classic constrained delegation.
Using the received TGS ticket, Service A contacts the domain controller to obtain a Forwardable TGS ticket to Service B on behalf of User. The domain controller verifies that the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the “Owner B” account is set to the SID of the “Owner A” account. The domain controller also verifies that “Owner A” has at least one SPN. As a result, the domain controller sends a Forwardable TGS ticket in response.
This behavior is an important difference. In RBCD, S4U2Proxy returns a Forwardable TGS ticket when a Nonforwardable ticket is provided, while in constrained delegation, S4U2Proxy returns a Forwardable TGS ticket only when a Forwardable ticket is provided.
Service A contacts Service B on behalf of User using the received Forwardable TGS ticket.
Let us note once again:
S4U2Self in RBCD returns a Nonforwardable TGS ticket.
S4U2Proxy always returns a Forwardable TGS ticket on success.
Conditions for carrying out the attack:
Ability to change the contents of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the attacked account.
Control over an account that has an SPN.
If the attack is successful, the attacker gains administrative access to the server running a service running on behalf of the account with the RBCD configured.
The first stage of the attack is to enter the SID of the controlled account that has the SPN in the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the account being attacked. As a result, the controlled account is able to act on behalf of almost any user when accessing a service associated with the attacked account.
rbcd.py 'DomainFQDN'/'Username':'Password' -delegate-from 'ControlledAccountWithSPN' -delegate-to 'Target$' -dc-ip 'DC_IP' -action write
In the second step, the attacker executes an S4U2Self TGS ticket request on behalf of the administrative user to the service running under the controlled account. As a result of the request, the attacker receives a Nonforwardable TGS ticket.
getST.py -spn "cifs/target" -impersonate $AdminAccountName -dc-ip $DomainController $DomainFQDN/$ControlledAccountWithSPN:$Password
In the third stage of the attack, the attacker uses the obtained Nonforwardable TGS ticket to execute the S4U2Proxy request. If the request is successful, he receives a Forwardable TGS ticket to the service of the account being attacked, acting on behalf of the administrative user. At this stage, the attack is completed, since the attacker already has full access to the service.
At first, this attack may seem unlikely for practical application. Indeed, the need to be able to change the msDS-AllowedToActOnBehalfOfOtherIdentity attribute in the target account seems to be a significant obstacle, since such an action requires administrator privileges. In addition, the question arises: how to obtain an account with the necessary SPN?
However, there are several nuances that greatly simplify the implementation of this attack in real conditions. Important factors that increase the likelihood of a successful attack will be considered below.
At the domain level, there is an attribute called ms-DS-MachineAccountQuota (MAQ), which is responsible for the number of machine accounts that an unprivileged user of the specified domain can add.
By default, the value of the ms-DS-MachineAccountQuota attribute is 10.
You can check the current value of MAQ, for example, using the special CrackMapExec module:
crackmapexec ldap $DC -u $Username -p $Password -d $DomainFQDN -M MAQ
Typically, a machine account automatically receives several SPNs upon creation. In addition, the user who created the machine account has a number of rights to it, including the ability to add new SPNs.
This means that an attacker, having hijacked even a regular unprivileged account, can create their own machine account and configure it for further use in RBCD attacks.
addcomputer.py -computer-name 'evilcomputer$' -computer-pass $GeneratedPass -dc-ip $DC_IP $Domain_FQDN/$Username:$Password
The addcomputer.py script provides a -method parameter that allows you to choose the protocol for adding a machine account. There are two options: SAMR and LDAPS. SAMR is used by default, as LDAPS may not be available in some cases.
Important: If you add an account using SAMR, SPNs are not created automatically. In this case, you must use a separate script, addspn.py, to add the required SPNs manually.
addspn.py -u '$DomainFQDD'\'evilcomputer$' -p $LM:$NT -s anyRecordName.$DomainFQDN $DC_FQDN
Recently, a method was discovered to conduct RBCD attacks even when there is no possibility to add machine accounts to the domain, including when the ms-DS-MachineAccountQuota attribute is equal to 0. In this case, the presence of an account with an SPN is not essential and for the attack it is enough to have a regular unprivileged user account.
One point that I would like to note: the analyzed method involves changing the password of a controlled user account. Thus, the attack leads to the inoperability of the specified account from the side of the attacked organization, that is, a “denial of service”, which should be taken into account.
Possession of one of the rights to the account being attacked:
GenericAll
GenericWrite
WriteDACL
WriteOwner
Allows the attacker to change the msDS-AllowedToActOnBehalfOfOtherIdentity attribute. Note: You can check or search for these permissions using Bloodhound.
Let’s consider another important method. It was previously noted that the account being attacked can independently change the value of its msDS-AllowedToActOnBehalfOfOtherIdentity attribute, and this does not require administrative privileges. However, the question arises: how to force the account to change the value of this attribute and enter the SID of the account controlled by the attacker? The answer is to use a Relay attack.
In short, as a result of this attack, a request for NetNTLMv1/2 authentication is intercepted, and the received authentication data is redirected for further execution of commands on behalf of the attacking account. One possible outcome of such an attack is to change the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
However, for beginners, understanding this process can be difficult. Initially, there was a desire to consider RBCD in connection with Relay attacks, but some difficulties arose:
The topic of Relay attacks is very large and deserves a separate article, and sometimes several articles. The description of the principles and conditions for carrying out these attacks is beyond the scope of the current material.
If we continue without explaining Relay attacks, this may violate the logic of the story, since the reader will be required to have knowledge that has not been discussed before. In previous articles, the material was presented sequentially “from scratch”, and this is an important feature from which the author does not want to deviate.
With this in mind, it was decided to end the article on RBCD attacks. However, this does not mean that the author will not return to this topic in the future, for example, after the article on Relay attacks.
Conduct a domain inventory for accounts with unused configured RBCD.
Add critical domain accounts to the Protected Users group or enable the “Account is sensitive and cannot be delegated” option in the attributes of the specified accounts.
Assign dedicated user accounts as service owners, if possible. Ensure password complexity and periodic rotation for the specified accounts.
Set the ms-DS-MachineAccountQuota attribute = 0.
Sign SMB and LDAP messages on all domain objects.
Configure and use LDAP channel binding.
Disable the Print Spooler service on all domain objects where it is not used.
Adjust firewall settings to limit the possibility of forced authentication.
Disable the use of the NetNTLM v1 protocol. If possible, refuse to use NetNTLM v2 (which is difficult to achieve in practice).
Use current versions of operating systems with critical updates installed, which helps protect against Drop the Mic or PrivExchange attacks.
Exclude the “Authenticated Users” group from the standard “Pre-Windows 2000 Compatible Access” group.
Use group policies to disable the use of insecure broadcast protocols NetBIOS, LLMNR, as well as the WPAD proxy auto-configuration service and the IPv6 protocol on domain objects.
Note: These recommendations should be approached on an individual basis, as it is not possible to give universal advice for all networks and domains. Before making changes, you should make sure that these adjustments are appropriate. For example, IPv6 or the WPAD service may be required for the network to function, and it is better to make adjustments to the settings instead of disabling them.