Andrewliera/GhostMap
GitHub: Andrewliera/GhostMap
一款面向授权漏洞赏金研究的行为式 Web 侦察工具,通过强力噪音过滤和稳定的跨扫描发现追踪机制,帮助安全研究者聚焦于真正值得手动验证的目标。
Stars: 0 | Forks: 0

# GhostMap
一款用于授权漏洞赏金研究的行为式 Web 侦察工具。
GhostMap 使用真实浏览器爬取目标,捕获浏览器看到的网络流量,对观察到的 endpoint 进行分类,并挑出最值得手动调查的目标。它的设计初衷是契合漏洞赏金猎人的实际工作方式:针对单个项目限定范围,谨慎对待授权,并且通过合理的结构化设计,使得验证状态能够在多次重新扫描中保留下来。
```
ghostmap workspace init
ghostmap -w --idor --html-report
ghostmap workflow -w
ghostmap verify -w --finding F-a3f1c8 --status testing
```
## 为什么开发这个工具
大多数安全侦察工具致力于发现*更多*的内容。而 GhostMap 则致力于发现*更少,但更可靠*的内容。在看到扫描结果出现大量误报之后——例如 Datadog RUM 信标被标记为 IDOR 候选者,广告追踪像素被评分为高优先级 endpoint,第三方分析 URL 中的顺序数字 ID 在面板上亮起警示——该工具的设计目标变成了:进行强力过滤,只展示猎人能在 30 分钟内切实完成验证的内容,并让关于*测试了什么以及为什么测试*的审计记录在几个月后也能轻松追溯。
该工具是围绕漏洞赏金猎人实际使用的工作流构建的:一次只处理一个项目,每次扫描前谨慎核实授权范围,在提交前对每个发现进行手动验证,并在单项测试任务所需的多次重新扫描中保持状态持久化。
## 值得一提的设计决策
**基于范围的授权拦截。** 每个项目都有自己的 YAML 范围文件,用于声明范围内的主机、范围外的路径,以及针对特定项目允许的主动行为权限(IDOR 变异、隐藏路由探测、已认证扫描)。如果主机不在授权范围内,或者程序未授权主动行为,扫描将被拒绝执行。这不是存在于用户脑海中的策略,而是通过代码强制执行的。([`core/scope.py`](core/scope.py))
**具有稳定 ID 的跨扫描发现注册表。** 发现结果由 (发现类型, 归一化目标, 区分参数) 的内容哈希作为主键进行索引,而不是根据特定扫描中的排序位置。给定 IDOR 候选项的 `F-a3f1c8` 在每次重新扫描中都会保持为 `F-a3f1c8`,因此验证状态、证据包和报告草稿都会绑定到实际的发现结果上,而不是绑定到那些在下次扫描发现新内容时就会变动的数字编号上。([`core/workspace.py`](core/workspace.py))
**深度防御的凭证脱敏。** 当扫描使用 `--cookie` 或 `--auth-header` 时,身份验证凭证永远不会写入磁盘。爬虫会在捕获时对请求/响应标头进行脱敏。输出写入器在序列化之前会执行第二轮脱敏。程序会对 POST body 进行清洗,清除 JSON token、表单编码凭证、Bearer/Basic auth 值、OTP 字段以及 CSRF token。这样做的目的是,如果有人读取了由于失误而被提交到公共代码仓库的扫描 JSON 文件,他们将无法提取出可用的会话。([`core/auth.py`](core/auth.py))
**工作区将代码与数据分离。** 早期版本将扫描输出写入到存放渲染器模块的同一目录中,导致 `rm output/*.json` 成了一个极易引发误删的危险操作。工作区为每个程序提供了独立的目录树:范围文件、扫描记录、报告、证据包以及发现注册表。在清理旧扫描记录时,不会发生意外删除渲染器代码的情况。
**保守的噪音分类。** `analyzer/noise.py` 模块将 URL 分类为多种类别——RUM 信标、营销像素、统计分析、广告网络、CDN 托管的第三方脚本、框架内部结构、静态资源——这样优先级排序器就可以忽略它们,而不是仅仅因为路径中恰好包含 UUID 就将它们标记为 IDOR 候选者。在针对某真实金融科技目标进行的首次扫描中,启用此功能后,噪音发现数量从 1430 个骤降至 36 个。
## 它的实际功能
```
Input: one target URL + a scope file + optional auth credential
│
▼
┌───────────────────┐
│ Playwright crawl │ follows in-scope links only, captures network XHRs
└───────────────────┘
│
▼
┌───────────────────┐
│ Analyzers │ noise filter, IDOR candidate detector, response
│ │ classifier, hidden route prober (if scope permits)
└───────────────────┘
│
▼
┌───────────────────┐
│ Workspace │ stable F-### IDs, deduplicated across scans,
│ registry │ verification state attached to findings
└───────────────────┘
│
▼
Output: scan JSON, HTML dashboard, markdown triage workflow,
evidence-redacted by default
```
## 当前状态
- 包含 99 个单元测试,ruff 检查通过,pyright 检查通过
- 已在六个真实的漏洞赏金项目上进行了测试(gonzagatech [自有项目]、Compass、Meesho、Twilio、Remitly 等),并且在每次扫描前都明确核实了授权
- 单人开发者项目,约 3500 行 Python 代码
- 尚未发布到 PyPI;需从源码安装
## 安装
需要 Python 3.10+ 和 Playwright。
```
git clone https://github.com/andrewliera/ghostmap.git
cd ghostmap
pip install -e .
playwright install chromium
```
## 快速开始
```
# 为一个 bug bounty program 初始化工作区
ghostmap workspace init
# (如果存在则自动使用 scopes/.yaml)
# 运行作用域内的扫描
ghostmap https://target.example.com -w --idor --html-report
# 对 findings 进行分类
ghostmap workflow -w
cat workspaces//reports/workflow.md
# 在处理 findings 时标记它们
ghostmap verify -w --finding F-a3f1c8 --status testing --note "reproducible in browser"
# 附上经过脱敏的 evidence
ghostmap evidence -w --finding F-a3f1c8 \
--request evidence/req.txt --response evidence/resp.txt
# 起草一份保守的 bug bounty 报告
ghostmap report -w --finding F-a3f1c8
```
## 已认证扫描
对于明确允许进行已认证自动化测试的项目:
```
# 将凭证存储在环境变量中,使其永远不会进入 shell history
read -s GHOSTMAP_TOKEN
export GHOSTMAP_TOKEN
# 对 bearer-token APIs(大多数现代 SPAs)使用 --auth-header
ghostmap https://target.example.com/dashboard -w \
--auth-header "Authorization: Bearer $GHOSTMAP_TOKEN" \
--html-report
# 或者对 session-cookie APIs 使用 --cookie
ghostmap https://target.example.com/dashboard -w \
--cookie "$GHOSTMAP_COOKIE" \
--html-report
# 完成后,使凭证失效并取消设置该变量
unset GHOSTMAP_TOKEN
```
凭证会从所有写入磁盘的输出结果中脱敏。但在扫描期间,它仍会驻留在内存中,当测试任务结束后,您有责任使其失效。
## 范围文件
每个项目都有一个 YAML 文件,用于声明可以进行测试的内容:
```
program: example-bbp
platform: hackerone
in_scope:
hosts:
- example.com
- "*.example.com"
url_patterns: []
out_of_scope:
hosts:
- admin.example.com
path_patterns:
- "^/admin"
- "^/internal"
- "^/staging"
permissions:
active_idor_testing: false # automated identifier mutation
hidden_route_probing: true # wordlist-based route discovery
authenticated_scanning: false # use of --cookie / --auth-header
notes: |
Source:
Last verified: YYYY-MM-DD
```
初始模板位于 [`scopes/_template.yaml`](scopes/_template.yaml)。默认配置特意设定得很严格——只有在阅读了特定项目的具体规则后,才能启用主动行为。
## 本工具不包含的功能
- 不是漏洞扫描器。它只展示值得手动调查的候选项。它不会声称自己能够发现漏洞。
- 不是完全自动化的。每种主动行为都需要用户核实范围以及项目规则是否允许。
- 不可用于未经授权的测试。授权拦截机制的存在是为了保护用户和目标双方。在范围文件声明的范围主机之外运行扫描需要显式开启宽松模式,并且这属于您的法律责任。
- 不能替代对目标的理解。漏洞赏金猎人的核心工作是进行手动验证——该工具只是让候选列表变得更精简,让证据变得更干净。
## 路线图
近期计划:
- 扩展第三方噪音过滤器(Taboola、BidSwitch、Adobe Audience Manager、1rx.io 以及其他广告技术)
- 针对 `wait_until="commit"` 在 JS hydration 完成前就返回的网站,开发感知 SPA 的爬虫等待策略
- 已认证侦察助手:解析 HAR 文件,以发现爬虫无法通过链接提取到达的 XHR endpoint
中期计划:
- 为每个发现提供既有稳定性又对人类有意义的哈希值(而不仅仅是 `F-XXXXXX`)
- 为希望从纯净 IP 和共享工作区运行扫描的用户提供可选的托管扫描层
- 导入 Burp Suite 会话——从现有的 Burp 项目中提取身份验证上下文
## 项目状态与联系方式
GhostMap 是一个开源项目,采用 MIT 许可证。
由 Andrew Gonzaga ([andrewliera](https://github.com/andrewliera)) 开发——一名拥有嵌入式系统和 AppSec 背景的软件工程师。我目前承接 AppSec 咨询、安全工具开发相关的业务,也寻找全职安全工程相关的职位。请通过 andrew.lira.gonzaga@gmail.com 或访问 [gonzagatech.com](https://gonzagatech.com) 联系我。
如果 GhostMap 在您的实际测试任务中提供了帮助,我非常乐意听闻。如果它暴露了本应被过滤掉的误报,请带上具体的 URL 模式提交一个 issue。
## 许可证
MIT — 查看 [LICENSE](LICENSE)。
标签:Bug Bounty, Web安全, 主机安全, 可自定义解析器, 特征检测, 蓝队分析, 逆向工具