Finsa-SC/subdomain-scanner

GitHub: Finsa-SC/subdomain-scanner

一款集子域名枚举、存活验证、蜜罐检测和页面截图于一体的终端交互式侦察工具,帮助安全人员在资产收集阶段快速筛选出高价值目标。

Stars: 3 | Forks: 0

# subdomain-validator
![Python](https://img.shields.io/badge/Python-3.10+-blue?style=flat-square&logo=python&logoColor=white) ![uv](https://img.shields.io/badge/env-uv-purple?style=flat-square) ![License](https://img.shields.io/badge/License-MIT-green?style=flat-square) ![Security](https://img.shields.io/badge/Use-Ethical%20Only-red?style=flat-square) ![Status](https://img.shields.io/badge/Status-Active-brightgreen?style=flat-square) **一款具备终端用户界面 (TUI)、蜜罐检测和实时页面截图功能的子域名枚举与验证工具。**
## ✨ 功能特性 **发现** - 多源子域名枚举 — HackerTarget、crt.sh、RapidDNS、AlienVault OTX - 来源选择 — 指定特定来源 (`-s`) 或一次性运行所有来源 (`--all`) - 灵活输入 — 支持域名 (`-d`)、文件 (`-dL`) 或标准输入/管道 - 通配符 DNS 基线检测以过滤误报 (`-w`) **验证** - 双协议 HTTP/HTTPS 验证,包含 IP 解析、服务器响应头和延迟测量 - 自定义 DNS 解析器 — Cloudflare、Google、Quad9、OpenDNS 或自定义 IP (`--dns`) - 按最小/最大字节数进行响应大小过滤 (`--min-size`、`--max-size`) - 从响应头进行技术检测 (Nginx、Apache、PHP、WordPress、Cloudflare 等) **TUI (终端用户界面)** - 由 [Textual](https://github.com/Textualize/textual) 驱动的全交互式 TUI - 实时显示扫描结果的动态表格 — 子域名、IP、服务器、HTTP/HTTPS 状态 - 侧边详情面板,提供每个子域名的 HTTP、HTTPS、技术栈和蜜罐检测详细信息 - 包含完整响应头、Cookie 和发现项的全屏详情视图 - 支持结构化查询语法的过滤栏 — `status:200`、`server:nginx`、`honeypot:true`、`NOT status:404` 等 - 键盘驱动导航 **🍯 蜜罐分析器** - 多信号指纹识别引擎,用于检测蜜罐、金丝雀陷阱和虚假服务 - 检查的信号:服务器签名、正文哈希、字面蜜罐响应头、可疑的响应头顺序、相同的 HTTP/HTTPS 正文、默认页面标题、诱饵子域名名称 - 采用 Noisy-OR 概率模型,具有分层信号权重(严重 / 强 / 弱) - 置信度标签:Confirmed (已确认) / Likely (极可能) / Probable (可能) / Possible (有可能) / Unlikely (不太可能) **📸 截图捕获** 在全屏视图下按 S 键,使用 Playwright (Chromium 无头渲染) 捕获当前的实时页面。 - 截图保存至 results/screenshots/.png - 仅对有效目标执行 (HTTP 200,大小 > 100 字节,非通用标题) - 使用 rich-pixels 在 TUI 内部进行行内渲染预览 Linux: xdg-open macOS: open Windows: os.startfile **导出** - 将 IP 保存为纯文本列表 (`-o`) - 保存包含元数据、摘要和分组发现项的结构化 JSON (`-oJ`) - 在所有保存的输出中自动过滤 Cloudflare 和 CDN IP - JSON 根据响应指纹哈希进行去重 - 使用 `--purge` 清除结果目录 ## 📋 环境要求 - Python 3.10+ - [uv](https://github.com/astral-sh/uv) - Chromium (首次截图时由 Playwright 自动安装) ## 🚀 快速开始 ``` # Clone git clone --depth 1 https://github.com/Finsa-SC/subdomain-validator.git cd subdomain-validator # 创建 virtual environment uv venv --python 3.10 source .venv/bin/activate # Linux / macOS .venv\Scripts\activate # Windows # 安装 dependencies uv sync # 安装 Playwright 浏览器(截图所需) playwright install chromium # (可选)配置默认项 cp .env.example .env ``` ## 📖 用法 ``` python app/main.py (-d DOMAIN | -dL FILE) [options] ``` 管道/标准输入支持: ``` cat hosts.txt | python app/main.py ``` ## 🚩 参数标志 ### 输入 | 标志 | 描述 | |------|-------------| | `-d`, `--domain` | 用于枚举子域名的目标域名 | | `-dL`, `--domain-list` | 包含待直接验证子域名的文件路径 | | `-s`, `--source` | 选择单个来源:`hackertarget`、`crtsh`、`rapiddns`、`alienvault` | | `--all` | 使用所有可用的发现来源并合并结果 | ### 配置 | 标志 | 描述 | |------|-------------| | `--timeout` | 请求超时时间(秒)(默认:3.0) | | `--thread` | 并发线程数(默认:5) | | `--delay` | 请求之间的延迟时间(秒)(默认:0.0) | | `--dns` | DNS 解析器:`cloudflare`、`google`、`quad9`、`opendns` 或原始 IP | | `--min-size` | 跳过小于 N 字节的响应 | | `--max-size` | 跳过大于 N 字节的响应 | ### 输出与导出 | 标志 | 描述 | |------|-------------| | `-o`, `--output` | 将存活 IP 保存为纯文本 | | `-oJ`, `--output-json` | 将完整的结构化结果保存为 JSON | | `-w`, `--no-wildcard` | 跳过匹配通配符 DNS 基线的子域名 | | `--honeypot` | 启用蜜罐分析器(在 TUI 中无论是否设置始终运行) | | `--purge` | 删除整个 `results/` 目录 | | `-V`, `--version` | 显示版本 | ## ⌨️ TUI 快捷键 | 按键 | 动作 | |-----|--------| | `↑` / `↓` | 在表格中导航 | | `Enter` / `D` | 打开侧边详情面板 | | `F` | 切换全屏详情视图 | | `S` | 截取实时页面截图(仅在全屏模式下) | | `/` | 聚焦过滤栏 | | `Escape` | 关闭详情 / 取消过滤栏聚焦 | | `C` | 复制子域名到剪贴板 | | `B` | 在浏览器中打开子域名 | | `E` | 导出选中项 | | `Shift+E` | 导出所有已过滤的结果 | | `F1` | 显示帮助 | | `Q` | 退出 | ## 🔍 过滤查询语法 过滤栏接受结构化查询。可以组合使用多个过滤器。 | 查询 | 描述 | |-------|-------------| | `status:200` | 匹配特定的 HTTP 状态码 | | `status:forbidden` | 匹配 401/402/403 | | `status:redirect` | 匹配 301/302/307/308 | | `server:nginx` | 按服务器响应头的值匹配 | | `tech:cloudflare` | 按检测到的技术匹配 | | `title:admin` | 按页面标题匹配 | | `honeypot:true` | 仅显示疑似蜜罐 | | `honeypot:confirmed` | 按置信度标签匹配 | | `wildcard:true` | 显示/隐藏通配符匹配项 | | `ip:1.2.3.*` | 按 IP 模式匹配(支持通配符) | | `ip:proxy` | 仅显示代理/CDN IP | | `size:500-5000` | 按响应大小范围过滤 | | `latency:100-500` | 按延迟范围(毫秒)过滤 | | `subdomain:*.dev.*` | 对子域名进行 Glob 模式匹配 | | `NOT status:404` | 对任何过滤器取反 | ## 💡 示例 ``` # 使用 TUI 进行基本扫描 python app/main.py -d example.com # 使用所有发现来源 python app/main.py -d example.com --all # 使用特定来源 python app/main.py -d example.com -s crtsh # 自定义 DNS + 跳过 wildcards + 保存 JSON python app/main.py -d example.com --dns cloudflare -w -oJ # 从 subdomain 文件扫描 python app/main.py -dL hosts.txt --thread 20 --timeout 5 # 通过管道从另一个 tool 传入 subfinder -d example.com | python app/main.py # 按大小过滤(最小 50 字节,最大 1MB) python app/main.py -d example.com --min-size 50 --max-size 1000000 # 带 jitter 延迟的慢速扫描 python app/main.py -d example.com --delay 0.5 --thread 3 # 清除 results 文件夹 python app/main.py --purge ``` ## 🍯 蜜罐分析器 蜜罐引擎在 TUI 中对每个子域名自动运行。信号被划分为不同的层级,并使用 **Noisy-OR** 概率模型进行综合计算。 | 层级 | 信号 | |------|---------| | **严重** | 已知的蜜罐服务器签名,与已知蜜罐匹配的正文哈希,字面蜜罐响应头 (`x-honeypot`、`x-canary` 等) | | **强** | 过时/刻意暴露的服务器版本,可疑的响应头顺序,HTTP 和 HTTPS 上正文完全相同(无重定向),默认服务器页面标题 | | **弱** | 高价值诱饵子域名名称 (`admin`、`vpn`、`db`、`shell` 等),返回 HTTP 200 但无页面标题 | | 分数 | 标签 | |-------|-------| | ≥ 90% | Confirmed (已确认) | | ≥ 75% | Likely (极可能) | | ≥ 50% | Probable (可能) | | ≥ 25% | Possible (有可能) | | < 25% | Unlikely (不太可能) | ## 🔍 发现来源 | 来源 | 键名 | 备注 | |--------|-----|-------| | HackerTarget | `hackertarget` | 默认。免费,无需 API 密钥。 | | crt.sh | `crtsh` | 证书透明度日志。无需密钥。 | | RapidDNS | `rapiddns` | 抓取 rapiddns.io 数据。 | | AlienVault OTX | `alienvault` | 被动 DNS。需要 API 密钥。 | ## 📸 截图 截图是通过在无头 Chromium 浏览器中(通过 Playwright)打开真实 URL,然后保存顶部视口来截取的。 保存至 `results/screenshots/.png`。预览也会使用 `rich-pixels` 在 TUI 全屏视图中进行行内渲染。 截图条件(必须全部满足): - HTTP 或 HTTPS 状态 = 200 - 响应大小 > 100 字节 - 页面标题不是通用默认页面(如 nginx 默认页面、“It works!” 等) ## 💾 输出文件 全部保存至 `results/`。CDN 和代理 IP(如 Cloudflare、Akamai、Fastly 等)会自动从输出中过滤掉。 | 文件 | 内容 | |------|----------| | `results/_healthy_ip.txt` | 返回 HTTP 200 的 IP | | `results/_problem_ip.txt` | 返回非 200 响应的 IP | | `results/.json` | 包含元数据、摘要和去重发现项的结构化 JSON | | `results/screenshots/.png` | 存活主机的整页截图 | ### JSON 结构 ``` { "metadata": { "timestamp": "2026-01-01 12:00:00", "domain": "example.com", "thread_used": 10 }, "summary": { "total_found": 42, "unique_active": 8, "honeypots": 2, "wildcard_ignored": 5, "others": 27 }, "findings": { "unique_active": { "": { "total": 3, "sample": { ... } } }, "honeypots": [ { ... } ], "wildcard_sample": [ { ... } ], "others": { ... } } } ``` 在 `unique_active` 和 `others` 中的发现项会根据 `status + server + body_hash` 生成的指纹哈希进行去重。每个条目包含一个 `total` 计数和一个代表性的 `sample`。 ## ⚙️ 环境变量 通过 `.env` 配置(从 `.env.example` 复制)。运行时 CLI 标志会覆盖这些变量。 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `TIMEOUT` | `3.0` | HTTP 请求超时时间(秒) | | `THREAD` | `5` | 并发线程数 | | `DELAY` | `0.0` | 请求之间的延迟 | | `DEBUG` | `False` | 当为 `True` 时,绕过 CLI 并直接针对 `hosts.txt` 运行 | ## 🏗️ 项目结构 ``` subdomain-validator/ ├── app/ │ ├── main.py # Entry point — argparse CLI, pipe support, --purge │ ├── analysis/ │ │ └── honeypot.py # HoneypotAnalyzer — Noisy-OR fingerprinting engine │ ├── core/ │ │ ├── request.py # HTTP/HTTPS requests via curl_cffi with stealth headers │ │ ├── scanner.py # ThreadPoolExecutor orchestration, wildcard baseline │ │ ├── stealth.py # Randomized User-Agent and browser impersonation │ │ └── validate.py # Per-subdomain validation, tech detection, data building │ ├── models/ │ │ ├── scan_config.py # ScanConfig dataclass and global config accessor │ │ └── signatures.py # Honeypot signatures, PROXY_IPS, DNS providers, UA fallbacks │ ├── sources/ │ │ ├── handler.py # Source dispatcher │ │ ├── hackertarget.py │ │ ├── crtsh.py │ │ ├── rapiddns.py │ │ └── alienvault.py │ ├── tui/ │ │ ├── app.py # Textual App root │ │ ├── filter_parser.py # Structured filter query engine │ │ ├── styles.css # TUI theme (dark, cyan/gold palette) │ │ ├── screens/ │ │ │ ├── main_screen.py # Main layout — table + filter + detail panel │ │ │ ├── fullscreen.py # Fullscreen detail + S to screenshot │ │ │ └── help_screen.py # F1 help modal │ │ └── widgets/ │ │ ├── subdomain_table.py │ │ ├── detail_panel.py │ │ └── stats_bar.py │ └── utils/ │ ├── screenshotter.py # Playwright screenshot + rich-pixels TUI preview │ ├── writer.py # JSON/TXT export with CDN IP filtering │ └── logger.py # File logger to /tmp/subv.log ├── assets/ │ └── banner.txt ├── .env.example ├── Dockerfile └── pyproject.toml ``` ## 🐳 Docker ``` # Build docker build -t subvr . # Run docker run --rm subvr -d example.com --all ``` ## 📜 许可证 基于 [MIT 许可证](LICENSE) 分发。
**subdomain-validator** — 使用 Python 和多个 OSINT 来源,用 ❤️ 构建 🇮🇩 *由 [Finsa Kusuma Putra](https://github.com/Finsa-SC) 骄傲地在印度尼西亚制作* #### *"Dari Indonesia, untuk dunia."* *来自印度尼西亚,献给全世界。*
标签:DNS解析, HTTP/HTTPS验证, Python, Textual, TUI, 多源枚举, 子域名枚举, 子域名验证, 密码管理, 开源项目, 技术识别, 插件系统, 搜索引擎优化SEO, 无后门, 特征检测, 白帽工具, 系统安全, 终端用户界面, 网络安全, 网页截图, 蜜罐检测, 请求拦截, 逆向工具, 通配符检测, 隐私保护, 黑盒测试