Skip to content
Back to skills

04 Subdomain Enum

ASecurity

Enumerate subdomains using passive and active techniques (subfinder, amass, chaos, assetfinder, crtsh, DNS brute force). Use when the user has a root domain in scope and needs the full subdomain list before probing.

  • 666 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
ai-agentsrustgobashrailsgitapisecurity

Works with

  • api

Security analysis

A92/100
  • mediumUses curl or wget to download content
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 2, 2026

npx -y skills add majiayu000/claude-skill-registry --skill 04-subdomain-enum --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 04 Subdomain Enum?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 04 Subdomain Enum
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-04-subdomain-enum/badge)](https://www.skillsdirectory.com/skills/majiayu000-04-subdomain-enum)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: subdomain-enum
description: Enumerate subdomains using passive and active techniques (subfinder, amass, chaos, assetfinder, crtsh, DNS brute force). Use when the user has a root domain in scope and needs the full subdomain list before probing.
metadata:
  type: skill
  phase: recon
  tools: [subfinder, amass, assetfinder, chaos, findomain, sublist3r, crtsh, anew]
---

# Subdomain Enumeration

> Maximum coverage. Multiple sources. Continuously updated.

## When to invoke

**Trigger phrases:**
- "enumerate subdomains for X"
- "subfinder X"
- "find subdomains of target.com"
- "run full subdomain recon"

## Pre-flight checklist

- [ ] Scope confirmed: `*.target.com` is in-scope (see `[[scope-analysis]]`)
- [ ] OOS list ready (to filter results)
- [ ] API keys configured (see below)
- [ ] Output dir created: `mkdir -p loot/<target>/subs/`

## API keys (set these once)

Most passive sources work without keys but **with keys you 3-5x your coverage**:

```bash
# ~/.config/subfinder/provider-config.yaml
chaos:
  - "YOUR_CHAOS_KEY"
binaryedge:
  - "YOUR_BINARYEDGE_KEY"
censys:
  - "ID:SECRET"
github:
  - "ghp_YOUR_GITHUB_TOKEN"
shodan:
  - "YOUR_SHODAN_KEY"
securitytrails:
  - "YOUR_SECURITYTRAILS_KEY"
virustotal:
  - "YOUR_VT_KEY"
```

Free tiers (sign up):
- **Chaos:** https://chaos.projectdiscovery.io (free for BB hunters)
- **Censys:** 250 queries/month free
- **GitHub:** any PAT works
- **SecurityTrails:** 50/month free
- **VirusTotal:** 4 req/min free

## The full pipeline

### 1. Passive enumeration (no traffic to target)

```bash
TARGET="target.com"
OUT="loot/$TARGET/subs"
mkdir -p "$OUT"

# subfinder — fastest, broadest passive
subfinder -d "$TARGET" -all -recursive -silent > "$OUT/subfinder.txt"

# assetfinder — adds extra sources
assetfinder --subs-only "$TARGET" > "$OUT/assetfinder.txt"

# chaos — ProjectDiscovery's curated dataset
chaos -d "$TARGET" -silent > "$OUT/chaos.txt"

# crtsh — certificate transparency
curl -s "https://crt.sh/?q=%25.${TARGET}&output=json" | \
    jq -r '.[].name_value' | sed 's/\*\.//g' | sort -u > "$OUT/crtsh.txt"

# findomain — Rust-based, fast
findomain -t "$TARGET" -q > "$OUT/findomain.txt" 2>/dev/null

# github-subdomains — mines GitHub for subdomain mentions
# pip install github-subdomains (or use the Go tool)
github-subdomains -d "$TARGET" -t "$GITHUB_TOKEN" -o "$OUT/github.txt"

# Combine & dedupe
cat "$OUT"/*.txt | sort -u > "$OUT/passive.txt"
echo "[+] Passive sources: $(wc -l < "$OUT/passive.txt") unique subdomains"
```

### 2. Active enumeration (DNS brute force)

```bash
# Use a strong wordlist (assetnote wordlists are gold)
WORDLIST="$HOME/tools/assetnote-wordlists/data/manual/best-dns-wordlist.txt"

# puredns is the modern choice (fast, accurate)
# Install: go install github.com/d3mondev/puredns/v2@latest
puredns bruteforce "$WORDLIST" "$TARGET" \
    -r resolvers.txt \
    --rate-limit 1000 \
    --write "$OUT/bruteforce.txt"

# Alternative: shuffledns + dnsx
shuffledns -d "$TARGET" -w "$WORDLIST" -r resolvers.txt -mode bruteforce > "$OUT/shuffle.txt"
```

**Get a fresh resolvers file** (critical for speed):
```bash
# Resolvers — use trusted, fast ones
curl -s https://raw.githubusercontent.com/proabiral/Fresh-Resolvers/master/resolvers.txt > resolvers.txt
# Validate them
dnsvalidator -tL resolvers.txt -threads 200 -o validated-resolvers.txt
```

### 3. Permutation / alteration

```bash
# Combine known subs into permutations
gotator -sub "$OUT/passive.txt" -perm permutations.txt -depth 1 -numbers 5 | \
    puredns resolve --resolvers validated-resolvers.txt > "$OUT/permutations.txt"

# Alternative: dnsgen
cat "$OUT/passive.txt" | dnsgen - | puredns resolve --resolvers validated-resolvers.txt > "$OUT/dnsgen.txt"
```

### 4. Combine, dedupe, filter OOS

```bash
# Everything in one file
cat "$OUT"/*.txt | sort -u > "$OUT/all.txt"

# Remove out-of-scope (from scope-analysis output)
grep -vFf "scope-oos.txt" "$OUT/all.txt" > "$OUT/in-scope.txt"

echo "[+] Total subdomains: $(wc -l < "$OUT/all.txt")"
echo "[+] In-scope:         $(wc -l < "$OUT/in-scope.txt")"
```

### 5. Hand off to next skill

The output `$OUT/in-scope.txt` feeds directly into `[[asset-discovery]]`.

## One-liner full pipeline

```bash
# Save this as scripts/full-sub-recon.sh
TARGET=$1
OUT="loot/$TARGET/subs"
mkdir -p "$OUT"

(subfinder -d "$TARGET" -all -silent;
 assetfinder --subs-only "$TARGET";
 chaos -d "$TARGET" -silent;
 curl -s "https://crt.sh/?q=%25.${TARGET}&output=json" | jq -r '.[].name_value' | sed 's/\*\.//g';
 findomain -t "$TARGET" -q 2>/dev/null) | sort -u | anew "$OUT/passive.txt"

echo "[+] Passive done: $(wc -l < "$OUT/passive.txt") subs"
```

Run:
```bash
chmod +x scripts/full-sub-recon.sh
./scripts/full-sub-recon.sh target.com
```

## Continuous mode

Set up nightly diff alerts → see `[[continuous-monitoring]]`.

```bash
# In cron
0 3 * * * cd /home/user/bb && ./scripts/full-sub-recon.sh target.com && \
          diff -u loot/target.com/subs/yesterday.txt loot/target.com/subs/passive.txt | \
          grep '^+' | grep -v '^+++' | \
          notify -bulk -id discord
```

## Output template

```
target.com
├── subs/
│   ├── passive.txt        ← passive sources
│   ├── bruteforce.txt     ← active DNS brute
│   ├── permutations.txt   ← gotator/dnsgen
│   ├── all.txt            ← combined+sorted
│   └── in-scope.txt       ← filtered against OOS
└── stats.txt
    ├── 247 total
    ├── 14 OOS removed
    └── 233 in-scope
```

## Cross-references

- `[[scope-analysis]]` — gives you the OOS filter
- `[[asset-discovery]]` — next: which of these are alive?
- `[[continuous-monitoring]]` — nightly diff alerts
- `[[subdomain-takeover]]` — check for dangling DNS

## Common pitfalls

1. **No API keys** = passive coverage drops ~70%. Configure Chaos minimum.
2. **Bad resolvers** = false positives. Validate with `dnsvalidator`.
3. **Including OOS** = wasted hunt time, possible report rejection.
4. **One-shot enumeration** = misses new subdomains added daily. Continuous is critical.
5. **Trusting brute force alone** = misses passive-only subs (like internal CDN names).

## Anti-WAF / stealth tips

- Some programs have WAFs on `*.target.com` that rate-limit recon
- Throttle: `--rate-limit 100` on puredns
- Use rotating User-Agents on HTTP-based sources (httpx)
- For private programs, ask the manager if there's a recon allowlist for your IP

## Validation: did we cover everything?

Sanity checks:
- Number of subs > 10 for any non-trivial target?
- Did `*.api.target.com` show up if APIs exist?
- Are subdomain levels covered? (`a.b.c.target.com`)
- Did Wayback / waybackurls also reveal hostnames we missed?
  - ```cat all-urls-from-wayback.txt | unfurl domains | grep target.com | anew "$OUT/wayback-domains.txt"```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.