agentsclimarketplace

04 subdomain enum

Skill 0xGhostCAT/claude-ai-cyber-security-skills/skills/04-subdomain-enum

30 Claude Code Skills + 60+ integrated tools for HackerOne/Bugcrowd bug bounty hunters

Install
npx -y skills add 0xGhostCAT/claude-ai-cyber-security-skills --skill 04-subdomain-enum

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.

What its author says it does

Copied from the file, not written here

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.

SKILL.md

6.7 KB, as published. Nobody here has run it

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:

# ~/.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)

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)

# 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):

# 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

# 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

# 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

# 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:

chmod +x scripts/full-sub-recon.sh
./scripts/full-sub-recon.sh target.com

Continuous mode

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

# 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"

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.