Configure pentest dropbox DNS tunneling

I work for a very large corporation that has many subsidiaries and they are buying up smaller companies. We need to send out a dropbox (Raspberry Pi or Intel NUC) that we could have a remote office plug into the network for internal pentesting and it establishes a ssh tunnel to our server regardless of network restrictions in the remote office.

Initially we used TAP from Trustedsec. TAP first tries to connect to a URL to retrieve a ‘commands.txt’ file that contains commands to run. If you don’t configure that, or if fails to connect to your http/https/ftp server URL, TAP will fail over to ssh and establish an ssh tunnel. We sometimes experienced issues with the dropbox connecting out from networks that required a proxy server and denied ssh outbound.

My solution was to configure the dropbox to tunnel over DNS if the device is unable to establish a connection over TAP.

I’ll leave configuring TAP up to the reader as another pentester installed it and I installed iodine. The TAP github page setup instructions seem easy enough to understand.

Steps to reproduce DNS tunneling using iodine:

Configure DNS:
See the iodine setup guide:
I thought I had missed something when it didn’t work the same day. After waiting for DNS changes to propagate I tried again the following day and it worked. The setup guide has a link to a tunnel tester in the Troubleshooting section.

Download iodine and install. Same steps on client and server:

git clone
cd iodine
sudo make install

Add iptables rules on your server to allow DNS connections.

sudo iptables -I INPUT 1 -p tcp --dport 53 -j ACCEPT
sudo iptables -I INPUT 2 -p udp --dport 53 -j ACCEPT

Run iodined on the server:

sudo ./iodined -f -c <tunnel IP address> <>

After entering your password for sudo, you’ll be prompted for a password for the tunnel connection. You can add the ‘-P <password>’ option on both client and server to script/automate the connection and avoid being prompted to enter one.
The ‘-f’ option was used to make it run in the foreground for troubleshooting and isn’t necessary once you have it working.
Note that the ‘-c’ option was critical to getting this to work.
The tunnel IP address is the local tunnel IP of your server. It isn’t the actual server IP address, it should be something that isn’t likely to be used on the LAN at either end. I used, and the dropbox client automatically received a tunnel IP address of (netmask

Run iodine on the client:

sudo iodine -f -r -P <password> <>

After ssh into the dropbox from my server over the DNS tunnel I was surprised to see that there wasn’t much lag and the connection was usable. I expected the connection to be much slower.

Configure the dropbox to check for a ssh connection over TAP after startup, and if none then start iodine to tunnel over DNS.

Edit: After posting a link to my article on Reddit and seeing some of the responses I realized that some don’t understand how DNS tunneling works and assume that if they block port 53 outbound and only allow network clients to use their internal DNS server then they are blocking DNS tunneling.

Here’s a good read to understand how DNS tunneling works and how to detect it. (I recommend Bro for DNS traffic analysis.)

Two relevant sections of the paper that are critical to understanding how DNS tunneling works:

With this hierarchical system a given domain owner can define the authoritative servers for their domain. This means that they are in control of the ultimate destination host for DNS queries for their domain. In a typical enterprise, endpoints do not make DNS requests directly to the internet. They have internal DNS servers that provide DNS services to an endpoint. However, given that DNS will forward their requests until the authoritative name server is contacted, an attacker with access on an internal endpoint can leverage the enterprise‘s DNS infrastructure for DNS tunneling to a domain that they control.

The last core technique is to encode data in DNS payloads. This is an area where the specifics of each utility vary widely. From a high level simplified point of view, the client wants to send data to server. It will encode that data in the DNS payload. For example the client could send an ‗A‘ record request where the data is encoded the in host
name: The server could respond with an answer as a CNAME response: In this way any data can be encoded
and sent to the server. The server can also respond with any data. If there is a need for the server to initiate a communication, it cannot be done directly. Clients do not have a service listening for DNS requests and are typically behind a firewall. Server initiated
communication can however be accomplished by having the client regularly poll the server. Then, if the server has data for the client it can send it as a response to the polling requests.