ACL Enumeration
Practical methods for enumerating ACL attack paths using PowerView, built-in PowerShell cmdlets, and BloodHound. The key is targeted enumeration — starting from a user you control and following the chain of rights outward.
Enumerating ACLs with PowerView
The Problem with Broad Enumeration
Running Find-InterestingDomainAcl without filters returns a massive amount of data that is impractical to sift through during a time-boxed assessment.
Find-InterestingDomainAcl
This will work, but the output is overwhelming. Instead, start with a user you control and enumerate outward.
Targeted Enumeration (Recommended Approach)
Step 1: Get the SID of your controlled user
Import-Module .\PowerView.ps1
$sid = Convert-NameToSid wley
Step 2: Find all objects this user has rights over
Without -ResolveGUIDs, the ObjectAceType field shows raw GUIDs instead of human-readable names:
Get-DomainObjectACL -Identity * | ? {$_.SecurityIdentifier -eq $sid}
This returns results with ObjectAceType values like 00299570-246d-11d0-a768-00aa006e0529 — not useful without translation.
Step 3: Resolve GUIDs to readable names
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid}
Now the ObjectAceType shows User-Force-Change-Password instead of the raw GUID. This command can take 1-2 minutes in large environments.
Manually resolving a GUID (without PowerView)
$guid = "00299570-246d-11d0-a768-00aa006e0529"
Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter {ObjectClass -like 'ControlAccessRight'} -Properties * | Select Name,DisplayName,DistinguishedName,rightsGuid | ?{$_.rightsGuid -eq $guid} | fl
Following the Chain
Once you find the first link (e.g., user wley has ForceChangePassword over damundsen), continue the process with the next user:
$sid2 = Convert-NameToSid damundsen
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid2} -Verbose
Check for nested group memberships that expand the attack surface:
Get-DomainGroup -Identity "Help Desk Level 1" | select memberof
Continue until you reach a high-value target or dead end.
Enumeration Without PowerView (Built-in Cmdlets)
Useful when you can’t import tools onto the system.
Build a user list
Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt
Iterate over all users checking ACLs
foreach($line in [System.IO.File]::ReadLines("C:\Users\htb-student\Desktop\ad_users.txt")) {
get-acl "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match 'INLANEFREIGHT\\wley'}
}
This is slow but works without any external tools. The output contains raw GUIDs that must be resolved manually.
Enumerating ACLs with BloodHound
BloodHound makes ACL attack path discovery dramatically faster than manual methods.
Key BloodHound Features for ACL Enumeration
-
Node Info > Outbound Control Rights — select a user node and check:
- First Degree Object Control — objects you have direct rights over
- Transitive Object Control — full chain of objects reachable via ACL abuse (the multi-hop path)
-
Right-click any edge → select Help for:
- Explanation of the specific right
- Tools and commands to exploit it
- OPSEC considerations
- External references
-
Pre-built queries — use “Find Principals with DCSync Rights”, “Shortest Paths to Domain Admins”, etc. to confirm critical attack paths
Example Attack Chain (Discovered via BloodHound)
wley
→ ForceChangePassword → damundsen
→ GenericWrite → Help Desk Level 1 (group)
→ MemberOf → Information Technology (group)
→ GenericAll → adunn
→ DS-Replication-Get-Changes + DS-Replication-Get-Changes-In-Filtered-Set → DCSync
Each hop represents a different ACL abuse primitive. BloodHound shows this entire path in a single graph view — what would take extensive manual enumeration is visible at a glance.
DCSync Rights Indicator
When a user has both of these extended rights on the domain object, they can perform a DCSync attack:
DS-Replication-Get-ChangesDS-Replication-Get-Changes-In-Filtered-Set
Use the BloodHound pre-built query “Find Principals with DCSync Rights” to identify these quickly.
Enumeration Methodology Summary
| Step | Action | Tool |
|---|---|---|
| 1 | Get SID of controlled user | Convert-NameToSid (PowerView) |
| 2 | Find all objects user has rights over | Get-DomainObjectACL -ResolveGUIDs (PowerView) |
| 3 | Identify the right (ForceChangePassword, GenericWrite, etc.) | -ResolveGUIDs flag or manual GUID lookup |
| 4 | Follow the chain — enumerate next user’s rights | Repeat step 2 with new user’s SID |
| 5 | Check group nesting for inherited rights | Get-DomainGroup -Identity <GROUP> | select memberof |
| 6 | Validate full attack path | BloodHound Transitive Object Control / pre-built queries |