背景
SRC 挖洞的大头耗在信息收集,标准套路四步:
- 子域枚举 — 拉根域下所有子域,确认存活
- 资产测绘 — FOFA/Hunter 捞存活资产,看端口与服务
- 指纹识别 — 判断框架(ThinkPHP、Shiro、Spring……),决定打什么
- 敏感路径探测 — 扫
.git、.env、swagger、actuator
手动跑要来回切工具、复制粘贴、手工去重,一次 2 小时起步且高度重复。于是用 Python 写了 src-recon-tool 把流水线固化:一条命令跑完四步,全流程 30 分钟内。
架构设计
入口是 recon.py CLI,四个核心模块按子命令组织,外加 YAML POC 模板引擎与可选 LLM 辅助:
target → recon.py → subdomain / asset / fingerprint / paths → out/<target>/
↓
poc_engine(YAML 模板)
↓
llm_assist(总结报告)
几个关键设计决策:
- 模块化:每个模块是独立子命令,既能
all一把梭,也能只跑一步 - 无 key 自动降级:没有 FOFA/Hunter/LLM 的 key 时模块自动降级或跳过,流水线永远能跑通
- 输出落盘:结果全写入
out/<target>/,去重、合并、归档一步到位 - 模板化 POC:检测逻辑做成 nuclei 风格 YAML 模板,加检测点只改 YAML
子域枚举模块
首选 OneForAll:数据源多(证书透明日志、DNS 爬虫、搜索引擎、测绘平台),覆盖面广;独立部署,用环境变量 ONEFORALL_HOME 指定路径。
OneForAll 依赖多、不是每台机器都方便,于是做了降级:没配 OneForAll 时改用 crt.sh 证书透明日志——https://crt.sh/?q=%25.example.com&output=json 无需 key,直接拉 JSON 解析子域;覆盖面差些但零依赖。
python src/recon.py subdomain -d example.com
输出示例:
[+] 子域枚举完成: example.com
共发现 128 个子域(OneForAll: 96 / crt.sh: 89 / 去重后: 128)
结果已保存: out/example.com/subdomains.txt
资产测绘模块
子域列表映射为实际资产(IP、端口、服务),接了两家测绘平台:
- FOFA:
https://fofa.info/api/v1/search/all,需FOFA_EMAIL+FOFA_KEY - Hunter:
https://hunter.qianxin.com/openApi/search,需HUNTER_KEY
key 走环境变量,不进代码和 git;Windows 用 setx 持久化:
export FOFA_EMAIL=xxx FOFA_KEY=xxx HUNTER_KEY=xxx # Linux / macOS
setx FOFA_EMAIL xxx && setx FOFA_KEY xxx # Windows
核心逻辑:拼查询语句、翻页、字段清洗:
def query_fofa(domain: str) -> list[dict]:
q = f'domain="{domain}"'
# FOFA API v1: /api/v1/search/all?email=&key=&qbase64=&size=&fields=
params = {
"email": os.environ["FOFA_EMAIL"],
"key": os.environ["FOFA_KEY"],
"qbase64": base64.b64encode(q.encode()).decode(),
"size": 100,
"fields": "host,ip,port,protocol,title,server",
}
resp = requests.get("https://fofa.info/api/v1/search/all", params=params, timeout=30)
resp.raise_for_status()
return resp.json().get("results", [])
FOFA 免费账号有积分限制,翻页太狠会被限流,故加了超时与重试,单源失败不影响其他源;没配 key 直接跳过并记日志。
指纹识别与敏感路径
指纹识别内置覆盖 ThinkPHP、Shiro、Spring、WordPress、Nginx 等规则,每条是”特征 → 指纹名”映射,走 headers + body 双通道:
- headers:
X-Powered-By、Server、Set-Cookie(如 Shiro 的rememberMe=deleteMe) - body:特定 meta、JS 路径、报错特征(如 ThinkPHP 报错页的
ThinkPHP)
FINGERPRINTS = [
{"name": "Shiro", "headers": ["rememberMe=deleteMe"]},
{"name": "ThinkPHP", "body": ["ThinkPHP", "tp5"]},
{"name": "Spring", "headers": ["X-Application-Context"], "body": ["Whitelabel Error Page"]},
{"name": "Nginx", "headers": ["nginx"]},
{"name": "WordPress", "body": ["wp-content", "wp-includes"]},
# ...
]
敏感路径探测内置字典,对重点资产逐个探测:
python src/recon.py paths -u https://example.com
“看到就该警惕”的路径:
/.git/config
/.env
/swagger-ui.html
/actuator
/druid/index.html
/actuator/env
/actuator/heapdump
逻辑:GET 请求 200 且 body 长度符合预期即命中,写入 out/<target>/sensitive_paths.txt 作为人工测试清单。
YAML POC 模板引擎
指纹识别后很多检测动作是固定的:是 Shiro 就测 rememberMe 反序列化,是 Spring 就测 actuator 泄露。写死在 Python 里很笨重——加检测点要改代码、跑测试、发版。
于是做了 nuclei 风格 YAML POC 模板引擎:检测逻辑外置到 pocs/,加检测点只加 YAML。引擎实现 nuclei 模板子集:info、requests、status/contains matcher、and/or 组合。
id: example-admin-detect
info:
name: Admin Panel Detect
severity: info
requests:
- method: GET
path: "/admin"
matchers:
- type: status
status: [200, 401, 403]
模板含义:GET /admin 返回 200/401/403 任一即命中(存在管理后台入口)。更复杂可用 contains 匹配响应体关键词,多 matcher 用 condition: and 组合:
id: spring-actuator-env
info:
name: Spring Actuator Env Exposed
severity: medium
requests:
- method: GET
path: "/actuator/env"
matchers:
- type: status
status: [200]
- type: contains
words: ["spring", "java.version"]
condition: and
调用方式:
python src/recon.py poc -t https://example.com -p pocs/example-http-detect.yaml
跑完输出命中/未命中,命中的进高优先级清单。引擎通用,也能复用公开 nuclei 模板做漏洞验证;目前只实现子集,复杂模板(多请求、变量、raw 请求)还在路上。
LLM 辅助
原始资产列表直接看容易漏重点,工具里可选 LLM 辅助模块,做两件事:
- 资产分级:资产 + 指纹打包给 LLM,按攻击价值分级(暴露的后台 > 带指纹框架 > 纯静态页)
- 攻击面总结:输出
out/<target>/llm_summary.md,列出优先测试点
配置走 OpenAI 兼容接口:
export LLM_API_KEY=xxx
export LLM_BASE_URL=https://api.openai.com/v1 # 可配其他兼容端点
export LLM_MODEL=gpt-4o-mini
同样无 key 自动降级:没配就跳过。LLM 输出只当参考、不进报告,人工复核后才采信,避免幻觉污染结果。
效果对比
同目标同批资产,手动 vs 工具化:
| 步骤 | 手动(工具来回切) | src-recon-tool |
|---|---|---|
| 子域枚举 | 30–40 分钟(开 OneForAll、等跑完、复制结果) | 3–5 分钟(一条命令) |
| 资产测绘 | 20–30 分钟(FOFA/Hunter 网页端手动翻页、复制) | 3–5 分钟(API 自动分页) |
| 指纹识别 | 15–20 分钟(逐个资产肉眼判断或开工具) | 2–3 分钟(批量规则匹配) |
| 敏感路径探测 | 20–30 分钟(手工构造请求逐条试) | 3–5 分钟(字典批量探测) |
| 结果整理去重 | 20–30 分钟(Excel/记事本手工整理) | 自动落盘 out/<target>/ |
| 合计 | 约 2 小时+ | 30 分钟内 |
省时间在三处:并行(模块互不依赖)、免搬运(自动落盘去重)、可复用(换个 -d 就是新目标)。
实战应用
这套工具已用在 EDUSRC 授权范围内的实战里,作为测试”开场动作”。心得:
- 先全流程再深入:
recon.py all后挑指纹/敏感路径命中的资产人工测试,命中率远高于无差别扫 - POC 沉淀是复利:新特征固化成 YAML 模板,下次自动扫到
- 降级救了场:临时环境没 key 也能跑通全流程(子域走 crt.sh)
- LLM 分级只当参谋:优先级可参考,打不打、怎么打还是人工判断
红线:只用于授权范围内的安全测试,未授权目标一律不碰;自动化省的是重复劳动,不降低合规要求。
开源地址
已开源(MIT License):
https://github.com/xiaoyang-xyc/src-recon-tool
目录结构:
src/recon.py CLI 入口
src/modules/ 各功能模块
pocs/ YAML POC 模板
tests/ 单元测试
out/ 输出目录(gitignore)
欢迎拿去用,或提 issue/PR 补充指纹与 POC 模板。后续计划:更多 matcher(regex、dsl)、多请求链式 POC、结果导出报告格式。