visitor@hunterweygandt:~$ cat acl-abuse.html|

ACL Abuse

Vulnerable Active Directory Lab · 2026

← Back to the other documents

ACL Abuse: GenericAll to Domain Admins

Summary

Active Directory objects (users, groups, OUs) have access control lists just like files do. When a low-privilege principal holds a dangerous right over a privileged object, GenericAll, WriteDacl, WriteOwner, AddMember, it can escalate privileges without cracking a single password. It simply uses the permission it was wrongly granted. These paths are usually invisible to defenders because they span multiple hops, which is exactly why BloodHound exists: to graph who-can-do- what-to-whom across the entire domain and surface the shortest path to Domain Admin.

This is the kill chain: a helpdesk account with GenericAll over a privileged group, chained all the way to Domain Admins.

MITRE ATT&CK: T1098 (Account Manipulation) Path: amoss (Helpdesk) -> GenericAll -> IT-Tier1-Admins -> Domain Admins

The misconfiguration

Two conditions create the path, both common in real environments:

  1. The Helpdesk group holds GenericAll over the IT-Tier1-Admins group. Over-delegation like this happens constantly, a helpdesk team is granted broad rights over a group "so they can manage it," and nobody realizes that GenericAll includes the ability to add arbitrary members.
  2. IT-Tier1-Admins is nested inside Domain Admins. Nested privileged groups are common and easy to lose track of, so a right over the nested group is effectively a right over Domain Admins.
# planted on the DC: grant Helpdesk GenericAll over IT-Tier1-Admins
$tier1DN = (Get-ADGroup "IT-Tier1-Admins").DistinguishedName
$sid     = (Get-ADGroup "Helpdesk").SID
$acl     = Get-Acl "AD:\$tier1DN"
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $sid,
    [System.DirectoryServices.ActiveDirectoryRights]::GenericAll,
    [System.Security.AccessControl.AccessControlType]::Allow,
    [guid]"00000000-0000-0000-0000-000000000000")
$acl.AddAccessRule($ace)
Set-Acl -Path "AD:\$tier1DN" -AclObject $acl

# nest the privileged group toward Domain Admins
Add-ADGroupMember -Identity "Domain Admins" -Members "IT-Tier1-Admins"

Execution

Mapping the path with BloodHound

Data was collected from Kali with bloodhound-python using amoss's credentials (amoss is in Helpdesk), then imported into BloodHound CE:

bloodhound-ce-python -d ecorp.local -u amoss -p 'LabP@ssw0rd!2025' -c All -ns 10.0.0.88 --zip
Kali terminal running bloodhound-ce-python against ecorp.local as the user amoss, targeting name server 10.0.0.88 with the All collection method. The Kerberos TGT request fails and the tool falls back to NTLM, then connects to the LDAP server dc-vuln.ecorp.local and enumerates the domain: 1 domain, 1 computer, 29 users, 60 groups, 2 GPOs, 8 OUs, 19 containers, 0 trusts. Output is compressed into a timestamped bloodhound.zip ready for ingest.
Collecting the graph data: bloodhound-ce-python authenticates as a low-privileged user and enumerates all of ecorp.local over LDAP, zipping the result for ingest. This is the data behind the attack path in the next screenshot.

Pathfinding from amoss@ecorp.local to Domain Admins@ecorp.local renders the full attack path:

AMOSS --MemberOf--> HELPDESK --GenericAll--> IT-TIER1-ADMINS --MemberOf--> DOMAIN ADMINS
BloodHound Community Edition pathfinding view showing the ACL Abuse chain in ecorp.local: the user AMOSS is a member of the Helpdesk group, which holds a GenericAll edge over IT-Tier1-Admins, which is in turn a member of Domain Admins - a full path from a low-privileged user to domain dominance. The detail panel confirms the GenericAll ACL is not inherited and lists the net rpc group addmem abuse commands.
BloodHound confirms the path before the attack: Helpdesk holds GenericAll over IT-Tier1-Admins, which nests into Domain Admins - so AMOSS reaches Domain Admins through two hops that never touch a privileged account directly.

BloodHound's edge help panel provides OS-specific abuse instructions (Windows / PowerView, Linux, plus OPSEC considerations). The Linux path was used here since the attacker box is Kali.

Abusing the right

GenericAll over a group includes the ability to add members. amoss adds herself to IT-Tier1-Admins, which (being nested in Domain Admins) makes her a domain admin, no password needed:

net rpc group addmem "IT-Tier1-Admins" "amoss" \
  -U 'ecorp.local/amoss%LabP@ssw0rd!2025' -S 10.0.0.88

# verify
net rpc group members "IT-Tier1-Admins" \
  -U 'ecorp.local/amoss%LabP@ssw0rd!2025' -S 10.0.0.88
# -> ECORP\amoss, ECORP\twellick

amoss is now effectively Domain Admin. The full kill chain from the start of the lab: sprayed employee credential -> helpdesk account (amoss) -> GenericAll abuse -> privileged group -> Domain Admins. All actions here authenticated as amoss using her known password. What makes this step notable is that the escalation from that foothold to Domain Admin required no additional credentials, no cracked hash, and no exploit, only the abuse of an over-permissive ACL. The attacker already had a low-privilege account; GenericAll turned it into domain dominance.

Kali terminal executing the ACL Abuse. The first net rpc group addmem attempt to add amoss to IT-Tier1-Admins fails with 'zsh: no such event: 2025' because the exclamation point in the password triggered history expansion inside double quotes. The command is retried with single quotes and succeeds silently. A final net rpc group members query confirms IT-Tier1-Admins now contains ECORP\amoss and ECORP\twellick - the abuse worked.
Executing the GenericAll abuse: net rpc group addmem adds amoss to IT-Tier1-Admins, and the follow-up net rpc group members confirms the new membership. Note the first attempt fails - the ! in the password triggers zsh history expansion under double quotes, so the credential has to be single-quoted.

Telemetry generated

This leaves two distinct footprints on the DC, corresponding to two stages of the attack:

Stage 1, the ACL being granted (setup) -> Event 5136

Field Value Why it matters
win.system.eventID 5136 Directory object modified
win.eventdata.objectDN CN=IT-Tier1-Admins,… Which object
win.eventdata.objectClass group It's a group
win.eventdata.attributeLDAPDisplayName nTSecurityDescriptor The DACL itself was changed

The nTSecurityDescriptor attribute is the object's security descriptor. A 5136 modifying it means someone rewrote the object's permissions, the fingerprint of ACL-based backdooring.

Stage 2, the group being abused (payoff) -> Event 4728

Field Value Why it matters
win.system.eventID 4728 Member added to global security group
win.eventdata.targetUserName IT-Tier1-Admins The (privileged) group
win.eventdata.memberName CN=Angela Moss,… Who was added
win.eventdata.subjectUserName amoss Who did it

Audit requirements: "Audit Security Group Management" (4728) and "Audit Directory Service Changes" (5136), both enabled by the lab's policy.

Detection

This part required a more specific detection design than the earlier ones. Kerberoasting and AS-REP roasting have signatures that are almost always malicious (RC4-for-a-service-account, pre-auth 0). Group changes are NOT like that, IT adds people to groups all day, so a rule firing on every 4728 would drown the defenders in noise. The fidelity has to come from WHICH group. The rule is therefore scoped to privileged group names.

Stock behavior: 4728 matches rule 60141 (level 5) and 5136 matches 60229 (level 4), both generic and low-severity. Neither is aware that a change to a privileged group is a privilege-escalation event.

Custom rules (/var/ossec/etc/rules/local_rules.xml):

<group name="privileged_group_change,acl_abuse,attack,windows,">

  <!-- ACL Abuse: attacker adds themselves to a privileged group -->
  <rule id="100220" level="12">
    <if_sid>60103</if_sid>
    <field name="win.system.eventID">^4728$</field>
    <field name="win.eventdata.targetUserName">IT-Tier1-Admins|Domain Admins|Enterprise Admins|Server-Admins</field>
    <description>Privileged group change: $(win.eventdata.memberName) added to $(win.eventdata.targetUserName) by $(win.eventdata.subjectUserName)</description>
    <mitre><id>T1098</id></mitre>
  </rule>

  <!-- ACL Abuse: the DACL edit that granted the rights in the first place -->
  <rule id="100221" level="12">
    <if_sid>60103</if_sid>
    <field name="win.system.eventID">^5136$</field>
    <field name="win.eventdata.attributeLDAPDisplayName">^nTSecurityDescriptor$</field>
    <field name="win.eventdata.objectClass">^group$</field>
    <description>DACL modified on group $(win.eventdata.objectDN) - possible ACL backdoor</description>
    <mitre><id>T1098</id></mitre>
  </rule>

</group>

Rule design notes:

Results: rule 100220 fired at level 12 ("Angela Moss added to IT-Tier1-Admins by amoss"), rule 100221 at level 10 ("DACL modified on group IT-Tier1-Admins").

Wazuh Threat Hunting dashboard on the DC-VULN agent, filtered to rule.id 100220 or 100221, showing 3 hits in the last two hours. Two events fire rule 100221 (level 10, event 5136) with the description 'DACL modified on group CN=IT-Tier1-Admins - possible ACL backdoor', and one event fires rule 100220 (level 12, event 4728) with 'Privileged group change: CN=Angela Moss added to IT-Tier1-Admins' - both custom rules detecting the ACL Abuse chain that the stock ruleset misses.
Both halves of the ACL Abuse detection land: rule 100221 catches the DACL edit (event 5136) that planted the backdoor, and rule 100220 catches the privileged group change (event 4728) when Angela Moss is added to IT-Tier1-Admins. Neither fires on the stock ruleset.

False positives / tuning: 100220's accuracy depends entirely on maintaining the privileged-group list, any high-value group must be added to the regex, and legitimate admin additions to those groups will also alert. 100221 will fire on any legitimate permission change to a group object, so in a busy environment it needs tuning: baseline normal delegation changes, or scope to only the most sensitive groups. The self-addition pattern (subject == member) could be added as a higher-fidelity sub-rule for the strongest signal.

Remediation

Notes/Troubleshooting

← Back to the other documents