AD-ACL-003: Non-default control over the domain object¶
high Permissions MITRE ATT&CK T1098, T1222 Reads: LDAP
A principal outside tier 0 holds write, WriteDacl or WriteOwner on the domain object, so it can grant itself DCSync or change domain-wide settings.
Why it matters¶
The domain object (DC=corp,DC=example) carries the replication rights, the domain-wide
settings (machine account quota, password policy attributes, gPLink of the domain) and
the inheritable ACEs that flow to every object below it.
- An attacker with WriteDacl on it adds Replicating Directory Changes (All) for an account they own, then runs DCSync. WriteOwner gets there in two steps (take ownership, then rewrite the DACL); GenericAll gets there directly.
- With GenericWrite or write access to all properties they can instead link a GPO to the
domain (see AD-GPO-002) or raise
ms-DS-MachineAccountQuota. - An inheritable ACE added here lands on every user, group and computer in the domain that does not block inheritance.
This is the classic shape of the PrivExchange problem (AD-ACL-007) and of many leftover delegations from migrations and old management tools.
How ad-doctor detects it¶
ad-doctor reads the DACL of the domain head with the SD flags control (the effective ACEs, not inherit-only ones) and reports every principal outside the default tier-0 set that holds a takeover right: GenericAll or full control, GenericWrite, WriteDacl, WriteOwner, or WriteProperty on all attributes (an ACE with no object type).
Default tier 0 is Administrators, Domain Admins, Enterprise Admins, Schema Admins, Domain
Controllers, Enterprise Domain Controllers, the read-only DC groups, the built-in
Administrator and SYSTEM. Each object is the principal's name, for example helpdesk or
Exchange Windows Permissions. Rights limited to one attribute or property set (for
example gPLink alone) are not takeover rights and are covered by
AD-GPO-002.
Attributes and probes read
nTSecurityDescriptor of the domain head (effective ACEs)
Severity¶
Always high: WriteDacl (or ownership, which implies it) on the domain head is one ACE away from AD-ACL-001, and therefore from every password hash.
False positives and limits¶
- Exchange on the shared permissions model before the 2019 fix: correct finding, fixed as described in AD-ACL-007.
- A tier-0 group created by the organisation (for example a dedicated AD admin group that is not nested in Domain Admins). ad-doctor does not know it is tier 0; if it really is managed as tier 0, accept the finding with an owner (../ci.md#accepted-risks).
Fix¶
-
Review the domain DACL (read-only):
$domain = (Get-ADDomain).DistinguishedName (Get-Acl "AD:$domain").Access | Where-Object { $_.AccessControlType -eq 'Allow' -and $_.ActiveDirectoryRights -match 'GenericAll|GenericWrite|WriteDacl|WriteOwner|WriteProperty' } | Format-Table IdentityReference, ActiveDirectoryRights, ObjectType, InheritanceType -AutoSize -
Remove the grants for the reported principals.
dsacls /Rremoves every ACE for the trustee on the domain object, including legitimate narrower ones, so check step 1: -
Check what the principal could already have done: unexpected replication rights (AD-ACL-001), new inheritable ACEs, changed domain settings, and the directory service change events (5136) for the domain object.
-
Delegate narrowly instead: if a team needs to manage objects, grant the specific rights on the OU that holds them, never on the domain head.
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-ACL-003"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
Research
Tools
MITRE ATT&CK
Available since 0.1.0.