← back to theory
AD

ACLs and DACLs in Active Directory

Underneath every object in Active Directory is a permission list that decides who can do what to it. These Access Control Lists are the quiet engine of most modern AD attack paths — not because ACLs are a flaw, but because in a large domain there are millions of them, they are edited by many hands over many years, and a single misconfigured entry can create a chain that ends at Domain Admin. BloodHound exists largely to find these chains.

Security descriptors, DACLs, and ACEs

Every object carries a security descriptor (stored in the ntSecurityDescriptor attribute). It has two parts that matter here:

PartPurpose
DACL (Discretionary ACL)The list of who is allowed or denied which permissions — the part attackers care about
SACL (System ACL)The list of what gets audited/logged — the defender's part

A DACL is made of ACEs (Access Control Entries). Each ACE ties a principal (a SID) to a right (read, write, reset password, full control) over the object. When Windows decides whether you can act on an object, it walks the DACL looking for ACEs that apply to you or your groups.

The rights that create attack paths

Not all rights are equal. A handful are "dangerous" because they can be turned into control of the principal they apply to:

RightWhat it lets you do
GenericAllFull control — do anything below, including reset the password outright
GenericWriteWrite most attributes — add an SPN (targeted Kerberoast), set logon script, write msDS-KeyCredentialLink
WriteDACLRewrite the object's DACL — grant yourself GenericAll, then do anything
WriteOwnerMake yourself the owner — the owner can always rewrite the DACL
ForceChangePasswordReset the account's password without knowing the current one
AddMemberAdd members to a group — add yourself to a privileged group
AllExtendedRightsIncludes password reset and, on the domain object, the DCSync rights

How a right becomes compromise

The pattern is always "I have right X over object Y, therefore I can control Y." A few concrete conversions:

You have…You can…
ForceChangePassword over a userReset their password and log in as them
GenericWrite over a userAdd an SPN and Kerberoast them, or write a Shadow Credential
GenericAll over a groupAdd yourself to it — instant privilege if the group is privileged
GenericAll / GenericWrite over a computerConfigure RBCD to impersonate anyone to it
WriteDACL over any objectGrant yourself GenericAll, then use any of the above
WriteOwner over any objectTake ownership, rewrite the DACL, then as above
DS-Replication rights over the domainDCSync — pull every hash in the domain
The important insight is chaining. You rarely have a right directly over Domain Admins. Instead you have GenericWrite over a service account, which lets you Kerberoast it, which cracks to a password, which happens to have WriteDACL over a group, which contains a user who can reset a helpdesk account, which… BloodHound draws exactly these multi-hop chains, and any single weak ACE can be the first link.

Why these misconfigurations exist

  • Delegation of administration. "Let the helpdesk reset passwords in this OU" is a legitimate need met by granting ForceChangePassword — and it is easy to grant too broadly.
  • Application installers. Software setup routines grant themselves rights over objects and never clean up.
  • Copy-paste permissions. An admin grants a working set of rights by cloning an existing object's ACL, propagating whatever was wrong with the original.
  • Nested groups. A right granted to a broad group silently applies to everyone nested inside it.
  • Age. ACLs accumulate for decades and are almost never audited or removed.

AdminSDHolder and adminCount

A related mechanism worth knowing. AD protects privileged accounts by periodically stamping their ACLs from a template object called AdminSDHolder, and marking them with adminCount=1. If an attacker can modify AdminSDHolder itself, the malicious ACE gets propagated to every protected account automatically — a persistence technique. Conversely, adminCount=1 on an account is a quick flag that it is (or was) privileged and worth attention.

Finding the paths

The reason ACL abuse is so central to modern AD attacks is that it is discoverable at scale. BloodHound collects every ACE in the domain and computes the graph, so an attacker asks it "what can this principal I control reach?" and gets a concrete chain — a WriteDacl here, a ForceChangePassword there — from a nobody to Domain Admin. The individual rights (GenericAll, WriteDacl, WriteOwner, ForceChangePassword, AddMember, and the delegation-writing rights) and how each is turned into access are covered with commands in the Vulns & Misconfigs section under AD ACL Abuse; this page is why those rights exist and how the mess accumulates.

Detection and defence

ControlEffect
Regular ACL audits with BloodHoundRun the same analysis attackers do, and remediate the paths — the single most effective measure
Least privilege on delegationGrant the narrowest right over the smallest scope; avoid GenericAll where a specific right suffices
Monitor DACL modifications (event 5136)Changes to sensitive objects' ACLs are high-signal
Watch AdminSDHolderAny change to it, or unexpected adminCount=1 accounts, warrants investigation
Tiered administrationPrevents a low-tier ACL win from reaching high-tier accounts

The takeaway

ACLs are where AD's flexibility becomes its risk. Every object's DACL is a set of "who can do what to me" rules, and a small set of rights — GenericAll, GenericWrite, WriteDACL, WriteOwner, ForceChangePassword — convert directly into control of the object they sit on. Attacks chain these single rights into long paths that end at Domain Admin, which is precisely what BloodHound is built to reveal. The defence is to run that same analysis yourself and prune the dangerous edges. The abuse tooling (BloodHound, PowerView, bloodyAD, Impacket) is in the Toolkit Vulns & Misconfigs, and the specific payoffs are covered on the Kerberoasting, Delegation, and DCSync pages.

Related reading