sazzadul007/Mr-cool-recon
GitHub: sazzadul007/Mr-cool-recon
一款整合 21 个 OSINT 数据源的高级子域名侦察框架,提供多源递归枚举、云资产指纹识别和差异对比能力。
Stars: 0 | Forks: 0
# Mr. Cool -- 高级被动 + 主动子域侦察框架,作者 sazzad007
从 **21 个免费/需密钥的来源**进行被动子域发现,智能多解析器
通配符过滤,**多源递归枚举**(crt.sh SAN 链 +
Wayback + GitHub + 可选的主动 JS/CSP 抓取),深度排列(级别
2-8),DNS 验证通过 **TTL / 使用的解析器 / 响应时间 /
DNSSEC** 进行丰富,反向 DNS 按 **ASN / 组织 / 云服务商** 分组,云
资产指纹识别(AWS、Azure、GCP、Cloudflare、Fastly、Akamai、Vercel、
Netlify、Heroku、GitHub Pages 等),**可配置、可解释的置信度
引擎**,**提供商健康摘要**,可查询的 **SQLite 情报
DB**,针对上一次运行的 **差异模式**,以及整洁的 `txt/ + json/ +
reports/` 输出布局 —— 包含恢复支持、缓存、各阶段指标
和自动发现的插件架构。
有关 pipeline 图表、完整的 JSON schema、插件 SDK
契约和置信度引擎公式,请参阅 `ARCHITECTURE.md`。
### 快速开始(安装)
```
git clone
cd # the folder containing run.py
pip install -r requirements.txt --break-system-packages
# (或者,使用 pip 可安装的形式:pip install -e . -- 这也会为你提供
# `passive-enum` 命令,请参阅下文的第 2/17 节)
cp .env.example .env # optional -- fill in any free API keys you have
python3 run.py -d example.com --profile balanced
```
完整细节(配置、密钥、CLI 工具来源、故障排除)在
下文的第 1 节中。
### v3.1 的新功能(本轮)
| 功能 | 状态 |
|---|---|
| 模块化插件系统 | 完成 |
| 自动插件发现(放入一个 `.py` 文件即可生效) | 完成 -- 之前已经实现,并已通过专用测试验证 |
| 提供商健康摘要(按来源的 成功/跳过/错误 + 主机数 + 重复项) | 完成 |
| 置信度引擎(累加式,可解释,可通过 `--config-file` 配置) | 完成 |
| 来源归属 | 完成 |
| 丰富的 JSON schema(`confidence_breakdown`、发现路径、ASN、云、丰富信息) | 完成 |
| TXT / CSV / HTML / Markdown 报告 | 完成 |
| SQLite 情报 DB(`intel.sqlite3`:运行历史、主机历史、搜索、跨运行重复项) | 完成 |
| 差异模式(`--diff ` 或 `--diff auto`) | 完成 |
| 恢复(分阶段 checkpoint + 优雅的 Ctrl+C 提示) | 完成,阶段中恢复不在范围内(参见 ARCHITECTURE.md) |
| 新增/修改模块的类型提示 | 已完成;对整个代码库进行严格的 `mypy` 检查仍在进行中,暂不作为强制的 CI 门控 |
| `black` / `ruff` / `mypy` / pre-commit | 已配置(`pyproject.toml`, `.pre-commit-config.yaml`) |
| 测试 | 跨 5 个文件的 25 个测试,涵盖 标准化、配置、置信度引擎、提供商健康、插件发现、情报 DB、差异模式、导出器;由于在此沙盒中未运行 `coverage.py`(没有网络进行安装),因此未提供覆盖率百分比声明 |
| CI/CD(lint -> 测试矩阵 3.11/3.12 -> build) | 完成 |
| pip 打包(`pyproject.toml`,`passive-enum` console script) | 完成 |
| Async engine | 未完成 -- 当前的并发基于线程池(`ThreadPoolExecutor`),这对于 I/O 密集型的 HTTP/DNS 工作已足够;真正的异步重写是一个更大的架构更改,留待未来进行 |
| 带有图表/时间线的 HTML dashboard | 部分完成 -- `report.html` 是一个交互式、可排序/可过滤的表格,带有摘要统计卡片,而不是图表 dashboard |
| 专用的“Mr. Cool”启动横幅(艺术字 logo + 作者/版本/引擎/模式/状态面板) | 完成 |
| `--minimal` 输出模式(仅保留 `txt/final_hosts.txt` + `reports/report.json`,删除其他所有内容) | 完成 |
| 每次运行自动保持最新输出(第二次运行永远不会与第一次运行的残留文件混在一起;`--resume` 是唯一的退出选项) | 完成 |
| 批量模式:`-dL/--domain-list example.txt` 在一个命令中扫描 2 个或以上域名,每个域名进入其独立的输出子文件夹 | 完成 |
### 最近一次完整代码修订中修复的问题
从头到尾检查了整个代码库并修复了发现的所有问题:
- **Bug:** 同时使用 `--diff --minimal` 会静默删除
`reports/diff.json` / `reports/diff.md` -- `--minimal` 的清理只
保留了 `report.json`,因此 `--diff` 被要求生成的那一个结果被
丢弃了。已修复:`cleanup_to_minimal()` 现在也会
保留(如果存在)`diff.json`/`diff.md`。添加了回归测试
(`test_cleanup_to_minimal_keeps_final_report_and_diff_output`)以及
端到端复现,以确保此问题不会静默复发。
- **Bug:** Provider Health 格式化程序中无用的三元表达式
(`"✓" if hosts > 0 else "✓"` -- 两个分支完全相同,显然是
遗留错误)。简化为仅保留勾选符号。
- **清理:** 移除了 `cli.py` 中未使用的 `import sys`。
- **加固:** 将排列主机映射回其父级(用于 `discovery_path`)时使用的递归深度保护,现在与
`wordgen.generate_deep_permutations` 的边界检查完全匹配(`depth < 0
or depth >= max_depth`,而不仅仅是上限) -- 防御性编程,因为在
实践中到达该代码的每个基础主机都已经在范围内。
- 完整检查还包括:API key 是否在任何地方被记录/打印
(并没有 -- 仅作为不透明的 dict 值传递),每个模块中未使用的 import
(启发式 + 手动检查 -- 干净),裸
`except:` 子句(没有 -- 每个捕获都是 `except Exception:`,因此
`KeyboardInterrupt`/`SystemExit` 仍然可以正确传播)。
### 安装(pip,可选)
```
pip install -e . # editable install from this repo, or `pip install .`
passive-enum -d example.com --profile balanced
```
`python3 run.py -d example.com` 继续像以前一样工作 -- pip
console script 是一个额外的入口点,而不是替代品。
**范围:** 仅针对您拥有或明确
授权测试的域名运行此工具。它仅查询公共/被动数据源并执行
标准 DNS 解析 -- 没有漏洞利用,没有凭据攻击。
可选的 `--active-recursion` 标志会抓取已发现主机上的公开页面
(以挖掘 JS/CSP 获取更多主机名) -- 仍然没有漏洞利用,但这是
对目标自身服务器的直接 HTTP 请求,因此它是可选的且默认关闭。
## 1. 安装
```
# 从项目根目录(包含 run.py 的文件夹)
pip install -r requirements.txt --break-system-packages
# 可选的外部 CLI 工具(自动检测,如缺失则跳过):
# subfinder https://github.com/projectdiscovery/subfinder
# assetfinder https://github.com/tomnomnom/assetfinder
# findomain https://github.com/findomain/findomain
# sublist3r https://github.com/aboul3la/Sublist3r
```
检查您系统上可用的内容:
```
python3 run.py --list-plugins
name confidence available
-----------------------------------------------
alienvault_otx Medium yes
anubisdb Medium yes
assetfinder Medium no (missing key/binary)
bufferover Medium yes
c99 High no (missing key/binary)
censys High no (missing key/binary)
certdb Medium no (missing key/binary)
certspotter High yes
chaos High no (missing key/binary)
crt.sh High yes
findomain Medium no (missing key/binary)
fullhunt Medium no (missing key/binary)
github Medium no (missing key/binary)
hackertarget Medium yes
rapiddns Medium yes
subfinder Medium no (missing key/binary)
sublist3r Medium no (missing key/binary)
threatminer Medium yes
urlscan Medium yes
virustotal Medium no (missing key/binary)
wayback Medium yes
```
开箱即用的免费来源 (9):`crt.sh`、`bufferover`、`alienvault_otx`、
`rapiddns`、`wayback`、`urlscan`(数量少)、`certspotter`(速率限制
低)、`hackertarget`(免费层级严格速率限制)、`anubisdb`、
`threatminer`。
CLI 工具来源(单独安装,在 `PATH` 上自动检测):`subfinder`、
`assetfinder`、`findomain`、`sublist3r`。
需密钥来源(免费注册):
| 来源 | 免费注册地址 | CLI 标志 |
|---|---|---|
| GitHub | github.com(个人访问 token) | `--github-token` |
| Censys | search.censys.io(社区层级) | `--censys-id` + `--censys-secret`(均需提供) |
| VirusTotal | virustotal.com | `--virustotal-key` |
| urlscan.io | urlscan.io(可选,提高速率限制) | `--urlscan-key` |
| CertSpotter | sslmate.com(可选,提高速率限制) | `--certspotter-key` |
| FullHunt | fullhunt.io | `--fullhunt-key` |
| Chaos | chaos.projectdiscovery.io(免费,基于资格) | `--chaos-key` |
您要求的付费/标准不明确的来源,以相同的插件方式接入:
| 来源 | 说明 | CLI 标志 |
|---|---|---|
| C99 | **付费** c99.nl 子域查找 API -- 需要您自己的付费密钥 | `--c99-key` |
| CertDB | 不存在单一的标准化公共“CertDB” API -- 作为带密钥的 **存根**(`subdomain_recon/sources/certdb.py`)发布,指向占位符 URL;请修改 `BASE_URL` 和响应解析以匹配您所指的具体服务,如果不需要,请删除该文件 | `--certdb-key` |
特意未包含(仅限付费,无可用的免费层级):Shodan、
BinaryEdge。特意未包含的来源及其原因(已停止更新、
违反服务条款的抓取,或已通过其他方式涵盖的独立工具)与
之前的 README 部分保持一致,并且仍然适用。
### 存储 API keys
```
cp .env.example .env
# 然后编辑 .env 并填入你拥有的任何 key
```
`.env` 已经在 `.gitignore` 中。如果密钥在多个
地方设置,优先级为:`--flag-on-cli` > shell 环境变量 > `.env` 文件。
## 2. 基本用法
```
python3 run.py -d example.com --profile balanced
```
### 自动保持最新输出(默认行为)
每次运行都会针对该域名从干净的状态开始 -- 除非您传递
`--resume`,否则域名输出目录会在
pipeline 启动前自动清除。针对同一域名的第二次运行永远不会与
第一次运行的残留文件混在一起;您不需要记住 `--fresh`(为了向后兼容,它被保留为
无操作标志,但只要您不进行恢复,清除现在是默认
行为)。
```
python3 run.py -d example.com --profile fast # run 1 -> output/...
python3 run.py -d example.com --profile fast # run 2 -> output/ auto-wiped first, clean result
python3 run.py -d example.com --profile fast --resume # only this one preserves the prior output
```
### 一次扫描多个域名(`-dL` / `--domain-list`)
```
# example.txt -- 每行一个 domain,空行和 #comments 将被跳过
example.com
another-domain.com
# this-one-is-commented-out.com
third-domain.com
```
```
python3 run.py -dL example.txt --profile balanced
```
针对文件中的每个域名运行完整的 pipeline(重复项
不区分大小写去重)。您也可以将 `-d` 与 `-dL` 结合使用 -- 两者都会
被扫描。每个域名都有其**独立的输出子文件夹**:
```
output/
example.com/
txt/ json/ reports/ ...
another-domain.com/
txt/ json/ reports/ ...
third-domain.com/
txt/ json/ reports/ ...
```
(使用单个 `-d` 且不带 `-dL` 时,输出仍像以前一样保持平坦在 `output/...` --
每个域名的子文件夹仅在批量模式下启用,因此
现有的单域名脚本/工作流不受影响。)自动保持最新
适用于每个域名,并且 Ctrl+C 会停止整个批次(已完成
的域名保留其结果;被中断的域名可以单独使用
`--resume -d ` 恢复)。批次摘要
(每个域名的 OK/INTERRUPTED/FAILED)会在最后打印。
**只想要最终结果,不要其他内容?** 使用 `--minimal` -- 在
运行之后,除了两个最终报告文件之外的所有内容都会被自动删除:
```
python3 run.py -d example.com --profile fast --minimal
```
只留下:
```
output/
txt/final_hosts.txt # hostnames only, one per line
reports/report.json # full structured report (IPs, sources, confidence, cloud, ...)
```
其他所有内容 -- 每个阶段的 `json/`、其他的 `txt/*.txt` 文件、
`report.csv`/`.html`/`.md`、`cache.sqlite3`、`intel.sqlite3`、
`metadata.json`、`checkpoints/`、`logs/` -- 都将被删除。(如果不使用
`--minimal`,默认行为保持不变:仅自动删除 `checkpoints/`,
其他所有内容都会保留 -- 请参见第 3 节和第 18 节。)
## 3. 输出结构
```
output/
txt/
passive_hosts.txt # stage 01 -- raw candidates, pre-DNS-validation
validated_hosts.txt # stage 03 -- initial DNS-validated hosts
recursive_hosts.txt # stage 04 -- hosts after recursive expansion
permutation_hosts.txt # stage 06 -- hosts found via permutation
final_hosts.txt # FINAL validated hostnames -- ONLY hostnames, one per line
json/
01_passive_sources.json
02_wildcard_detection.json
03_initial_dns_validation.json
04_recursive_enumeration.json
05_word_extraction.json
06_permutation_validation.json
07_reverse_dns.json # PTR + ASN, per IP
08_cloud_discovery.json
09_dns_records.json
10_final_filter_validation.json # final hosts + TTL/resolver/RTT/DNSSEC
reports/
report.json # full structured report: hostname -> IPs + everything else
report.csv
report.html # dark-themed, sortable, filterable
report.md
metadata.json # first_seen/last_seen/sources/discovery_path per host
cache.sqlite3 # API + DNS cache (persists across runs)
checkpoints/ # per-stage checkpoint files, auto-deleted after a
# successful run (see "Auto-cleanup" below)
logs/
```
**`txt/final_hosts.txt` 仅包含已验证的主机名** -- 不包含 IP,不包含
元数据 -- 完全是“仅主机名”列表。您要求追踪的其他每个字段
(来源、provider_count、confidence、records、cloud、wildcard、
recursive_depth、discovery_path、tags、metadata)都位于 `reports/report.json` 中,
按主机划分,例如:
```
{
"host": "login.example.com",
"validated": true,
"sources": ["crt.sh", "recursive-wayback"],
"provider_count": 2,
"confidence": 0.98,
"confidence_label": "High",
"records": {
"ips": ["1.2.3.4"],
"ttl": 300,
"resolver_used": "8.8.8.8",
"response_time_ms": 14.2,
"dnssec": false,
"dns_records": {"A": {"values": ["1.2.3.4"], "ttl": 300}, "MX": {...}}
},
"cloud": {"provider": "AWS", "service": "CloudFront", "evidence": "d123.cloudfront.net"},
"wildcard": false,
"recursive_depth": 1,
"discovery_path": ["example.com"],
"tags": ["recursive"],
"metadata": {
"first_seen": 1753350000.0,
"last_seen": 1753350100.0,
"validation_time": 1753350100.0,
"ptr": {"1.2.3.4": "ec2-1-2-3-4.compute-1.amazonaws.com"},
"asn": {"1.2.3.4": {"asn": "16509", "prefix": "1.2.3.0/24", "country": "US",
"registry": "arin", "org": "AMAZON-02"}}
}
}
```
### 自动清理
运行成功完成后,`output/checkpoints/` 将被自动删除
(一旦每个阶段完成,就没有什么可恢复的了) --
`txt/`、`json/`、`reports/`、`metadata.json`、`cache.sqlite3` 和 `logs/`
将保留在原处;这些是实际的交付物。传递 `--keep-checkpoints`
如果您想检查它们或稍后对运行进行恢复分析。
## 4. 配置文件
配置文件 | 线程 | 最大深度 | 排列/级别 | 缓存 TTL | 检查的 DNS 解析器
---|---|---|---|---|---
fast | 30 | 2 | 500 | 1h | 系统默认
balanced | 60 | 5 | 3,000 | 6h | 8.8.8.8, 1.1..1
thorough | 100 | 8 | 20,000 | 24h | 8.8.8.8, 1.1.1.1, 9.9.9.9
```
python3 run.py -d example.com --profile thorough --max-depth 8
python3 run.py -d example.com --profile balanced --threads 120 --perm-limit 8000
python3 run.py -d example.com --profile balanced --config-file myconfig.json
```
## 5. 更智能的通配符检测
简单的单探测通配符检查存在两个问题: 某个解析器的
陈旧缓存或临时应答可能会产生误报,并且 子域可以有
其**自身**独立于根域的通配符条目
(例如,`*.dev.example.com` 捕获所有内容,即使 `*.example.com` 并
没有)。
此版本修复了这两个问题:
- **多探测、多解析器多数投票。** 4 个随机的、基本上
保证未注册的标签会在
当前活跃的配置文件中的每个解析器(`balanced`/`thorough` 上的 Google/Cloudflare/Quad9)上进行探测。一个 IP
只有在**大多数**探测/解析器组合中出现时,才会被
计为通配符签名的一部分 -- 单个偶然的应答无法
单独产生(或隐藏)通配符信号。这就是修复
“通配符检测总是返回 0”问题的方法:旧版本使用
单一的静态检查,太容易漏掉临时的通配符
响应,或者太急于将一个零星的 IP 称为通配符。
- **按层级检测**,精神上与以前相同:在
排列阶段在已验证的主机下扩展得更深之前,它会
单独探测 `*.` 以获取其自己的通配符签名。发现
是通配符的主机将保留在结果中(报告中为 `"wildcard": true`),但不会用作
进一步排列的基础。
## 6. DNS 验证丰富
`reports/report.json` / `json/10_final_filter_validation.json` 中
每个最终主机的记录现在除了包含解析的 IP 外,还包含:
- 解析记录的 **TTL**
- **使用的解析器**(实际应答的配置解析器中的哪一个)
- 以毫秒为单位的 **响应时间**
- **DNSSEC** -- 尽力检查支持 DNSSEC 的重新查询上的 Authenticated Data (AD) 标志
## 7. 递归枚举 -- 多源扩展
旧版本仅针对每个新发现的主机重新查询 crt.sh。此
版本每轮通过**每个主机的多个独立来源**进行
扩展:
```
developer.example.com
|
+--> crt.sh (certificate SAN chaining)
+--> Wayback Machine (archived URLs under the host)
+--> GitHub code search (only if --github-token is set)
+--> [opt-in, --active-recursion] JS file links + CSP header hostnames
```
每个新验证的主机都会在 `discovery_path` 中记录**它是在哪个父主机下被发现的**
-- 因此您可以准确追踪
`vpn.internal.developer.example.com` 是如何被到达的(例如,
`["example.com", "developer.example.com", "internal.developer.example.com"]`)。
## 8. 反向 DNS -- 按 ASN / 提供商 / 云分组
`reports/report.json["reverse_dns_groups"]`(以及 `report.md` / `summary` 输出的“Reverse DNS”部分
)按以下方式对每个最终主机进行分组:
- **ASN** -- 通过 Team Cymru 的基于 DNS 的 whois 服务
(`origin.asn.cymru.com` / `asn.cymru.com`)进行免费、无需密钥的查找
;无需 API key,无速率受限的
付费依赖)
- **云提供商** -- 见下文
每个主机的 PTR + ASN 详细信息也位于完整报告中每个主机的 `metadata.ptr` /
`metadata.asn` 下。
## 9. 云/CDN 发现
每个已验证主机的 CNAME 链(最多 8 跳)都会被跟踪并与
已知的提供商指纹进行匹配:
CloudFront/S3/ELB -> **AWS** | azurefd/azurewebsites/blob.core.windows.net -> **Azure**
| appspot/run.app/cloudfunctions -> **GCP** | cloudflare.net -> **Cloudflare**
| fastly.net -> **Fastly** | akamai*/edgekey -> **Akamai** |
vercel.app -> **Vercel** | netlify.app -> **Netlify** | heroku* -> **Heroku**
| github.io -> **GitHub Pages**
匹配结果在每个主机中显示为 `"cloud": {"provider": "AWS", "service": "CloudFront", "evidence": "...", "cname_chain": [...]}`
并在 `reverse_dns_groups.by_cloud_provider` 中汇总。(它只能
报告 CNAME 链实际揭示的内容 -- 直接指向
裸 IP 且没有 CNAME 的主机无法通过这种方式进行归属;这是
被动 CNAME 指纹识别的固有限制,而不是 bug。)
## 10. 恢复与 checkpoint
```
python3 run.py -d example.com --profile thorough --resume
python3 run.py -d example.com --profile thorough --fresh # force a clean re-run
```
pipeline 阶段,按顺序:`01_passive_sources`、`02_wildcard_detection`、
`03_initial_dns_validation`、`04_recursive_enumeration`、`05_word_extraction`、
`06_permutation_validation`、`07_reverse_dns`(+ ASN)、`08_cloud_discovery`、
`09_dns_records`、`10_enrichment`、`11_final_filter_validation`。
## 11. 添加新来源(插件架构)
无需更改核心 pipeline 代码。在
`subdomain_recon/sources/` 中创建一个新文件:
```
# subdomain_recon/sources/my_source.py
from .base import Source, SourceContext
class MySource(Source):
name = "my_source"
confidence = "Medium"
def fetch(self, domain, ctx: SourceContext):
return [f"host1.{domain}", f"host2.{domain}"]
```
它会被自动拾取 -- 使用 `python3 run.py --list-plugins` 验证。
## 12. 运行测试套件
```
pip install pytest dnspython --break-system-packages
pytest tests/ -v
```
涵盖:主机名标准化、范围/深度检查、配置文件加载
和覆盖、置信度评分,以及完整的 `txt/ + json/ + reports/`
导出布局(包括“自动清理仅移除 checkpoint”
行为)。
## 13. 提供商健康摘要
每次运行都以按来源的细分结束 -- 打印到控制台并
嵌入 `reports/report.md` 中:
```
Provider Summary
alienvault_otx ✓ 114 hosts
certspotter ✓ 98 hosts
github ✗ Missing key (github)
chaos ✗ Missing key (chaos)
subfinder ✓ 31 hosts
Unique Hosts : 421
Duplicates : 198
Errors : 2
```
`✗` 区分了 **跳过**(不可用 -- 缺少密钥或 CLI 二进制文件,
明确命名)和 **错误**(异常实际上逃逸出了该
来源的 `fetch()`)。有关一个已知的限制,请参阅 `ARCHITECTURE.md`
(受速率限制/认证失败的 HTTP 响应目前显示为“ok, 0 hosts”
而不是一个明显的错误,因为来源尚未将状态码报告
回 pipeline)。
## 14. 置信度引擎
完整的公式和 JSON `confidence_breakdown` 结构在
`ARCHITECTURE.md` 中。简要版本 -- 累加积分,可通过
`--config-file` 配置:
```
{ "confidence_weights": { "cloud": 20, "permutation_penalty": -25 } }
```
默认值:2+ 提供商 +20,DNS 有效 +20,递归 +15,云 +10,GitHub
+15,crt.sh +10,仅排列 -15。分数限制在 `[0, 100]`;High
## 15. SQLite 情报 DB + 差异模式
每次运行都存储在 `output/intel.sqlite3` 中(与 API/DNS
`cache.sqlite3` 分开) -- 运行历史、跨运行的主机历史、跨运行
重复检测和主机名搜索都是针对它进行的普通 SQL 查询
(参见 `subdomain_recon/intel_db.py`)。如果您
不需要,可以使用 `--no-intel-db` 跳过此步骤。
```
# 与特定的已保存 report 进行 diff
python3 run.py -d example.com --diff /path/to/old/reports/report.json
# 与该 domain 在 intel.sqlite3 中最近一次的先前运行进行 diff
python3 run.py -d example.com --diff auto
```
写入 `reports/diff.json` + `reports/diff.md` 并记录 NEW/REMOVED
摘要。
## 16. 恢复 + Ctrl+C
```
python3 run.py -d example.com --profile thorough --resume # the ONLY way to skip the auto-wipe
python3 run.py -d example.com --profile thorough # every other invocation auto-wipes first (see section 2)
```
`--fresh` 仍然会被解析(这样旧脚本就不会中断),但现在是一个无操作 --
只要不传递 `--resume`,清除就是默认行为。
在运行过程中按下 Ctrl+C 不再只是静默退出 -- 它会准确记录
哪些阶段已完成/checkpoint,并打印精确的 `--resume`
命令以继续。恢复粒度是按阶段的(有关为何未实现阶段中恢复的原因,请参阅 `ARCHITECTURE.md`
)。在批量模式(`-dL`)下,Ctrl+C
在当前域名之后停止整个批次;已完成的域名
保留其结果,被中断的域名可以单独恢复。
## 17. 开发者工具
```
pip install -r requirements-dev.txt # pytest, black, ruff, mypy, pre-commit
pre-commit install # run lint+format+tests before every commit
black .
ruff check .
mypy .
pytest tests/ -v
```
CI(`.github/workflows/tests.yml`):lint(`ruff` + `black --check`)-> 测试
矩阵(Python 3.11、3.12)-> 软件包构建,每个阶段都作为下一个阶段的门控。
## 18. 故障排除
- **`pip install ... --break-system-packages` 提示“no such option”** --
您的 pip 版本较旧;请升级 pip 或去掉该标志并使用
virtualenv。
- **未安装 dnspython** -- 基本的 A 记录解析会回退到
Python 内置的 `socket` 模块,但 AAAA/CNAME/MX/TXT/NS/PTR、TTL、
DNSSEC 和 ASN 查找都需要它:`pip install dnspython --break-system-packages`。
- **`subfinder` / `assetfinder` / `findomain` / `sublist3r` 显示“no (missing
key/binary)”** -- 这些是可选的外部 CLI 工具;请安装它们并
确保它们在 `PATH` 上,或者忽略它们。
- **c99 / certdb 从未运行** -- 两者都需要您自己提供密钥(c99 是
付费 API;certdb 是存根 -- 请参阅第 1 节)。
- **空的 `txt/final_hosts.txt`** -- 检查 `output/logs/run_*.log` 和
`reports/report.json["metrics"]` 内部的 `errors` 列表 -- 最常见的是没有
可访问的来源(没有网络 / 没有 keys / 没有 CLI 工具),或者
该域名具有激进的通配符 DNS 过滤掉了每个候选者(检查
`report.json["wildcard_ips"]`)。
- **缓存似乎陈旧** -- 通过 `--config-file` 降低 `cache_ttl_seconds`,或者
删除 `output/cache.sqlite3`。
## 许可证
MIT -- 请参阅 `LICENSE`。此工具仅供授权的安全测试
和研究使用。仅针对您拥有或获得
明确书面测试许可的域名和系统使用。作者不对
滥用承担任何责任。
标签:ESC4, GitHub, OSINT, 子域名枚举, 安全侦察, 实时处理, 无服务器架构, 系统安全, 逆向工具