|
1 | 1 | # subenum |
2 | 2 |
|
| 3 | +[](https://github.com/TMHSDigital/subenum/actions) |
3 | 4 | [](https://goreportcard.com/report/github.com/TMHSDigital/subenum) |
4 | | -[](https://github.com/TMHSDigital/subenum/actions) |
5 | | -[](https://github.com/TMHSDigital/subenum/releases) |
6 | | -[](https://github.com/TMHSDigital/subenum/blob/main/LICENSE) |
7 | | -[](https://github.com/TMHSDigital/subenum/blob/main/docs/docker.md) |
| 5 | +[](https://github.com/TMHSDigital/subenum/releases) |
| 6 | +[](LICENSE) |
| 7 | +[](docs/docker.md) |
| 8 | +[](https://github.com/TMHSDigital/subenum/actions/workflows/codeql.yml) |
8 | 9 |
|
9 | | -A Go-based CLI tool for subdomain enumeration. |
| 10 | +**Fast, concurrent subdomain enumeration via DNS resolution. Written in Go.** |
10 | 11 |
|
11 | | -## Description |
| 12 | +Built for security professionals and students conducting authorized reconnaissance. Uses a configurable worker pool to fire hundreds of DNS queries in parallel, with graceful shutdown, retry logic, and safe simulation mode built in. |
12 | 13 |
|
13 | | -`subenum` takes a domain and a wordlist as input. It then attempts to resolve `word.domain` for each word in the wordlist using DNS lookups. Valid subdomains that return an A or CNAME record are printed to the console. |
| 14 | +> **For authorized use only.** Only scan domains you own or have explicit written permission to test. |
14 | 15 |
|
15 | | -## Cybersecurity Context & Importance |
16 | | - |
17 | | -Subdomain enumeration is a crucial first step in the reconnaissance phase of a penetration test or security assessment. Its primary goal is to map out the target organization's digital footprint. Here's why it's important: |
18 | | - |
19 | | -* **Expanding Attack Surface Discovery**: Organizations often have numerous subdomains for different services, applications (e.g., `blog.example.com`, `api.example.com`), or development/staging environments (e.g., `dev.example.com`, `staging.app.example.com`). Many of these might not be publicly linked or widely known. Each discovered subdomain is a potential entry point for an attacker. |
20 | | -* **Identifying Forgotten or Unmaintained Assets**: Companies might have old subdomains pointing to outdated, unpatched applications or servers. These "forgotten" assets can be highly vulnerable and are prime targets. |
21 | | -* **Finding Hidden or Test Environments**: Subdomains like `test.example.com` or `uat.example.com` may have weaker security configurations, use default credentials, or expose sensitive debugging information that could be leveraged. |
22 | | -* **Discovering Different Technologies/Services**: Different subdomains can host applications built with various technologies. Knowing this allows security professionals to tailor vulnerability scanning and exploitation techniques to specific technology stacks. |
23 | | -* **Bypassing Security Controls**: Security measures like Web Application Firewalls (WAFs) might be rigorously applied to the main domain but not consistently across all subdomains. A vulnerable service on an "unprotected" subdomain could offer a path into the internal network. |
24 | | -* **Targeting Specific Services**: Subdomains often give clues about the services they host (e.g., `mail.example.com`, `vpn.example.com`, `ftp.example.com`). This allows for focused attacks against known vulnerabilities in those types of services. |
25 | | -* **Information Gathering for Further Attacks**: The structure and naming conventions of subdomains can provide insights into the organization's internal structure, naming schemes, or technologies in use, which can be valuable for social engineering or other targeted attacks. |
26 | | - |
27 | | -By discovering more subdomains, security testers can identify a broader range of potential vulnerabilities and provide a more comprehensive assessment of an organization's security posture. |
| 16 | +--- |
28 | 17 |
|
29 | | -## Legal & Ethical Usage Disclaimer |
| 18 | +## How It Works |
30 | 19 |
|
31 | | -**IMPORTANT**: This tool is provided for **educational and legitimate security testing purposes only**. |
| 20 | +``` |
| 21 | +wordlist.txt ──► worker pool (N goroutines) ──► DNS resolver ──► stdout / file |
| 22 | + │ │ |
| 23 | + ctx cancellation timeout + retries |
| 24 | + (SIGINT/SIGTERM) per query |
| 25 | +``` |
32 | 26 |
|
33 | | -* **Authorization Required**: Only use this tool on systems and domains for which you have explicit permission to test. |
34 | | -* **Prohibited Uses**: This software must NOT be used for: |
35 | | - * Unauthorized access to systems or networks |
36 | | - * Data theft or exfiltration |
37 | | - * Disruption of services (DoS/DDoS) |
38 | | - * Any activity prohibited by applicable local, national, or international laws |
39 | | -* **Responsible Use**: Always follow responsible disclosure practices if you discover vulnerabilities. |
40 | | -* **Legal Compliance**: Users are solely responsible for ensuring their use of this tool complies with all relevant laws, regulations, and organizational policies. |
| 27 | +Each wordlist entry is combined with the target domain (`api` + `example.com` → `api.example.com`) and resolved concurrently. Only entries that return a DNS record are reported. |
41 | 28 |
|
42 | | -The developers and contributors of `subenum` explicitly prohibit any use of this software for malicious purposes or to cause harm. Violation of these terms may subject you to legal action. |
| 29 | +--- |
43 | 30 |
|
44 | 31 | ## Installation |
45 | 32 |
|
46 | | -### From Source |
| 33 | +**From source** (requires Go 1.22+): |
47 | 34 |
|
48 | 35 | ```bash |
49 | | -# Clone the repository |
50 | 36 | git clone https://github.com/TMHSDigital/subenum.git |
51 | 37 | cd subenum |
52 | | - |
53 | | -# Build the tool |
54 | | -go build -buildvcs=false |
| 38 | +go build -buildvcs=false -o subenum |
55 | 39 | ``` |
56 | 40 |
|
57 | | -### Using Docker |
| 41 | +**From a release binary:** |
58 | 42 |
|
59 | | -You can also run `subenum` using Docker: |
| 43 | +Download a pre-built binary for your platform from the [Releases](https://github.com/TMHSDigital/subenum/releases) page. |
| 44 | + |
| 45 | +**Docker:** |
60 | 46 |
|
61 | 47 | ```bash |
62 | | -# Build the Docker image |
63 | 48 | docker build -t subenum . |
64 | | - |
65 | | -# Run with Docker |
66 | 49 | docker run --rm -v $(pwd)/data:/data subenum -w /data/wordlist.txt example.com |
67 | 50 | ``` |
68 | 51 |
|
69 | | -### Using Make |
70 | | - |
71 | | -The project includes a Makefile for common tasks: |
| 52 | +**Make:** |
72 | 53 |
|
73 | 54 | ```bash |
74 | | -# Show available commands |
75 | | -make help |
76 | | - |
77 | | -# Build the binary |
78 | | -make build |
79 | | - |
80 | | -# Run with default settings |
81 | | -make run |
| 55 | +make build # compile |
| 56 | +make run # build and run with defaults |
| 57 | +make help # list all targets |
82 | 58 | ``` |
83 | 59 |
|
| 60 | +--- |
| 61 | + |
84 | 62 | ## Usage |
85 | 63 |
|
86 | | -```bash |
87 | | -go build |
88 | | -./subenum -w <wordlist_file> <domain> |
89 | 64 | ``` |
| 65 | +subenum -w <wordlist> [flags] <domain> |
| 66 | +``` |
| 67 | + |
| 68 | +### Flags |
| 69 | + |
| 70 | +| Flag | Default | Description | |
| 71 | +|------|---------|-------------| |
| 72 | +| `-w <file>` | — | Wordlist file, one prefix per line **(required)** | |
| 73 | +| `-t <n>` | `100` | Number of concurrent worker goroutines | |
| 74 | +| `-timeout <ms>` | `1000` | Per-query DNS timeout in milliseconds | |
| 75 | +| `-dns-server <ip:port>` | `8.8.8.8:53` | DNS server (IP and port validated on startup) | |
| 76 | +| `-retries <n>` | `1` | Retry attempts per subdomain on failure | |
| 77 | +| `-o <file>` | — | Write results to file in addition to stdout | |
| 78 | +| `-v` | `false` | Verbose output — IPs, timings, per-query status | |
| 79 | +| `-progress` | `true` | Live progress line (disable with `-progress=false`) | |
| 80 | +| `-simulate` | `false` | Simulation mode — no real DNS queries | |
| 81 | +| `-hit-rate <n>` | `15` | Simulated resolution rate, percent (1–100) | |
| 82 | +| `-version` | — | Print version and exit | |
| 83 | + |
| 84 | +--- |
90 | 85 |
|
91 | | -### Flags: |
| 86 | +## Examples |
92 | 87 |
|
93 | | -- `-w <file>`: Path to the wordlist file (required). |
94 | | -- `-t <number>`: Number of concurrent workers (default: 100). |
95 | | -- `-timeout <ms>`: DNS lookup timeout in milliseconds (default: 1000ms). |
96 | | -- `-dns-server <ip:port>`: DNS server to use for lookups (default: 8.8.8.8:53). |
97 | | -- `-v`: Enable verbose output with detailed information about each lookup. |
98 | | -- `-progress`: Show scan progress (default: true, use `-progress=false` to disable). |
99 | | -- `-o <file>`: Write discovered subdomains to file (in addition to stdout). |
100 | | -- `-retries <number>`: Number of DNS retry attempts per subdomain (default: 1). |
101 | | -- `-simulate`: Run in simulation mode — no actual DNS queries are made. |
102 | | -- `-hit-rate <number>`: In simulation mode, percentage of subdomains that "resolve" (default: 15, range: 1-100). |
103 | | -- `-version`: Show version information and exit. |
| 88 | +**Basic scan:** |
104 | 89 |
|
105 | | -### Output: |
| 90 | +```bash |
| 91 | +./subenum -w wordlist.txt example.com |
| 92 | +``` |
106 | 93 |
|
107 | | -Without verbose mode, the tool only outputs successfully resolved subdomains: |
108 | 94 | ``` |
109 | | -Found: blog.example.com |
| 95 | +Found: api.example.com |
110 | 96 | Found: mail.example.com |
| 97 | +Found: www.example.com |
| 98 | +``` |
| 99 | + |
| 100 | +**High-throughput scan with Cloudflare DNS, saving results:** |
| 101 | + |
| 102 | +```bash |
| 103 | +./subenum -w wordlist.txt -t 300 -timeout 500 -dns-server 1.1.1.1:53 -o results.txt example.com |
| 104 | +``` |
| 105 | + |
| 106 | +**Verbose scan — shows IPs, timings, and a final summary:** |
| 107 | + |
| 108 | +```bash |
| 109 | +./subenum -w wordlist.txt -v example.com |
111 | 110 | ``` |
112 | 111 |
|
113 | | -With verbose mode (`-v`), you'll see additional information: |
114 | 112 | ``` |
115 | 113 | Starting subenum v0.3.0 |
| 114 | +Mode: LIVE DNS RESOLUTION |
116 | 115 | Target domain: example.com |
117 | 116 | Wordlist: wordlist.txt |
118 | 117 | Concurrency: 100 workers |
119 | 118 | Timeout: 1000 ms |
120 | 119 | Retries: 1 |
121 | 120 | DNS Server: 8.8.8.8:53 |
122 | 121 | --- |
123 | | -Total wordlist entries: 50 |
124 | | -Resolved: www.example.com (IP: 93.184.216.34) in 52.789ms |
125 | | -Found: www.example.com |
126 | | -Failed to resolve: nonexistent.example.com (Error: lookup nonexistent.example.com: no such host) in 81.234ms |
127 | | -Progress: 100.0% (50/50) | Found: 3 |
| 122 | +Total wordlist entries: 1842 |
| 123 | +Resolved: api.example.com (IP: 93.184.216.34) in 28ms |
| 124 | +Found: api.example.com |
| 125 | +Resolved: mail.example.com (IP: 93.184.216.35) in 31ms |
| 126 | +Found: mail.example.com |
| 127 | +Progress: 100.0% (1842/1842) | Found: 7 |
128 | 128 |
|
129 | 129 | Scan completed for example.com |
130 | | -Processed 50 subdomain prefixes |
131 | | -Found 3 valid subdomains |
| 130 | +Processed 1842 subdomain prefixes |
| 131 | +Found 7 subdomains |
132 | 132 | ``` |
133 | 133 |
|
134 | | -## Example |
| 134 | +**Resilient scan for flaky networks:** |
135 | 135 |
|
136 | | -Assuming you have a wordlist file named `words.txt` with the following content: |
137 | | - |
138 | | -``` |
139 | | -blog |
140 | | -mail |
141 | | -www |
142 | | -shop |
| 136 | +```bash |
| 137 | +./subenum -w wordlist.txt -retries 3 -timeout 2000 example.com |
143 | 138 | ``` |
144 | 139 |
|
145 | | -And you want to enumerate subdomains for `example.com`: |
| 140 | +**Clean output for piping into other tools:** |
146 | 141 |
|
147 | 142 | ```bash |
148 | | -./subenum -w words.txt example.com |
| 143 | +./subenum -w wordlist.txt -progress=false example.com \ |
| 144 | + | cut -d' ' -f2 \ |
| 145 | + | your-takeover-scanner |
149 | 146 | ``` |
150 | 147 |
|
151 | | -Potential output: |
| 148 | +**Stop mid-scan cleanly** — press `Ctrl+C`. In-flight queries drain, partial results are printed, and the output file is flushed. |
152 | 149 |
|
153 | | -``` |
154 | | -Found: blog.example.com |
155 | | -Found: mail.example.com |
156 | | -Found: www.example.com |
157 | | -``` |
| 150 | +--- |
158 | 151 |
|
159 | | -### Examples with Additional Options |
| 152 | +## Simulation Mode |
160 | 153 |
|
161 | | -Using a custom DNS server: |
162 | | -```bash |
163 | | -./subenum -w words.txt -dns-server 1.1.1.1:53 example.com |
164 | | -``` |
| 154 | +Run without making any real DNS queries. Useful for demonstrations, CI pipelines, and feature development. |
165 | 155 |
|
166 | | -Enabling verbose output while using higher concurrency and longer timeout: |
167 | 156 | ```bash |
168 | | -./subenum -w words.txt -v -t 200 -timeout 2000 example.com |
| 157 | +./subenum -simulate -hit-rate 20 -w examples/sample_wordlist.txt example.com |
169 | 158 | ``` |
170 | 159 |
|
171 | | -Disabling progress reporting (useful for scripting): |
172 | | -```bash |
173 | | -./subenum -w words.txt -progress=false example.com |
174 | 160 | ``` |
| 161 | +╔════════════════════════════════════════════════════════════════════╗ |
| 162 | +║ SIMULATION MODE ACTIVE - NO ACTUAL DNS QUERIES WILL BE PERFORMED ║ |
| 163 | +║ Results are artificially generated for educational purposes only ║ |
| 164 | +╚════════════════════════════════════════════════════════════════════╝ |
175 | 165 |
|
176 | | -Saving results to a file: |
177 | | -```bash |
178 | | -./subenum -w words.txt -o results.txt example.com |
| 166 | +Found (SIMULATED): api.example.com |
| 167 | +Found (SIMULATED): dev.example.com |
| 168 | +Found (SIMULATED): staging.example.com |
179 | 169 | ``` |
180 | 170 |
|
181 | | -Using retries for unreliable networks: |
182 | | -```bash |
183 | | -./subenum -w words.txt -retries 3 example.com |
184 | | -``` |
| 171 | +Common subdomains (`www`, `api`, `mail`, `dev`, `staging`, etc.) resolve at a fixed 90% rate. All other entries use the `-hit-rate` percentage. |
185 | 172 |
|
186 | | -### Simulation Mode for Safe Testing |
| 173 | +--- |
187 | 174 |
|
188 | | -The tool includes a simulation mode for safely testing functionality without performing actual DNS queries: |
| 175 | +## Why Subdomain Enumeration |
189 | 176 |
|
190 | | -```bash |
191 | | -# Safe simulation mode (no actual DNS queries) |
192 | | -./subenum -simulate -w examples/sample_wordlist.txt example.com |
193 | | -``` |
194 | | - |
195 | | -In simulation mode: |
196 | | -- **No actual DNS queries** are performed (completely network-safe) |
197 | | -- Results are randomly generated based on common patterns |
198 | | -- All output is clearly marked as simulated |
199 | | -- You can adjust the "hit rate" (percentage of domains that resolve): |
200 | | - ```bash |
201 | | - # Simulate with 25% of domains resolving |
202 | | - ./subenum -simulate -hit-rate 25 -w examples/sample_wordlist.txt example.com |
203 | | - ``` |
204 | | - |
205 | | -This mode is perfect for: |
206 | | -- Educational demonstrations |
207 | | -- Testing the tool functionality |
208 | | -- Understanding the output format |
209 | | -- Developing additional features |
| 177 | +Subdomain enumeration is a standard first step in authorized penetration testing and security assessments. Discovered subdomains can surface: |
| 178 | + |
| 179 | +- Forgotten or unmaintained services running outdated software |
| 180 | +- Development and staging environments with weaker security controls |
| 181 | +- Infrastructure not covered by WAFs or other perimeter defenses |
| 182 | +- Services leaking internal naming conventions and technology choices |
| 183 | + |
| 184 | +This tool exists to help security professionals map that attack surface efficiently — on domains they are authorized to test. |
| 185 | + |
| 186 | +--- |
| 187 | + |
| 188 | +## Documentation |
| 189 | + |
| 190 | +| Document | Description | |
| 191 | +|----------|-------------| |
| 192 | +| [Architecture](docs/ARCHITECTURE.md) | Internals: worker pool, context propagation, output pipeline | |
| 193 | +| [Developer Guide](docs/DEVELOPER_GUIDE.md) | Building, testing, project structure, contribution workflow | |
| 194 | +| [Contributing](docs/CONTRIBUTING.md) | How to report bugs, suggest features, and submit PRs | |
| 195 | +| [Docker Usage](docs/docker.md) | Container setup, volume mounting, simulation in Docker | |
| 196 | +| [Advanced Usage](examples/advanced_usage.md) | Scripting, integration, combined flag examples | |
| 197 | +| [Changelog](logs/CHANGELOG.md) | Release history | |
| 198 | + |
| 199 | +--- |
| 200 | + |
| 201 | +## Legal |
| 202 | + |
| 203 | +This software is provided for **educational and authorized security testing purposes only**. |
| 204 | + |
| 205 | +- You must have explicit written permission to scan any domain you do not own. |
| 206 | +- Do not use this tool for unauthorized access, data collection, or disruption of services. |
| 207 | +- Users are solely responsible for compliance with all applicable laws. |
| 208 | + |
| 209 | +The developers explicitly prohibit malicious use. See [LICENSE](LICENSE) for full terms. |
| 210 | + |
| 211 | +--- |
210 | 212 |
|
211 | 213 | ## Contributing |
212 | 214 |
|
213 | | -See [CONTRIBUTING.md](docs/CONTRIBUTING.md) for details on how to contribute to this project. |
| 215 | +Pull requests are welcome. See [CONTRIBUTING.md](docs/CONTRIBUTING.md) for the workflow, testing requirements, and ethical guidelines. |
0 commit comments