t0kubetsu/subdomainenum

GitHub: t0kubetsu/subdomainenum

一款子域名枚举 CLI,整合被动与主动探测并输出彩色摘要与机器可读报告。

Stars: 0 | Forks: 0

# subdomainenum **subdomainenum** 通过被动工具(subfinder、amass、findomain、assetfinder — 这些工具内部还会查询 crt.sh 和其他 CT 日志)发现子域名, 可选地使用 dnsrecon 和 gobuster 暴力破解 DNS,使用 wfuzz 模糊测试虚拟主机,解析每个结果,并输出彩色摘要。 ![Python](https://img.shields.io/badge/python-%3E%3D3.11-blue) ![Tests](https://img.shields.io/badge/tests-182%20passing-brightgreen) ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen) ![License](https://img.shields.io/badge/license-GPLv3-lightgrey) ## 目录 - [Features](#features) - [Requirements](#requirements) - [Installation](#installation) - [External Tools](#external-tools) - [CLI Usage](#cli-usage) - [Python API](#python-api) - [Docker](#docker) - [Project Structure](#project-structure) - [Running Tests](#running-tests) - [Contributing](#contributing) ## 功能 | Source / Mode | Type | What it does | | ------------------ | ------- | ------------------------------------------------------------------------------------ | | **subfinder** | Passive | Runs `subfinder -d domain -silent` | | **amass** | Passive | Runs `amass enum -d domain -silent` | | **findomain** | Passive | Runs `findomain --target domain --quiet` | | **assetfinder** | Passive | Runs `assetfinder --subs-only domain` | | **dnsrecon** | Active | Runs all applicable types: `std,srv,axfr,crt,zonewalk,bing,yand` + `brt,snoop` | | **gobuster dns** | Active | Brute-forces DNS with a wordlist (`gobuster dns --domain domain -w wordlist`) | | **wfuzz** | Active | Fuzzes virtual hosts via the `Host` header against a target URL | | **DNS resolution** | — | All discovered FQDNs are resolved (A + AAAA) in parallel with a configurable timeout | Passive and active sources can be run independently or combined (`--mode all`). ## 要求 - Python ≥ 3.11 - [`dnspython`](https://www.dnspython.org/) ≥ 2.6 - [`rich`](https://github.com/Textualize/rich) ≥ 13.7 - [`typer`](https://typer.tiangolo.com/) ≥ 0.12 - [`psycopg2-binary`](https://pypi.org/project/psycopg2-binary/) ≥ 2.9 - [`cryptography`](https://cryptography.io/) ≥ 42 External tools are optional — absent tools are silently skipped. Run `subdomainenum info` to see which are available. ## 安装 **From source (recommended):** ``` git clone https://github.com/t0kubetsu/subdomainenum.git cd subdomainenum python -m venv .venv source .venv/bin/activate pip install -e ".[dev]" # installs the CLI + all dev/test dependencies ``` The `subdomainenum` command is then available in your shell. ## 外部工具 Run `subdomainenum info` to check which tools are detected on your `$PATH`: | Tool | Install | | ----------- | -------------------------------------------------------------------------- | | subfinder | `go install github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest` | | amass | `go install github.com/owasp-amass/amass/v4/...@latest` | | findomain | Download from https://github.com/Findomain/Findomain/releases | | assetfinder | `go install github.com/tomnomnom/assetfinder@latest` | | dnsrecon | `apt install dnsrecon` / `pip install dnsrecon` | | gobuster | `go install github.com/OJ/gobuster/v3@latest` | | wfuzz | `apt install wfuzz` / `pip install wfuzz` | ## CLI 使用 ### 被动枚举(默认) ``` # 查询 TLS SAN、subfinder、amass、findomain、assetfinder(assetfinder 包含 crt.sh + CT 日志) subdomainenum check example.com ``` ### 主动枚举(DNS 暴力破解 + 可选 vhost 模糊测试) ``` # 使用单词表进行 DNS 暴力破解 subdomainenum check example.com \ --mode active \ --wordlist /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt # 暴力破解 + vhost 模糊测试 subdomainenum check example.com \ --mode active \ --wordlist /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \ --url http://10.0.0.1 ``` ### 所有来源组合 ``` subdomainenum check example.com \ --mode all \ --wordlist /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \ --url http://10.0.0.1 ``` ### JSON 输出 ``` # 机器可读输出(标准输出) subdomainenum check example.com --json # 保存到文件 subdomainenum check example.com --json --output report.json ``` ### 调试日志 ``` # 将每个工具的原生输出保存到日志文件 subdomainenum check example.com --debug-log /tmp/debug.log # 也支持 --json subdomainenum check example.com --json --debug-log /tmp/debug.log ``` When `--debug-log` is specified, every line emitted by each tool is written to the given file as structured plain text (one section per source, with the command, all output lines, status, and any error). No debug output is sent to stderr — a brief `Debug log → ` confirmation appears at the end. ### DNS 超时 ``` # 调整每次查询的 DNS 解析超时(默认 5.0 秒) subdomainenum check example.com --timeout 10 ``` ### 工具可用性 ``` subdomainenum info ``` ### 版本 ``` subdomainenum --version ``` ## Python API ### 完整评估 ``` from subdomainenum.assessor import assess from subdomainenum.models import EnumMode from subdomainenum.reporter import print_report report = assess( "example.com", mode=EnumMode.PASSIVE, # passive | active | all wordlist=None, # required for active/all url=None, # optional: target URL for wfuzz timeout=5.0, # DNS resolution timeout per query progress_cb=print, # optional: called with status strings ) print_report(report) ``` ### 处理结果 ``` from subdomainenum.assessor import assess report = assess("example.com") print(report.domain) # "example.com" print(report.mode.value) # "passive" # 子域名 for sub in report.subdomains: print(sub.fqdn, sub.status.value, sub.ip_addresses, sub.sources) # 虚拟主机(wfuzz,仅在主动/全部模式下配合 --url 使用) for vhost in report.vhosts: print(vhost.vhost, vhost.status_code, vhost.content_length) # 每个来源的结果 for src in report.sources: print(src.name, len(src.subdomains), src.available, src.error) ``` `Status` values: `ALIVE`, `DEAD`, `TIMEOUT`, `ERROR`, `FOUND`, `NOT_FOUND`, `SKIPPED`. ### JSON 序列化 ``` import json from subdomainenum.assessor import assess from subdomainenum.reporter import to_dict report = assess("example.com") print(json.dumps(to_dict(report), indent=2)) ``` ## Docker A Docker image with all tools pre-installed and SecLists (DNS + Web-Content directories) bundled is available via the included `Dockerfile`. ``` # 构建镜像 docker compose build # 被动检查 docker compose run subdomainenum check example.com # 使用捆绑的 SecLists 单词表进行主动检查 docker compose run subdomainenum check example.com \ --mode active \ --wordlist /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt # 所有模式 + vhost 模糊测试,将报告保存到主机 ./reports/ docker compose run subdomainenum check example.com \ --mode all \ --wordlist /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \ --url http://10.0.0.1 \ --json \ --output /reports/example.json # 检查容器内的可用工具 docker compose run subdomainenum info ``` ## 项目结构 ``` subdomainenum/ ├── subdomainenum/ │ ├── __init__.py Package version │ ├── models.py Dataclasses: SubdomainResult, VhostResult, │ │ SourceResult, EnumReport + Status/EnumMode enums │ ├── dns_utils.py resolve_ips(), is_alive() — dnspython wrappers │ ├── constants.py ACTIVE_TOOLS registry, detect_tools(), get_install_hint() │ ├── assessor.py assess() — orchestrates passive + active sources │ ├── reporter.py Rich terminal output + to_dict() + save_report() │ ├── verdict.py build_verdict() — factual count summary │ ├── cli.py Typer CLI: check, info sub-commands │ └── tools/ │ ├── tool_runner.py subprocess wrapper used by all active tools │ ├── subfinder.py subfinder wrapper │ ├── amass.py amass enum wrapper (passive is amass's default) │ ├── findomain.py findomain wrapper │ ├── assetfinder.py assetfinder wrapper │ ├── dnsrecon.py dnsrecon -t brt wrapper │ ├── gobuster_dns.py gobuster dns wrapper │ └── wfuzz.py wfuzz vhost fuzzing wrapper ├── tests/ │ ├── __init__.py │ ├── test_models.py │ ├── test_verdict.py │ ├── test_constants.py │ ├── test_dns_utils.py │ ├── test_assessor.py │ ├── test_reporter.py │ ├── test_cli.py │ └── tools/ │ ├── test_tool_runner.py │ └── test_wrappers.py ├── Dockerfile ├── docker-compose.yml ├── pyproject.toml ├── requirements.txt ├── requirements-dev.txt └── README.md ``` ## 运行测试 ``` source .venv/bin/activate # 使用覆盖率运行所有测试(通过 pyproject.toml 自动配置) pytest # 快速运行(短回溯) pytest --tb=short -q # 运行单个模块 pytest tests/test_assessor.py -v # 运行单个测试类 pytest tests/test_cli.py::TestCheckCommand -v ``` The test suite has **182 tests** and achieves **100% coverage** across all modules. All DNS I/O (`dns.resolver.Resolver.resolve`), TLS sockets, and subprocess calls are mocked at the boundary — no test touches a real server or the internet. ## 贡献 1. Fork the repository and create a feature branch. 2. Add or update tests — the project targets 80%+ unit test coverage. 3. Run `pytest` and confirm all tests pass before opening a pull request. 4. Follow the existing docstring format (reStructuredText / docutils field lists). 5. Use [conventional commits](https://www.conventionalcommits.org/): `fix:`, `feat:`, `refactor:`, `test:`, `docs:`, `chore:` ## 许可 GPLv3 — see [LICENSE](LICENSE) for details。
标签:amass, assetfinder, CDN识别, dnsrecon, DNS查询, findomain, gobuster, GPLv3, Python, Python 3.9+, subfinder, Transformers, wfuzz, 主动发现, 二进制发布, 代码覆盖率, 单元测试, 反取证, 子域名枚举, 子域名解析, 安全监控, 安全评估, 开源工具, 无后门, 漏洞挖掘辅助, 系统安全, 网络安全, 虚拟主机模糊测试, 被动发现, 证书透明日志, 请求拦截, 逆向工具, 隐私保护, 颜色编码摘要