subenum

command module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2026 License: GPL-3.0 Imports: 15 Imported by: 0

README

subenum

Fast, concurrent subdomain enumeration via DNS brute-forcing. Written in pure Go.


Build

Go CodeQL Release Go Report Card

Concurrent Workers · Context-Aware Cancellation · Retry with Backoff · Wildcard Detection · Simulation Mode · Interactive TUI

Quick Start | Documentation | Architecture | Changelog




Feature Matrix

Module Capabilities
Worker Pool Spawn N goroutines for parallel DNS resolution with configurable concurrency ceiling.
DNS Engine Resolve subdomains against any custom DNS server with per-query timeouts and exponential-backoff retries.
Wildcard Detection Double-probe random subdomain check before scanning; exits early unless -force is set.
Graceful Shutdown Trap SIGINT/SIGTERM, drain in-flight workers, flush partial results to disk.
Input Validation Enforce RFC-compliant domain syntax and strict IP:port format for DNS server arguments.
Wordlist Dedup Automatically remove duplicate entries from the wordlist before scanning.
Simulation Mode Generate synthetic DNS results at a configurable hit rate without network I/O.
Output Pipeline Stream resolved domains to stdout (pipe-friendly); progress and diagnostics go to stderr.
Progress Reporting Live terminal progress with atomic counters, updated on a 2-second ticker.
Interactive TUI Form-based config screen and live-scrolling results view via -tui flag (Bubble Tea). No arguments required.



System Architecture

flowchart LR
    subgraph Input
        A[Wordlist File] -->|"dedup + load"| B(Entry Slice)
        C[CLI Flags] --> D(Argument Parser)
    end

    subgraph PreScan
        D --> W{Wildcard\nDetection}
        W -->|"no wildcard / --force"| E
    end

    subgraph Engine
        B --> E{Worker Pool\nN Goroutines}
        E -->|subdomain.domain| F[DNS Resolver]
        F -->|retry + backoff| F
        G[Context] -->|cancel| E
        G -->|timeout| F
    end

    subgraph OutputLayer ["Output"]
        F -->|resolved| H["stdout (results only)"]
        F -->|resolved| I[Output File]
        E -->|atomic counters| J["stderr (progress)"]
    end

    K[SIGINT / SIGTERM] -->|cancel| G



[!IMPORTANT] Authorized use only. Only scan domains you own or have explicit written permission to test. Unauthorized scanning may violate applicable laws. Users are solely responsible for compliance.

[!NOTE] Wildcard DNS detection. Before scanning, subenum resolves two random subdomains to check for wildcard DNS. If the domain uses wildcard records, the tool exits with a warning (all subdomains would resolve, making results meaningless). Pass -force to override and scan anyway.

[!CAUTION] Simulation mode (-simulate) generates synthetic results and performs zero network I/O. Do not confuse simulated output with real DNS data.




Installation

Prerequisites: Go >= 1.22 · Git · Make (optional) · Docker (optional)

One-liner (build from source):

git clone https://github.com/TMHSDigital/subenum.git && cd subenum && go build -buildvcs=false -o subenum

Pre-built binaries: download from the Releases page (Linux, macOS, Windows).

Docker:

docker build -t subenum . && docker run --rm -v $(pwd)/data:/data subenum -w /data/wordlist.txt example.com

Make:

make build        # compile binary
make simulate     # safe run, no DNS queries
make help         # list all targets

Configuration

Flag Default Description
-w <file> -- Wordlist file, one prefix per line (required)
-t <n> 100 Concurrent worker goroutines
-timeout <ms> 1000 Per-query DNS timeout in milliseconds
-dns-server <ip:port> 8.8.8.8:53 DNS server address (validated on startup)
-attempts <n> 1 Total DNS resolution attempts per subdomain (1 = no retry)
-force false Continue scanning even if wildcard DNS is detected
-o <file> -- Write results to file in addition to stdout
-v false Verbose output: IPs, timings, per-query status (written to stderr)
-progress true Live progress line on stderr (disable with -progress=false)
-simulate false Simulation mode: no real DNS queries
-hit-rate <n> 15 Simulated resolution rate, percent (1-100)
-tui false Launch the interactive Terminal UI (no other flags required)
-version -- Print version and exit
-retries <n> -- Deprecated: alias for -attempts, prints a warning



Usage

subenum -w <wordlist> [flags] <domain>

Basic scan:

./subenum -w wordlist.txt example.com

High-throughput with Cloudflare DNS, saving results:

./subenum -w wordlist.txt -t 300 -timeout 500 -dns-server 1.1.1.1:53 -o results.txt example.com

Resilient scan for flaky networks:

./subenum -w wordlist.txt -attempts 3 -timeout 2000 example.com

Pipe-friendly output (progress goes to stderr, only results on stdout):

./subenum -w wordlist.txt example.com | cut -d' ' -f2 | your-takeover-scanner

Force scan on wildcard domain:

./subenum -w wordlist.txt -force example.com

Simulation (zero network I/O):

./subenum -simulate -hit-rate 20 -w examples/sample_wordlist.txt example.com

Graceful shutdown: press Ctrl+C at any time. In-flight queries drain, partial results are flushed.

Interactive TUI (no arguments):

./subenum -tui
# or
make tui

Fill in the form, press ctrl+r to scan. Last-used values are saved to ~/.config/subenum/last.json and restored on next launch.

Key Action
tab / shift+tab / ↑↓ Navigate fields
space Toggle Simulate / Force
ctrl+r Start scan
ctrl+c Abort scan (in scan view) / quit (in form)
r New scan — returns to form with last values pre-filled
q Quit after scan completes



Project Anatomy
subenum/
├── .github/
│   ├── workflows/
│   │   ├── go.yml              # CI: build, test, lint, release
│   │   ├── codeql.yml          # Weekly CodeQL security analysis
│   │   └── pages.yml           # GitHub Pages deployment
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md       # Structured bug report form
│   │   └── feature_request.md  # Feature proposal template
│   ├── dependabot.yml          # Automated dependency updates
│   └── PULL_REQUEST_TEMPLATE.md
├── data/
│   └── wordlist.txt            # Default wordlist for Docker/Make
├── docs/
│   ├── ARCHITECTURE.md         # Internals: worker pool, context, output
│   ├── CONTRIBUTING.md         # PR workflow, testing, ethical guidelines
│   ├── DEVELOPER_GUIDE.md      # Build, test, project structure
│   ├── DOCUMENTATION_STRUCTURE.md
│   ├── docker.md               # Container setup and volume mounting
│   ├── _config.yml             # Jekyll config for GitHub Pages
│   └── index.md                # GitHub Pages landing page
├── examples/
│   ├── sample_wordlist.txt     # 50-entry starter wordlist
│   ├── advanced_usage.md       # Scripting and integration patterns
│   ├── demo.sh                 # Quick demo script
│   └── multi_domain_scan.sh    # Batch scanning example
├── internal/
│   ├── dns/
│   │   ├── resolver.go         # ResolveDomain, ResolveDomainWithRetry, CheckWildcard
│   │   ├── resolver_test.go    # DNS resolution and wildcard detection tests
│   │   ├── simulate.go         # SimulateResolution (synthetic DNS)
│   │   └── simulate_test.go    # Simulation logic tests
│   ├── output/
│   │   ├── writer.go           # Thread-safe output (results→stdout, rest→stderr)
│   │   └── writer_test.go      # Output writer tests
│   └── wordlist/
│       ├── reader.go           # LoadWordlist (dedup + sanitize)
│       └── reader_test.go      # Wordlist loading and dedup tests
├── tools/
│   └── wordlist-gen.go         # Custom wordlist generator utility
├── main.go                     # CLI entry point: flag parsing, wiring
├── main_test.go                # CLI-level tests: validation, flag logic
├── go.mod                      # Go module (zero external dependencies)
├── Dockerfile                  # Multi-stage Alpine build
├── docker-compose.yml          # Compose orchestration
├── Makefile                    # Build, test, lint, simulate, Docker targets
├── .gitattributes              # Line-ending normalization rules
├── .golangci.yml               # Linter configuration (golangci-lint v2)
├── CHANGELOG.md                # Versioned release history
├── SECURITY.md                 # Vulnerability disclosure policy
└── LICENSE                     # GNU General Public License v3.0



Tech Stack

Core Engine Go 1.22 · net.Resolver · context · sync/atomic
Concurrency goroutines · channels · sync.WaitGroup · sync.Mutex
Infrastructure Docker · Alpine · Make · docker-compose
CI/CD GitHub Actions · CodeQL · Dependabot · golangci-lint
Quality go test -race · golangci-lint v2 · gosec · govet



Development

See CONTRIBUTING.md for the pull request workflow and ethical guidelines. See DEVELOPER_GUIDE.md for build instructions, testing, and project structure.




Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
dns
tui
Package tui provides a Bubble Tea terminal UI for subenum.
Package tui provides a Bubble Tea terminal UI for subenum.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL