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, 子域名枚举, 安全侦察, 实时处理, 无服务器架构, 系统安全, 逆向工具