pentesting-dns

$npx mdskill add xalgord/xalgorix/pentesting-dns

- Default port `53/tcp` and `53/udp` (queries on UDP, zone transfers and large answers on TCP); `5353/udp` for mDNS/zeroconf. - When `nmap`/banner shows `domain`, e.g. `53/tcp open domain Microsoft DNS 6.1.7601 ... Windows Server 2008 R2 SP1`. - For mapping an organization's attack surface (subdomains, mail/AD infrastructure) and for finding misconfigured authoritative/recursive servers.

SKILL.md

.github/skills/pentesting-dnsView on GitHub ↗
---
name: pentesting-dns
description: Testing DNS services (default 53/TCP+UDP, 5353/UDP mDNS) for zone transfers (AXFR), version/banner disclosure, subdomain and reverse-lookup enumeration, open recursion/amplification, DNSSEC and CAA misconfiguration, and Active Directory SRV record discovery during authorized engagements.
domain: cybersecurity
subdomain: network-services-pentesting
tags:
- penetration-testing
- network-services
- dns
version: '1.0'
author: xalgorix
license: Apache-2.0
---

# Pentesting DNS (port 53)

## When to Use
- Default port `53/tcp` and `53/udp` (queries on UDP, zone transfers and large answers on TCP); `5353/udp` for mDNS/zeroconf.
- When `nmap`/banner shows `domain`, e.g. `53/tcp open domain Microsoft DNS 6.1.7601 ... Windows Server 2008 R2 SP1`.
- For mapping an organization's attack surface (subdomains, mail/AD infrastructure) and for finding misconfigured authoritative/recursive servers.

## Quick Enumeration
```bash
# Version banner (works on most BIND servers)
dig version.bind CHAOS TXT @<DNS_IP>
nmap -p53 --script dns-nsid <DNS_IP>      # also grabs NSID/version

# Default DNS NSE sweep
nmap -n --script "(default and *dns*) or fcrdns or dns-srv-enum or dns-random-txid or dns-random-srcport" <IP>

# Record lookups
dig ANY  @<DNS_IP> <DOMAIN>     # everything the server will disclose
dig A    @<DNS_IP> <DOMAIN>
dig AAAA @<DNS_IP> <DOMAIN>
dig TXT  @<DNS_IP> <DOMAIN>
dig MX   @<DNS_IP> <DOMAIN>
dig NS   @<DNS_IP> <DOMAIN>
dig -x 192.168.0.2 @<DNS_IP>    # reverse lookup

# Interactive
nslookup
> SERVER <DNS_IP>
> <IP_MACHINE>                   # reverse lookup
```

## Critical: Checks Most Often Missed
- **Zone transfer (AXFR)** — the single highest-value miss; dumps the entire zone (every host/record). Try with and without a guessed domain:
```bash
dig axfr @<DNS_IP>                 # try without a domain
dig axfr @<DNS_IP> <DOMAIN>        # try guessing the domain
fierce --domain <DOMAIN> --dns-servers <DNS_IP>   # AXFR against every NS, then dict attack
dnsrecon -d active.htb -a -n <DNS_IP>             # zone transfer
```
- **Open recursion / amplification** — if recursion is on, the server can be abused for reflected DDoS using big `ANY`/`DNSSEC` answers.
- **Active Directory SRV records** — `_gc`, `_ldap`, `_kerberos`, `_kpasswd` reveal domain controllers.
- **DNSSEC/NSEC zone walking**, lame/out-of-sync delegation, overly broad **CAA** `issue`/`issuewild`, and very low TTLs (accelerate malicious record propagation).

### How to CONFIRM
- AXFR success: `dig axfr` returns multiple records and a closing SOA instead of `Transfer failed`/`connection timed out`.
- Recursion available: `dig google.com A @<IP>` response **flags** contain `ra` (recursion available).
- AD environment: SRV queries return `_kerberos._tcp`/`_ldap._tcp` targets pointing at DCs.
- Version disclosure: `dig version.bind CHAOS TXT` returns a version string instead of refused/empty.

## Workflow

### Step 1: Enumerate
Fingerprint with `dig version.bind CHAOS TXT @<DNS_IP>` / `fpdns` / `nmap --script dns-nsid`. Run the default `*dns*` NSE sweep. Identify whether the server is authoritative, recursive, or caching.

### Step 2: Authenticate / unauth access
DNS queries are unauthenticated. Test the trust boundary instead: attempt AXFR (relies on a permissive `allow-transfer`), and test recursion (`allow-recursion`/`allow-query`) by querying an external domain and checking the `ra` flag.

### Step 3: Exploit / Extract
- Pull the zone via AXFR if allowed.
- Brute force subdomains and reverse ranges when AXFR is blocked:
```bash
for sub in $(cat <WORDLIST>); do dig $sub.<DOMAIN> @<DNS_IP> | grep -v ';\|SOA' | sed -r '/^\s*$/d' | grep $sub | tee -a subdomains.txt; done
dnsenum --dnsserver <DNS_IP> --enum -p 0 -s 0 -o subdomains.txt -f <WORDLIST> <DOMAIN>
dnsrecon -D subdomains-1000.txt -d <DOMAIN> -n <DNS_IP>
dnsrecon -r 127.0.0.0/24 -n <DNS_IP>     # reverse sweep
dnsdict6 -s -t <domain>                   # IPv6 (AAAA) brute force
```
- Enumerate AD/service records:
```bash
dig -t _gc._tcp.lab.domain.com
dig -t _ldap._tcp.lab.domain.com
dig -t _kerberos._tcp.lab.domain.com
nmap --script dns-srv-enum --script-args "dns-srv-enum.domain='domain.com'"
nmap -sSU -p53 --script dns-nsec-enum --script-args dns-nsec-enum.domains=<DOMAIN> <NS_IP>  # NSEC walk
```

### Step 4: Post-access / pivot
Use recovered hostnames/IPs (especially internal-IP subdomains) to reach internal services; if a subdomain resolves to an internal IP, do reverse-DNS brute forcing of that range against the zone's NS. Send mail to a non-existent address at the domain to harvest internal server names/IPs from the NDN bounce headers.

## Key Concepts
| Concept | Description |
|---------|-------------|
| **AXFR** | Asynchronous Full Transfer Zone — dumps an entire zone if `allow-transfer` is permissive |
| **Authoritative vs recursive/caching** | Authoritative answers for its zones; recursive resolves for clients (recursion = amplification risk) |
| **`ra` flag** | "Recursion available" in the response; indicates open recursion |
| **SRV records** | `_service._proto` records locating servers (AD DCs via `_kerberos`/`_ldap`/`_gc`) |
| **DNSSEC / NSEC** | Signed zones; NSEC chains can be walked to enumerate names |
| **CAA** | Authorizes which CAs may issue certs; over-broad policy widens cert-abuse surface |

## Tools & Systems
| Tool | Purpose |
|------|---------|
| **dig** | All record types, AXFR, version.bind, recursion/DNSSEC checks |
| **nslookup** | Interactive queries / reverse lookups |
| **fierce** | AXFR attempts against every NS then dictionary brute force |
| **dnsrecon** | Zone transfer, reverse sweeps, subdomain brute force |
| **dnsenum** | Subdomain enumeration with wordlists |
| **dnscan / dnsdict6** | Recursive and IPv6 subdomain brute forcing |
| **nmap dns-* NSE** | dns-nsid, dns-srv-enum, dns-nsec-enum, recursion checks |
| **Metasploit** | `auxiliary/gather/enum_dns`, `auxiliary/scanner/dns/dns_amp` |

## Common Scenarios
### Scenario 1: Open AXFR
`dig axfr @<DNS_IP> <DOMAIN>` succeeds and dumps the full zone, exposing every internal hostname and IP — instant attack-surface map.

### Scenario 2: AD domain controller discovery
SRV queries for `_ldap._tcp` and `_kerberos._tcp` return the FQDNs and ports of domain controllers, seeding AD attacks.

### Scenario 3: Open recursion amplifier
`dig google.com A @<IP>` shows the `ra` flag; the resolver can be abused for `ANY`/DNSSEC reflection amplification.

## Output Format
```
## DNS Finding

**Service**: DNS (53/tcp+udp)
**Severity**: <High|Medium|Low>
**Target**: <DNS_IP>  Software: <BIND x.y | Microsoft DNS ...>

### Evidence
- AXFR allowed: dig axfr @<IP> <DOMAIN> returned full zone (<N> records)
- Recursion available (ra flag) -> amplification risk
- AD SRV records disclosed DCs: <hostnames>
- version.bind: <version string>

### Reproduction
dig axfr @<DNS_IP> <DOMAIN>
dig google.com A @<DNS_IP>     # check ra flag

### Recommendation
1. Restrict `allow-transfer` to secondary NS only; block AXFR from untrusted IPs
2. Disable recursion on authoritative servers (`allow-recursion`/`recursion no`)
3. Hide version (`version "";` in BIND options)
4. Tighten CAA, ensure DNSSEC key rollover (DS/CDS) is consistent
```

More from xalgord/xalgorix