Finsa-SC/subdomain-scanner
GitHub: Finsa-SC/subdomain-scanner
一款集子域名枚举、存活验证、蜜罐检测和页面截图于一体的终端交互式侦察工具,帮助安全人员在资产收集阶段快速筛选出高价值目标。
Stars: 3 | Forks: 0
# subdomain-validator
.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) 分发。





**一款具备终端用户界面 (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/
**subdomain-validator** — 使用 Python 和多个 OSINT 来源,用 ❤️ 构建
🇮🇩 *由 [Finsa Kusuma Putra](https://github.com/Finsa-SC) 骄傲地在印度尼西亚制作*
#### *"Dari Indonesia, untuk dunia."*
*来自印度尼西亚,献给全世界。*
标签:DNS解析, HTTP/HTTPS验证, Python, Textual, TUI, 多源枚举, 子域名枚举, 子域名验证, 密码管理, 开源项目, 技术识别, 插件系统, 搜索引擎优化SEO, 无后门, 特征检测, 白帽工具, 系统安全, 终端用户界面, 网络安全, 网页截图, 蜜罐检测, 请求拦截, 逆向工具, 通配符检测, 隐私保护, 黑盒测试