Sudomy: The Bash Orchestrator That Weaponizes 22 APIs for Subdomain Reconnaissance
Hook
While most subdomain enumeration tools query 5-7 data sources, Sudomy aggregates intelligence from 22 different third-party services in a single execution—all orchestrated by 3,000 lines of Bash script that somehow works.
Context
Bug bounty hunters and penetration testers face a fundamental challenge: modern web applications distribute their attack surface across dozens or hundreds of subdomains. A company’s main website might be hardened, but dev.company.com or staging-api.company.com could expose critical vulnerabilities. Traditional subdomain discovery relied on DNS zone transfers (rarely permitted) or bruteforcing DNS records (slow and incomplete).
The explosion of certificate transparency logs, passive DNS databases, and threat intelligence platforms created a new opportunity: passive enumeration. By aggregating data from services that already crawled and indexed the internet, security researchers could discover subdomains without ever touching the target infrastructure. The problem shifted from “how do we find subdomains?” to “how do we efficiently query 20+ data sources, deduplicate results, and filter out garbage?” Sudomy emerged as a Bash-based answer to this orchestration challenge, creating a reconnaissance pipeline that chains together subdomain discovery, DNS resolution, HTTP probing, port scanning, and vulnerability detection into a single automated workflow.
Technical Insight
Sudomy’s architecture is essentially a state machine implemented in Bash, moving discovered domains through sequential processing stages. Each stage produces output files that feed into the next stage, with the tool managing file I/O, process execution, and error handling through shell scripting conventions.
The passive enumeration phase demonstrates this orchestration pattern. Sudomy doesn’t implement its own API clients—instead, it shells out to existing tools and parses their output. For Censys, it invokes the Python CLI; for Shodan, it uses curl with API keys; for certificate transparency logs, it queries crt.sh directly. Here’s a simplified version of how it aggregates results:
# Subdomain collection from multiple sources
function passive_recon() {
DOMAIN=$1
OUTPUT_DIR=$2
# Certificate Transparency via crt.sh
curl -s "https://crt.sh/?q=%25.${DOMAIN}&output=json" | \
jq -r '.[].name_value' | sed 's/\*\.//g' | \
sort -u >> "${OUTPUT_DIR}/crtsh.txt"
# Shodan API query
if [[ -n "$SHODAN_API" ]]; then
curl -s "https://api.shodan.io/dns/domain/${DOMAIN}?key=${SHODAN_API}" | \
jq -r '.data[]?' | \
sort -u >> "${OUTPUT_DIR}/shodan.txt"
fi
# Aggregate and deduplicate
cat "${OUTPUT_DIR}"/*.txt | \
sort -u | \
grep -E "^([a-z0-9-]+\.)*${DOMAIN}$" > "${OUTPUT_DIR}/all_subdomains.txt"
}
The virtual host grouping feature reveals Sudomy’s intelligence layer. After DNS resolution, it parses the results to identify which subdomains resolve to the same IP address. This prevents redundant port scanning—if 20 subdomains share an IP, you only need to scan that IP once. The implementation uses associative arrays (a Bash 4+ feature) to build this mapping:
# Group subdomains by IP address
declare -A ip_to_subdomains
while IFS=, read -r subdomain ip; do
if [[ -n "$ip" ]]; then
ip_to_subdomains["$ip"]+="${subdomain} "
fi
done < resolved_domains.csv
# Output virtual host groups
for ip in "${!ip_to_subdomains[@]}"; do
echo "[+] IP: $ip -> Hosts: ${ip_to_subdomains[$ip]}"
done
The HTTP probing stage chains together httprobe (to detect web servers on both standard and non-standard ports) and gowitness (for screenshot capture). This demonstrates Sudomy’s “glue code” philosophy—it doesn’t reinvent web probing, it just coordinates existing tools efficiently. The tool pipes httprobe output directly into subsequent stages:
# HTTP/HTTPS probing pipeline
cat alive_subdomains.txt | \
httprobe -c 50 | \
tee web_services.txt | \
aquatone -threads 10 -out screenshots/
The multiprocessing approach for DNS resolution shows pragmatic Bash parallelism. Instead of implementing thread pools, Sudomy uses GNU Parallel or xargs to distribute DNS queries across multiple processes. This parallelization is critical when resolving thousands of candidate subdomains:
# Parallel DNS resolution using dnsprobe
cat candidate_subdomains.txt | \
dnsprobe -r resolvers.txt -threads 100 -o resolved.txt
What makes Sudomy particularly valuable for bug bounty workflows is its URL intelligence gathering from web archives. It queries the Wayback Machine, CommonCrawl, and UrlScan.io to extract historical URLs, then categorizes them by file type (JavaScript, PDFs, parameters). This reveals forgotten endpoints and potential attack vectors:
# Extract URLs from Wayback Machine
curl -s "http://web.archive.org/cdx/search/cdx?url=*.${DOMAIN}/*&output=json&collapse=urlkey" | \
jq -r '.[]|select(.[2]|test("application/javascript"))|.[2]' | \
grep -oP 'https?://[^"]+\.js' | \
sort -u > js_files.txt
The output generation phase creates structured artifacts: HTML reports with embedded visualizations, CSV files for spreadsheet import, and even network topology graphs using Graphviz. This output-first design acknowledges that reconnaissance data is only valuable if it’s actionable and shareable with teams.
Gotcha
The Bash implementation creates real operational friction. Error handling is rudimentary—if one API call fails, debugging requires reading through terminal output or log files to identify which of the 22 services broke. There’s no graceful degradation; if a tool in the pipeline isn’t installed or configured properly, the entire workflow can fail silently or produce incomplete results. Modern exception handling and logging frameworks simply don’t exist in Bash’s world.
API dependency creates a bottleneck that fundamentally limits scalability. Many of the 22 services enforce rate limits (SecurityTrails: 100 queries/month on free tier; Shodan: 100 queries/month; Censys: 250 API calls/month). If you’re scanning large corporations with extensive subdomain footprints, you’ll hit these limits within hours. The tool doesn’t implement intelligent quota management or caching—each run consumes fresh API credits. Furthermore, API keys require manual configuration in a config file, which becomes a maintenance burden when services change their authentication schemes or deprecate endpoints. In 2024, several of Sudomy’s configured services have modified their APIs or introduced stricter authentication, meaning portions of the passive enumeration might fail without obvious warnings.
Verdict
Use if: You’re conducting bug bounty or pentest engagements where comprehensive subdomain discovery justifies the setup overhead, you’re running on Linux/WSL infrastructure where Bash dependencies aren’t problematic, you already have API keys for major reconnaissance services and want a single command to orchestrate them all, or you need automated generation of HTML reports and visual artifacts for client deliverables. Sudomy excels when you want “turn-key” reconnaissance that sacrifices flexibility for convenience. Skip if: You need production-grade reliability with proper error handling and logging, you’re working in resource-constrained environments where running 10+ external tools is impractical, you require cross-platform support for Windows or macOS native execution, or you want fine-grained control over individual enumeration techniques without Bash abstraction layers. For modern workflows, consider migrating to Go-based alternatives like Amass or modular ProjectDiscovery toolchains that offer better performance, error handling, and maintainability.