Skip to content

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.

  1. 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.
  2. 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.
  3. 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

  1. 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
    
  2. Remove the grants for the reported principals. dsacls /R removes every ACE for the trustee on the domain object, including legitimate narrower ones, so check step 1:

    # dsacls "DC=corp,DC=example" /R "CORP\helpdesk"
    
  3. 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.

  4. 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

ad-doctor scan dc01.corp.example --ldaps -u 'CORP\auditor' --only AD-ACL-003

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

References

Microsoft and vendors

Research

Tools

MITRE ATT&CK

Available since 0.1.0.