Production-ready subdomain enumeration for security researchers. Fast, intelligent, and respectful of rate limits.
Stop cobbling together multiple tools. DNX combines passive reconnaissance with active brute-forcing in one clean package. Written in Perl for speed and portability.
10 API sources + parallel DNS resolution + wildcard detection + takeover checks = Complete subdomain discovery
# Install dependencies and run
make deps
./dnx --domain target.com
# Full scan with all features
./dnx -d target.com --wordlist subdomains.txt --threads 50 \
--recursive --http-probe --takeover-check
# Passive only (zero packets to target)
./dnx -d target.com --passivemake deps && sudo make install# Install Perl modules
cpanm LWP::UserAgent JSON Net::DNS Term::ANSIColor
# Make executable
chmod +x dnx
# Optional: Install system-wide
sudo cp dnx /usr/local/bin/make # Syntax check
make deps # Install dependencies
make install # Install to /usr/local/bin
make uninstall # Remove from system
make test # Run tests
make clean # Clean cache and outputs
make help # Show all commandsPassive Enumeration • Query 10 sources without touching the target
Active Brute-Force • Parallel DNS resolution with custom wordlists
Wildcard Detection • Automatically filter false positives
Smart Caching • 24-hour cache reduces API load
Multi-Format Output • Text, JSON, CSV exports
Progress Tracking • Real-time progress bars and ETA
Graceful Exit • Ctrl+C saves partial results
DNS Rotation • Distribute queries across multiple resolvers
Record Type Support • A, AAAA, CNAME, MX, NS, TXT, SOA
Recursive Discovery • Find subdomains of subdomains
Zone Transfer • Attempt AXFR on misconfigured servers
HTTP Probing • Test service availability and extract titles
Takeover Detection • Identify vulnerable subdomains
crt.sh • Certificate Transparency logs
HackerTarget • DNS and threat intelligence
ThreatCrowd • Crowdsourced threat data
AlienVault OTX • Open Threat Exchange
Riddler.io • Comprehensive DNS database
BufferOver • DNS enumeration service
URLScan • URL scanning and analysis
VirusTotal • Enhanced subdomain discovery
Shodan • Internet-wide scanning data
SecurityTrails • Historical DNS data
# Quick passive scan
./dnx -d github.com
# Passive + brute-force
./dnx -d stripe.com --wordlist subdomains.txt
# High-speed mode (50 threads)
./dnx -d target.com -w large-list.txt --threads 50
# Save results
./dnx -d target.com -o results.json --format json# Custom DNS resolvers
./dnx -d target.com --resolvers 1.1.1.1,8.8.8.8,9.9.9.9
# Multiple record types
./dnx -d target.com --record-types A,AAAA,MX,NS,TXT
# Recursive discovery
./dnx -d target.com --recursive --recursion-depth 2
# Zone transfer attempt
./dnx -d target.com --zone-transfer
# HTTP probing with takeover detection
./dnx -d target.com --http-probe --takeover-check
# Slow and stealthy
./dnx -d target.com --threads 5 --rate-limit 3
# With API keys for maximum coverage
./dnx -d target.com \
--shodan-key YOUR_SHODAN_KEY \
--virustotal-key YOUR_VT_KEY \
--securitytrails-key YOUR_ST_KEY
# Quiet mode for scripting
./dnx -d target.com -q -o subdomains.txt
# Verbose debugging
./dnx -d target.com -v --wordlist test.txtDNX handles various input formats automatically:
# All of these work:
./dnx -d example.com
./dnx -d https://example.com
./dnx -d http://example.com/path
./dnx -d example.com:443| Option | Description | Default |
|---|---|---|
-d, --domain |
Target domain (required) | - |
-w, --wordlist |
Brute-force wordlist | - |
-t, --threads |
Concurrent threads | 20 |
--timeout |
DNS timeout (seconds) | 5 |
-o, --output |
Output file | stdout |
-f, --format |
text, json, csv | text |
-p, --passive |
Passive only (no DNS) | false |
--no-bruteforce |
Skip brute-force | false |
-q, --quiet |
Minimal output | false |
-v, --verbose |
Detailed logging | false |
-r, --recursive |
Recursive discovery | false |
--recursion-depth |
Recursion depth | 3 |
-z, --zone-transfer |
Attempt AXFR | false |
--http-probe |
Probe HTTP services | false |
--takeover-check |
Check for takeovers | false |
--resolvers |
DNS servers (comma-separated) | 8.8.8.8,1.1.1.1 |
--rate-limit |
API requests/second | 10 |
--record-types |
DNS types to query | A |
--shodan-key |
Shodan API key | - |
--virustotal-key |
VirusTotal API key | - |
--securitytrails-key |
SecurityTrails API key | - |
-h, --help |
Show help | - |
--version |
Show version | - |
Create ~/.dnx/config.ini for persistent settings:
# Performance
threads = 30
timeout = 5
rate_limit = 10
# Output
format = text
# DNS Resolvers
resolvers = 8.8.8.8,1.1.1.1,9.9.9.9
# API Keys (optional)
shodan_api_key = YOUR_KEY_HERE
virustotal_api_key = YOUR_KEY_HERE
securitytrails_api_key = YOUR_KEY_HERE- Sign up: https://www.virustotal.com/
- Get key: https://www.virustotal.com/gui/my-apikey
- Use it:
export VIRUSTOTAL_API_KEY="your_key"
./dnx -d target.com --virustotal-key "your_key"- Sign up: https://account.shodan.io/register
- Get key: https://account.shodan.io/
- Use it:
export SHODAN_API_KEY="your_key"
./dnx -d target.com --shodan-key "your_key"- Sign up: https://securitytrails.com/
- Get key: https://securitytrails.com/app/account/credentials
- Use it:
export SECURITYTRAILS_API_KEY="your_key"
./dnx -d target.com --securitytrails-key "your_key"Clean, colorized terminal output:
www.github.com 140.82.121.4
api.github.com 140.82.121.6
docs.github.com 185.199.108.153
Structured data for automation:
{
"domain": "github.com",
"timestamp": "2025-11-19 12:34:56",
"count": 157,
"subdomains": [
{
"subdomain": "www.github.com",
"ip": "140.82.121.4"
}
]
}Import into spreadsheets:
subdomain,ip
www.github.com,140.82.121.4
api.github.com,140.82.121.6
Passive Scan: 5-15 seconds (network dependent)
1K wordlist @ 20 threads: 30-60 seconds
10K wordlist @ 50 threads: 5-10 minutes
100K wordlist @ 100 threads: 30-45 minutes
# Maximum speed (use with caution)
./dnx -d target.com -w huge.txt --threads 100 --timeout 3
# Balanced approach
./dnx -d target.com -w medium.txt --threads 30 --timeout 5
# Stealth mode
./dnx -d target.com -w small.txt --threads 5 --rate-limit 3Pro Tips:
- Start with passive enumeration
- Use targeted wordlists (quality over quantity)
- Increase threads only if your network can handle it
- Custom resolvers can dramatically improve speed
- Cache is your friend (24-hour retention)
Query multiple record types simultaneously:
./dnx -d target.com --record-types A,AAAA,MX,NS,TXT| Type | Purpose |
|---|---|
| A | IPv4 addresses |
| AAAA | IPv6 addresses |
| CNAME | Canonical name aliases |
| MX | Mail exchange servers |
| NS | Name servers |
| TXT | Text records (SPF, DKIM, etc.) |
| SOA | Start of authority |
Find subdomains of discovered subdomains:
./dnx -d target.com --recursive --recursion-depth 2Automatically tries common patterns on found subdomains:
- www, dev, staging, test, api, admin, portal
Attempt DNS zone transfer on misconfigured servers:
./dnx -d target.com --zone-transferQueries all nameservers and attempts AXFR. Rarely successful on modern infrastructure, but worth trying.
Test if discovered subdomains have active HTTP/HTTPS services:
./dnx -d target.com --http-probeFeatures:
- Tests both HTTP and HTTPS
- Extracts page titles
- Records HTTP status codes
- Follows redirects
Check for vulnerable CNAME records pointing to:
./dnx -d target.com --takeover-checkDetects:
- GitHub Pages (github.io)
- Heroku (herokuapp.com)
- AWS S3 (amazonaws.com)
- Azure (azurewebsites.net)
- CloudFront (cloudfront.net)
Identifies dangling DNS records that could be exploited.
# Full enumeration with all sources
./dnx -d target.com \
--wordlist /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt \
--threads 50 \
--record-types A,AAAA,CNAME \
--recursive \
--http-probe \
--takeover-check \
--output target-subdomains.json \
--format json# Passive only (zero footprint)
./dnx -d target.com --passive --no-bruteforce -o recon.txt
# Review results, then targeted brute-force
./dnx -d target.com -w custom-wordlist.txt --threads 10# Daily cron job
0 2 * * * /usr/local/bin/dnx -d mycompany.com -q -o /var/log/subdomains-$(date +\%Y\%m\%d).json -f json
# Compare changes
diff /var/log/subdomains-20250119.json /var/log/subdomains-20250120.json# Scan multiple domains
for domain in $(cat domains.txt); do
./dnx -d $domain -p -o results/$domain.json -f json
sleep 5
done# Kitchen sink approach
./dnx -d target.com \
--wordlist huge-list.txt \
--threads 50 \
--passive \
--recursive --recursion-depth 2 \
--zone-transfer \
--http-probe \
--takeover-check \
--record-types A,AAAA,CNAME,MX,NS,TXT \
--shodan-key $SHODAN_KEY \
--virustotal-key $VT_KEY \
--securitytrails-key $ST_KEY \
--output full-assessment.json \
--format jsonDNX includes a basic wordlist. For comprehensive scanning:
SecLists (Recommended)
git clone https://github.com/danielmiessler/SecLists.git
./dnx -d target.com -w SecLists/Discovery/DNS/subdomains-top1million-110000.txtOther Quality Lists:
- https://github.com/rbsec/dnscan
- https://gist.github.com/jhaddix/86a06c5dc309d08580a018c66354a056
- https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS
Press Ctrl+C anytime:
- Saves all discovered subdomains
- Shows elapsed time and statistics
- Cleans up temporary files
- No data loss
Automatically filters false positives:
[!] Wildcard DNS detected for *.target.com → 1.2.3.4
[*] Filtering wildcard responses...
Results cached for 24 hours:
- Reduces API load
- Faster repeated scans
- Respects public services
- Automatic cache expiry
# Feed to httpx for live host detection
./dnx -d target.com -q | httpx -silent
# Check with nuclei
./dnx -d target.com -q | nuclei -t vulnerabilities/
# Resolve with massdns
./dnx -d target.com -q > subs.txt
massdns -r resolvers.txt -t A -o S subs.txt
# Screenshots with aquatone
./dnx -d target.com -q | aquatone# Extract subdomains with jq
./dnx -d target.com -f json | jq -r '.subdomains[].subdomain'
# Filter by IP range
./dnx -d target.com -f json | jq '.subdomains[] | select(.ip | startswith("192.168"))'
# Count results
./dnx -d target.com -f json | jq '.count'#!/bin/bash
# Full reconnaissance pipeline
DOMAIN=$1
# Subdomain enumeration
./dnx -d $DOMAIN --passive -o ${DOMAIN}_subs.txt
# Port scanning
cat ${DOMAIN}_subs.txt | naabu -silent -o ${DOMAIN}_ports.txt
# HTTP probing
cat ${DOMAIN}_ports.txt | httpx -silent -o ${DOMAIN}_http.txt
# Vulnerability scanning
cat ${DOMAIN}_http.txt | nuclei -silent -o ${DOMAIN}_vulns.txt
echo "Complete! Results in ${DOMAIN}_*.txt"Combine tools for maximum effectiveness:
# Passive from multiple tools
subfinder -d target.com -all -silent > subs1.txt
./dnx -d target.com --passive --no-bruteforce -q > subs2.txt
cat subs1.txt subs2.txt | sort -u > all_passive.txt
# Verify with DNX brute-force
./dnx -d target.com -w all_passive.txt --threads 50 -o verified.txt
# Probe services
cat verified.txt | httpx -silent -status-code -title -tech-detect
# Check for vulnerabilities
cat verified.txt | nuclei -t cves/ -t vulnerabilities/# Error: Cannot locate Net/DNS.pm
cpanm Net::DNS
# Or install all at once
make deps# Use faster DNS resolvers
./dnx -d target.com --resolvers 1.1.1.1,8.8.8.8
# Increase threads
./dnx -d target.com --threads 50
# Reduce timeout for dead hosts
./dnx -d target.com --timeout 3# Reduce request rate
./dnx -d target.com --rate-limit 5
# Use API keys for higher limits
./dnx -d target.com --virustotal-key YOUR_KEY# Verbose mode shows wildcard detection
./dnx -d target.com -v
# Manual wildcard check
dig randomstring123.target.com# Cache directory permissions
chmod 755 ~/.dnx
chmod 644 ~/.dnx/cache/*
# Output file permissions
./dnx -d target.com -o results.txt
chmod 644 results.txtDO:
- Scan your own domains
- Get written permission before testing
- Respect rate limits and ToS
- Use for authorized security assessments
DON'T:
- Scan without permission
- Abuse public APIs
- Ignore rate limits
- Use for malicious purposes
This tool is for authorized security testing only. Users are responsible for complying with all applicable laws. Unauthorized scanning may be illegal in your jurisdiction.
Pull requests welcome for:
- Additional passive sources
- Performance improvements
- Bug fixes
- Documentation improvements
- New features (discuss first in issues)
Coding Standards:
- Follow existing Perl style
- Add tests for new features
- Update documentation
- Keep dependencies minimal
Q: Why Perl instead of Go/Python/Rust?
A: Perl is ubiquitous, fast for text processing, and the entire tool is a single self-contained script. No compilation needed.
Q: How many API keys do I need?
A: None required! 27 sources work without keys. Add keys for VirusTotal, Shodan, and SecurityTrails to access 3 more premium sources.
Q: Is DNX better than Amass?
A: Different tools for different needs. Amass has 10x more sources and enterprise features. DNX is simpler, lighter, and includes active enumeration + takeover checks in one tool.
Q: Can I use DNX in bug bounties?
A: Yes! Many researchers use DNX for initial reconnaissance. Combine with Subfinder for passive, then DNX for active verification.
Q: Does DNX work on Windows?
A: Yes, with Strawberry Perl or WSL. Best experience on Linux/macOS.
Q: How do I add a new API source?
A: Edit the script and add a function like query_newsource(). Follow existing patterns. PRs welcome!
- AXFR improvements and better error handling
- Certificate transparency stream monitoring
- Subdomain takeover auto-exploitation (ethical mode)
- Integration with Metasploit/Cobalt Strike
- Web interface for teams
- Machine learning for wordlist optimization
- IPv6 support improvements
- Database export (SQLite, PostgreSQL)
Author: bl4ckstack
License: MIT
Version: 1.0.0
Built for security researchers who value speed, accuracy, and respect for infrastructure.
Project: https://github.com/blackstack/dnx
Issues: https://github.com/blackstack/dnx/issues
Wordlists: https://github.com/danielmiessler/SecLists
OWASP Testing: https://owasp.org/www-project-web-security-testing-guide/
Star it if DNX helped you find something interesting • Contributions welcome!
