In the past few years, I did some in-depth research and analysis on many popular DNS tunneling tools including DNS2TCP, TCP-over-DNS, OzymanDNS, Iodine, SplitBrain, DNScat-P/DNScat2, DNScapy, TUNS, PSUDP, YourFreedom etc. Although most DNS Tunneling tools are implemented in different languages and/or may have different features and settings, they share the same concept and achieve the same goal, which is trying to bypass the traditional IPS or firewall inspection and network security policy to reach the Internet. They can do data exfiltration by relaying TCP connections over DNS, which is hard to detect and block.
In this blog, I will show my work on one of the DNS tunneling tools, DNS2TCP, to explain how DNS tunneling works and analyze its network traffic pattern/behaviors. DNS2TCP is one of data exfiltration tools that supports SSH, SMTP, POP and other TCP connections over DNS protocol.
1 DNS2TCP Test-bed Setup
1.1 How DNS2TCP works
Like most tunneling technologies, DNS2TCP requires a public domain which can be used for the DNS tunneling. Once a public domain is configured and DNS2TCP software is installed, we can start DNS2TCP tool to run SSH/POP/SMTP or any other applications.
Figure 1 shows the detailed steps on how DNS2TCP works.
- Start DNS2TCP client from the laptop (in our setup, the IP address is 192.168.212.71), which has a default DNS server configuration (in our setup, the IP address is 192.168.212.11). When a user configures the DNS2TCP and starts an SSH session, the DNS2TCP client software will encapsulate SSH payloads into multiple subdomains on the pre-configured public tunneling domain and send these DNS subdomain requests to DNS server.
- Most domains can be resolved by DNS server without any issue, but for the DNS tunneling domain, (in our setup, I am using a fake domain, dns2tcp.tunnel.srt.blox), the DNS server cannot resolve them and will forward the request to the DNS2TCP server (the IP address is 192.168.212.81).
- The DNS2TCP server receives the DNS request, decapsulates the payload, and uses as a proxy to connect to the Internet resource. In our testbed, I setup an SSH server (192.168.212.91) as Internet resource.
- Then Internet resource responds to the request and sends the payload to the DNS2TCP server.
- The DNS2TCP server encapsulates the response payload from the Internet into DNS response packet, and sends back to the DNS2TCP client. The DNS2TCP client receives the DNS response traffic and decapsulates them. Then the client is able to receive all the response traffic from the Internet resource.
Figure 1. How DNS2TCP works
1.2 Testbed Topology
I used Fedora release 12 as a host machine, and installed VMware Workstation 11. I setup the whole testbed using the VMware workstation guests. I created four guests below:
- DNS2TCP client, which is an Ubuntu OS guest using network adaptor as NAT (i.e. vmnet8). Inside the Ubuntu, network address is statically configured as 192.168.212.81, and the network nameserver is configured as 192.168.212.11. The package DNS2TCP is installed.
- DNS2TCP server, which is also an Ubuntu OS guest using network adaptor as NAT(i.e., vmnet8). It has almost the same configuration as DNS client, but IP address is configured as 192.168.212.71. The package DNS2TCP is also installed on this machine.
- Internet Resource (SSH Server), which is an Ubuntu OS guest as well. It serves as an Internet resource, and has SSH server, SMTP server and HTTP server installed. It has the same DNS nameserver configured, 192.168.212.11, and its static IP address is 192.168.212.91.
- DNS Server. I use Infoblox vNIOS as the DNS server. It has a static network IP address, 192.168.212.11. I add a special DNS zone, dns2tcp.tunnel.srt.blox, for the DNS tunneling use. It is configured as a forward zone, which forwards DNS queries to DNS2TCP server, 192.168.212.71. The configuration is shown in Figure 2.
Figure 2: DNS tunneling domain: dns2tcp.tunnel.srt.blox
1.3 DNS2TCP Installation and Configuration
- DNS2TCP Server
First I install dns2tcp package in the Ubuntu guest OS.
apt-get install dns2tcp
Then I configure the DNS2TCP server options. The listing IP address is its local network interface 192.168.212.71, and the port number is the DNS port tcp/53. The domain we will use for DNS tunnel is dns2tcp.tunnel.srt.blox.
Since the DNS2TCP server has an IP address is 192.168.212.71, we put the listing IP address on this interface, and port number to be 53. In this study, I only focus on SSH session over DNS tunneling.
Figure 3. Configuration on DNS2TCP Server
Last, I start DNS tunneling daemon by running the command below.
dns2tcpd –F –d 3 –f config.dns2tcp.tunel.srt.blox.txt
- DNS2TCP Client
Similar to DNS2TCP server, first we need to install dns2tcp package in the Ubuntu guest OS. Second we configure the DNS2TCP client as follows.
Figure 4. Configuration on DNS2TCP Client
At last, we run DNS2TCP application as proxy in the client,
dns2tcpc –d 3 –f config.dns2tcp-client.txt
Now, we can start SSH session to the SSH server 192.168.212.91 using DNS tunneling.
ssh email@example.com –p 2222 –D 8081
It should be able to connect to the SSH server through DNS tunneling channel.
2 DNS2TCP Network Capture
I install Wireshark pcap tool  on the DNS2TCP client to capture all the traffic that we have seen during the experiments. In order to reduce the noise and irrelevant packets, I apply capture-filters in Wireshark and only capture the DNS traffic on port 53 on the network interface.
2.2 Testing Cases
In order to study the DNS tunneling traffic on different use cases and scenarios, I captured the DNS2TCP tunneling traffic for the following testing cases:
- Handshake between DNS2TCP client and DNS2TCP server without any applications.
- A single SSH session when DNS2TCP has no key configured.
- A single SSH session when DNS2TCP has a wrong key configured.
- A single SSH session when DNS2TCP has a correct key configured.
- Multiple SSH sessions when DNS2TCP has correct key configured.
To avoid possible bias or unexpected network issues, I repeated the above testing scenarios at least 5 times and collected their network pcaps respectively. Also I entered various shell commands for SSH sessions when DNS2TCP tunnel is connected.
2.3 Pcap Archives
During my study, I have collected 18 pcaps on different testing cases. The size of the pcap is from 690 bytes to 460 KBytes. The pcap list is shown in the Figure 5 below. The naming convention is roughly like [ToolName]-[Application]-[Retry]-[TestingScenarios].pcap. Please note that, traffic on multiple DNS2TCP handshake experiments is captured within one pcap.
Figure 6 also shows the DNS tunneling traffic in details. We can see that there are quite a number of DNS queries on dns2tcp.tunnel.srt.blox, which actually are DNS traffic that encapsulates SSH session over DNS tunneling.
Figure 5. List of captured traffic
Figure 6. DNS tunneling traffic
3 Analysis on DNS2TCP Traffic
3.1 Encode/Decode Method
DNS2TCP tool uses base64 encode/decode algorithm to encapsulate/decapsulate the SSH traffic into DNS query request/response.
Base64 is one of encode/decode algorithms to convert binary format data into text format data. It is commonly used in SMTP attachment. The detailed information can be found at wiki page .
3.2 DNS Tunneling Packets
Here are some samples of DNS packets that we captured in DNS tunneling session.
1 0.000000 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT AAAAAPlbAA.=auth.dns2tcp.tunnel.srt.blox
2 0.003993 192.168.212.71 -> 192.168.212.81 DNS Standard query response TXT
3 0.004040 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn+FgAABADEzMjFGMjRCQTgyMUVCNzM4MjdGNUM0RjU1NzVGMjJFMkJBNTUxMUU.=auth.dns2tcp.tunnel.srt.blox
4 0.005772 192.168.212.71 -> 192.168.212.81 DNS Standard query response TXT
5 0.005794 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8Tv9+PAHNzaA.=connect.dns2tcp.tunnel.srt.blox
6 0.016487 192.168.212.71 -> 192.168.212.81 DNS Standard query response TXT
7 0.016698 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAABBA.dns2tcp.tunnel.srt.blox
8 0.016747 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAACCFNTSC0yLjAtT3BlblNTSF82LjYuMXAxIFVidW50dS0ydWJ1bnR1Mg0.K.dns2tcp.tunnel.srt.blox
9 0.016776 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAADBA.dns2tcp.tunnel.srt.blox
10 0.027635 192.168.212.71 -> 192.168.212.81 DNS Standard query response TXT
11 0.027713 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAQAEBA.dns2tcp.tunnel.srt.blox
12 0.027999 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAFCAAAB6wIFH/YzMOkC0BJ0kmaj8GQ3TIAAADUY3VydmUyNTUxOS1zaGE.yNTZAbGlic3NoLm9yZyxlY2RoLXNoY
13 0.028038 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAGBA.dns2tcp.tunnel.srt.blox
14 0.028062 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAHCGhlbGxtYW4tZ3JvdXAtZXhjaGFuZ2Utc2hhMjU2LGRpZmZpZS1oZWx.sbWFuLWdyb3VwLWV4Y2hhbmdlLXNoY
15 0.028083 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAIBA.dns2tcp.tunnel.srt.blox
16 0.028104 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAJCAAAAWdlY2RzYS1zaGEyLW5pc3RwMjU2LWNlcnQtdjAxQG9wZW5zc2g.uY29tLGVjZHNhLXNoYTItbmlzdHAzO
17 0.028125 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAKBA.dns2tcp.tunnel.srt.blox
18 0.028146 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAALCHNzaC5jb20sc3NoLWVkMjU1MTktY2VydC12MDFAb3BlbnNzaC5jb20.sc3NoLXJzYS1jZXJ0LXYwMUBvcGVuc
19 0.028166 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAAMBA.dns2tcp.tunnel.srt.blox
20 0.028187 192.168.212.81 -> 192.168.212.71 DNS Standard query TXT hn8AAAANCG5zc2guY29tLHNzaC1kc3MtY2VydC12MDBAb3BlbnNzaC5jb20sZWN.kc2Etc2hhMi1uaXN0cDI1NixlY2RzY
The first few DNS queries should be the encapsulations on TCP/SSH handshakes. The remaining part from packet #8 should be the real content of SSH payload. Here are some observations from all the pcaps we collected:
- DNS2TCP uses the fixed subdomain for the TCP/SSH handshakes. That is, .=auth., .=connect.. We can see the subdomains in the packet #1, #3, #5.
- DNS2TCP uses the first 4 bytes of subdomain to maintain and track the same session. For example, hn8A is used for the flow here. We can see that each DNS query, they always start with hn8A in this flow. We call it as session-tag.
- DNS2TCP uses base64 for encode/decode method. By removing session-tag, we can use base64 to decode the pattern in packet #8. Figure 7 shows the real payload in SSH session after the decoding. We can see “SSH-2.0-OpenSSH_” text inside.
Figure 7. DNS query domain after Based64 decode
3.3 DNS2TCP Tunneling FLow
As I mentioned above, DNS2TCP has a session-tag to track each flow. It would be a good indicator for us to cluster various DNS2TCP queries into their own corresponding sessions.
Beside the session-tag we observed, we also find that,
- DNS2TCP has a high query rate on the same tunneling domain, and/or high volume of the subdomain names.
- DNS2TCP has a high number of unique subdomains over a short period.
- Length of subdomain name is quite long, which varies from 50 to 160 bytes.
- Some specific characters such as “+”, “/” also appear in the subdomain name.
4 Suggestion for DNS2TCP Tunnel Detection
Based on our observation in Chapter 3, I will provide some suggestions for the DNS2TCP tunneling detection. However, please note that in this blog we only demonstrate the results on SSH session over DNS2TCP tunneling. For other applications in SMTP or POP3, we can apply the same techniques to analyze the network traffic patterns on the corresponding protocols and develop similar rules for the DNS2TCP detection.
4.1 Payload Detection
4.1.1 Detection for new DNS2TCP negotiation
We inspect the DNS query name and find the subdomain field on “=auth” and “=connect”.
4.1.2 Detection for SSH negotiation
For each SSH connection, there will be “SSH-2.0” string from client to indicate it is SSH 2.0 session. We can look base64 encoding on this string pattern. So we can inspect the DNS query name to find “FNTSC0yLjAt” in the subdomain field.
4.2 Machine-Learning Analytics-based Detection
Infoblox released NIOS 7.3 which introduced DNS Threat Analytics for Data Exfiltration Prevention early this year in 2016. For most DNS tunneling tools, Infoblox Advanced DNS Protection (ADP) product with NIOS 7.3 or above are able to detect and block most DNS tunneling behaviors. Please refer to our Infoblox product  and Infoblox blog pages  for details.
In this blog, I used DNS2TCP as an example to show our study on DNS tunneling tools. The research process on other DNS tunneling tools should be similar, although they might have different configurations and features. In general, we need to setup a testbed for the DNS tunneling tools, try to run it and capture some DNS tunneling traffic, and then analyze the network traffic to get their DNS subdomain patterns and/or DNS query behaviors.
- Greg Farnham, Detecting DNS Tunneling, 2013, by the SANS Institute. http://www.sans.org/reading-room/whitepapers/dns/detecting-dns-tunneling-34152,
- DNS2TCP Tool, http://www.aldeid.com/wiki/Dns2tcp
- Wireshark Tool, https://www.wireshark.org/
- Base64, http://en.wikipedia.org/wiki/Base64
- Infoblox Advanced DNS Protection, https://www.infoblox.com/products/secure-dns/advanced-dns-protection
- Introducing DNS Threat Analytics for Data Exfiltration Prevention, https://community.infoblox.com/t5/Community-Blog/Introducing-DNS-Threat-Analytics-for-Data-Exfiltrat…