Skip to content

Latest commit

 

History

History
364 lines (262 loc) · 10.4 KB

File metadata and controls

364 lines (262 loc) · 10.4 KB


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 with all applicable laws and regulations.



Feature Matrix

Module Description
Worker Pool Spawn N goroutines for parallel DNS resolution with a configurable concurrency ceiling
DNS Engine Resolve subdomains against any DNS server with per-query timeouts and retry backoff
Wildcard Detection Double-probe check before scanning; aborts early unless -force is set
Graceful Shutdown Trap SIGINT/SIGTERM, drain in-flight workers, flush partial results
Input Validation RFC-compliant domain syntax and strict ip:port format enforcement
Wordlist Dedup Deduplicate wordlist entries in a single pass before scanning begins
Simulation Mode Generate synthetic DNS results at a configurable hit rate — zero network I/O
Output Pipeline Resolved domains to stdout (pipe-clean); progress and diagnostics to stderr
Interactive TUI Form-based config and live-scrolling results via -tui; session values persisted



System Architecture

flowchart LR
    subgraph Input
        A[Wordlist File] -->|"dedup + load"| B(Entry Slice)
        C[CLI Flags / TUI Form] --> 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)"]
        F -->|resolved| I[Output File]
        E -->|atomic counters| J["stderr (progress)"]
    end

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



Installation

Prerequisites: Go 1.22+ · Git · Make (optional) · Docker (optional)

Build from source
git clone https://github.com/TMHSDigital/subenum.git
cd subenum
go build -buildvcs=false -o subenum
Pre-built binaries

Download the appropriate binary for your platform from the Releases page.

Platforms: Linux (amd64, arm64) · macOS (amd64, arm64) · Windows (amd64)

SHA-256 checksums are provided alongside each binary.

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

Or with Compose:

docker compose run subenum
Make targets
make build          # compile binary
make test           # run test suite with race detector
make lint           # run golangci-lint
make simulate       # safe run — no DNS queries
make tui            # launch interactive TUI
make docker-build   # build Docker image
make help           # list all targets



Configuration

CLI flags

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 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 detail (stderr)
-progress true Live progress line on stderr
-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
-version Print version and exit
-retries <n> Deprecated — alias for -attempts, prints a warning

Note

Wildcard DNS is detected automatically before scanning begins. If the target resolves wildcard records, the tool exits with a warning — all subdomains would match, making results meaningless. Pass -force to override.

Caution

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




Usage

CLI

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

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 — only resolved subdomains on stdout

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

Force scan on a 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

Press Ctrl+C at any time to abort. In-flight queries drain and partial results are flushed before exit.


Interactive TUI

./subenum -tui

No flags required. Fill in the form and press ctrl+r to start scanning. Last-used values are saved to ~/.config/subenum/last.json and restored on next launch.


subenum TUI — Configure Scan


TUI keyboard reference
Key Action
tab / shift+tab / Navigate fields
space Toggle Simulate / Force
ctrl+r Start scan
ctrl+c Abort scan (scan view) / quit (form)
r New scan — restores last-used values
q Quit after scan completes



Tech Stack

Layer Components
Core Engine Go 1.22 · net.Resolver · context · sync/atomic
Concurrency goroutines · channels · sync.WaitGroup · sync.Mutex
TUI Bubble Tea · Bubbles (textinput, viewport, progress) · Lip Gloss
Infrastructure Docker · Alpine · Make · docker-compose
CI/CD GitHub Actions · CodeQL · Dependabot · golangci-lint v2
Quality go test -race · gosec · govet · staticcheck



Project structure
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
│   │   └── feature_request.md
│   ├── dependabot.yml
│   └── PULL_REQUEST_TEMPLATE.md
├── data/
│   └── wordlist.txt            # Default wordlist for Docker/Make
├── docs/
│   ├── assets/
│   │   └── tui-form.png        # TUI screenshot
│   ├── ARCHITECTURE.md
│   ├── CONTRIBUTING.md
│   ├── DEVELOPER_GUIDE.md
│   ├── docker.md
│   ├── _config.yml
│   └── index.md
├── examples/
│   ├── sample_wordlist.txt
│   ├── advanced_usage.md
│   ├── demo.sh
│   └── multi_domain_scan.sh
├── internal/
│   ├── dns/                    # ResolveDomain, CheckWildcard, SimulateResolution
│   ├── output/                 # Thread-safe Writer (stdout/stderr separation)
│   ├── scan/                   # Scan engine: Config, Event types, Run()
│   ├── tui/                    # Bubble Tea UI: form, scan view, session config
│   └── wordlist/               # LoadWordlist (dedup + sanitize)
├── tools/
│   └── wordlist-gen.go
├── main.go                     # CLI entry point
├── main_test.go
├── go.mod
├── Dockerfile
├── docker-compose.yml
├── Makefile
├── .golangci.yml               # golangci-lint v2 configuration
├── CHANGELOG.md
├── SECURITY.md
└── LICENSE                     # GNU General Public License v3.0



Development

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