关于 bb-methodology
bb-methodology 是面向漏洞猎手的漏洞赏金与安全测试工作流技能,结合测试模式选择、目标导向测试和灵活的五阶段流程,指导侦察、映射、漏洞发现与验证。
主要功能
- 01按测试类型选择工作流
- 02设定会话目标与漏洞类别
- 03采用非线性的五阶段流程
- 04映射端点、角色与业务流程
- 05从批判性和多角度分析问题
- 06报告前验证发现
适用场景
- 01规划有明确目标的漏洞赏金测试
- 02选择符合红队或渗透测试范围的发现
- 03根据新线索在侦察与测试间切换
- 04提交报告前验证影响
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill bb-methodology安装后在 Claude Code 中输入/bb-methodology确认已加载。
详细介绍
漏洞赏金方法论:工作流 + 思维方式
用于漏洞挖掘会话的主编排器。将非线性的 5 阶段工作流与批判性思维框架相结合,帮助顶尖 1% 的猎手脱颖而出。
第 0 部分:确认模式(首先要做的事)
在判断什么算作发现之前,先确认参与类型。 同一个目标会因适用模式不同而产生不同形式的报告。在这个工作流中,搞错这一点是最大的时间浪费——请在第 0 阶段之前明确回答。
| 参与类型 | 什么算作发现 | 什么会被拒绝 |
|---|---|---|
| 漏洞赏金(H1 / Bugcrowd / Intigriti / 私有 VDP) | 仅限证明了影响的漏洞。完整利用链必须造成攻击者可实现的危害。 | 安全卫生问题(仅 EoL 软件、仅宽松的 CSP、堆栈跟踪、没有具体影响的信息披露、“最佳实践”违规) |
| 红队(外部客户参与) | 安全卫生问题、侦察、IoC 和防御状态观察都属于交付内容 | 无——即使是“此处未发现问题”,也可作为正面的防御观察报告 |
| 渗透测试(已签署的 SoW / WAPT) | 取决于 SoW。请明确阅读范围。通常接受安全卫生问题、影响和侦察结果 | 范围外资产、未经签署的测试 |
| 内部审计 | 与合规要求对应的发现(PCI / ISO / NIST / DPDPA / GDPR) | 未映射到控制项的发现 |
硬性规则: 在第 0 阶段开始前,把参与类型写在漏洞挖掘笔记的第一行。如果无法从用户的指示中判断,请询问一次。不要自行假设——这个错误会同时浪费你和分诊人员的时间。
一次授权参与的经验: 对此目标的初次排查发现了 5 个安全卫生问题(SP2013 EoL、宽松的 CSP、堆栈跟踪),并按红队格式提交。实际参与类型是漏洞赏金。这些发现会因“仅供参考,未证明影响”而被判定为 N/A。更正后重新排查,将安全卫生问题作为背景而非发现,同一目标最终找到了 11 个证明了影响的漏洞,其中包括 3 个严重漏洞。
第 1 部分:思维方式(如何思考)
核心原则
漏洞挖掘不是“找一个漏洞”,而是“证明一种攻击场景”。要像有明确目标的攻击者那样思考,而不是像寻找模式的扫描器那样思考。
每日纪律:定义、选择、执行
在执行任何命令之前:
- 定义:“今天我针对 [功能/领域],以实现 [CIA 影响]”
- 选择:选择 1–2 种漏洞类别(IDOR、竞态条件等)
- 执行:只专注于所选技术,不要偏离方向。
5 个终极目标(每次会话选择一个)
- 机密性——窃取攻击者不应看到的数据
- 完整性——修改攻击者不应更改的数据
- 可用性——干扰服务(仅限应用层 DoS)
- 账户接管——控制其他用户的账户
- RCE——在服务器上执行命令
4 个思考领域
1. 批判性思维(深入分析)
质疑信任边界:
- 前端控制已禁用?通过代理直接发送请求
user_role=usercookie?改为admin- POST 中的
price=1000?改为1 <script>被拦截?尝试<img onerror=...>
逆向分析开发者的思维方式:
- 功能 A 有身份验证检查 → 类似的功能 B(新添加)可能没有
- 复杂流程(优惠券 + 积分 + 退款)→ 边缘情况容易存在漏洞
- 存在
/api/v2/user→/api/v1/user是否仍以较弱的身份验证方式运行?
假设情景实验:
- 跳过结账 → 直接访问
/checkout/success - 跳过 2FA → 导航到
/dashboard - 同时发送 10 次优惠券请求 → 是否存在竞态条件?
- 在同级端点上将
guid=f8a2...替换为id=100→ 是否存在 IDOR?
2. 多角度思考(多个视角)
| 视角 | 检查内容 |
|---|---|
| 水平(相同角色) | 用户 A 的令牌 + 用户 B 的 ID -> IDOR |
| 垂直(不同角色) | 普通用户 -> /admin/deleteUser |
| 数据流(代理视角) | JSON 中的隐藏参数:debug=false、discount_rate |
| 时间/状态 | 竞态条件、删除后重用会话 |
| 客户端环境 | 移动端 UA -> 使用身份验证较弱的旧版 API |
| 业务影响 | “如果这里出问题,会造成多少美元的损失?” |
3. 战术思维(模式检测)
- 命名异常:到处都是
userId,却突然出现user_id-> 开发人员不同,安全性较弱 - 错误差异:相同的 403,但 JSON 结构不同 -> 后端系统不同
- 环境差异:生产环境与开发/预发布环境 -> 调试标头、CSP 已禁用
- 版本差异:更新前后的 JS 文件 -> 新端点、已移除的参数
- 供应链:检查框架/库的版本是否存在已知 CVE
- 第三方集成:Stripe/Auth0/Intercom -> 是否缺少 webhook 签名?
4. 战略思维(全局视角)
- 不对称性:防御者必须修补所有漏洞。你只需要一个。
- 直觉训练:记录某件事“感觉不对劲”的原因。之后再验证。更新思维数据库。
- 未知事项管理:有些东西无法理解?将其加入“稍后调查”列表。即时学习。
新手与专业人士:7 阶段对比
| 阶段 | 新手 | 专业人士 |
|---|---|---|
| 侦察 | 只看主域名 | 影子 IT、开发环境、所有资产 |
| 发现 | 寻找错误 | 寻找设计矛盾、业务逻辑缺陷 |
| 利用 | 受阻时放弃 | 构造过滤器绕过载荷 |
| 升级 | 只报告现象 | 将问题串联成实际危害(会话窃取、ATO) |
| 可行性 | 包含不现实的条件 | 尽量减少攻击前提 |
| 报告 | 只陈述事实 | 量化业务风险 |
| 复测 | 检查旧 PoC 是否失效 | 分析修复方法,寻找不完整的修补 |
两种方法路径
- 路径 A(基于功能):“这个功能很复杂” -> 深入检查其输入处理 -> 发现漏洞
- 路径 B(基于漏洞):“我想找 IDOR” -> 寻找具有连续 ID 的端点 -> 测试访问控制
反模式(不要再这样做)
- 频繁切换项目:至少专注于一个目标 2 周/30 小时
- 只用工具狩猎:自动化会找到重复问题。手动测试才能发现独特漏洞。
- 钻牛角尖:每个参数最多花 45 分钟。设定计时器。如果卡住了,先睡一觉再想。
- 没有目标:“只是随便看看” = 浪费时间。务必先定义目标。
注意事项
- 模式混淆 — 将漏洞赏金项目当作红队演练,会浪费时间在那些最终被标记为 N/A 的安全卫生问题上。开始任何侦察前,先确认项目类型(PART 0)。
- 标记不唯一 — 使用
test、marker或javascript作为测试字符串会触发误报。始终使用长度至少为 8 个字符的随机字母数字标记,并与基线进行核验。 - 仅凭状态码声称绕过成功 — 200 OK,但响应正文逐字节相同,并不代表绕过成功。声称成功前,始终对比响应正文。
- 根据单次样本得出时间结论 — 一次 2 倍异常是网络抖动,不是有效信号。基于时间的结论至少需要进行 10 次交错试验,且达到 2σ 阈值。
- 超过 5 次迭代时使用 Shell 循环 — zsh 数组展开可能会悄无声息地导致循环执行 0 次。只要循环要遍历列表、文件或计算得出的范围,就使用带有 try/except 的 Python。
- 假设阶段是线性的 — 5 阶段流程并非线性流程。第 3 阶段发现的新 API,需要返回第 2 阶段进行映射。第 4 阶段遭遇 WAF 拦截,需要返回第 1 阶段进行源 IP 侦察。
- 违反 20 分钟规则 — 在单个端点上超过 20 分钟仍无进展,会浪费本次会话时间。轮换目标:端点 → 子域名 → 漏洞类别 → 目标。
- 忽视 A→B 信号 — 发现一个漏洞,意味着同一开发人员很可能在附近犯过其他错误。确认发现后,务必花 20 分钟寻找同类问题。
- 先写报告,后做验证 — 未确认漏洞仍可复现就撰写报告,会因撤回发现而浪费数小时。提交前几分钟务必重新测试。
- 过早反驳 — 用户说“再多找一些”时,通常是对的。声称覆盖完整前,先完成另外 3 份 hunt-* 技能清单。
- 在无效候选上耗费 45 分钟 — 如果经过 4 小时以上后,某项发现仍无法在第二个账户上复现,就记录撤回原因并继续。不要再花时间让它奏效。
第 2 部分:工作流(要做什么)
5 阶段非线性流程
+-------------------------------------------------+
| |
| +----------+ +----------+ +----------+ |
| | 1. RECON |---+| 2. MAP |---+| 3. FIND | |
| +----------+ +-----+----+ +-----+-----+ |
| ^ | | |
| | v v |
| | +----------+ +----------+ |
| +----------| 4. PROVE |---+| 5. REPORT| |
| +----------+ +----------+ |
| |
| Non-linear: stuck at any phase -> go back |
| New API found at phase 3 -> return to phase 2 |
| WAF blocks at phase 4 -> origin IP from phase 1 |
+-------------------------------------------------+
这不是线性流程。 可以在各阶段之间自由切换。遇到阻碍时,返回之前的阶段。
第 0 阶段:会话开始(每次都要)
执行任何命令前,先回答以下问题:
- 定义:“今天,我的目标是 [功能/域名],以实现 [C/I/A/ATO/RCE]”
- 选择:选择 1–2 类漏洞(IDOR、XSS、SSRF 等)
- 执行:只专注于已选技术
选择路线——广度还是深度?
| 信号 | 广度(侦察扫描) | 深度(定向测试) |
|---|---|---|
| 新项目,第一天 | X | |
通配符范围 *.target.com | X | |
| 已在主 Web 应用上工作超过 3 天 | X | |
| 范围更新(新增域名) | X | |
| 发现有趣的子域名 | X |
第 1 阶段:侦察
目标:最大化攻击面,找到他人遗漏之处。
广度方法(初始扫描):
Subdomain enum -> DNS resolution -> HTTP probing -> Port scan -> Tech detect
深度方法(定向测试):
Google Dorks -> JS file download -> Hidden param discovery -> API mapping
| 发现内容 | 后续操作 |
|---|---|
| 存活的子域名及其技术栈 | 第 2 阶段(映射) |
| 已知软件(WordPress、Jira) | 立即检查 CVE 和默认配置 |
| 云资源(S3、Firebase) | 测试权限(读取/写入/列举) |
| 在某主机上探测 5 分钟仍一无所获 | 跳过,尝试下一台主机(5 分钟规则) |
命令:/recon target.com
阶段 2:映射与分析
目标:像开发者一样了解应用。
检查清单:
- 映射所有端点(Burp/Caido 站点地图 + JS 分析)
- 确认身份验证模型(Cookie、JWT、OAuth、SAML?)
- 找出业务关键流程(付款、注册、密码重置、数据导出)
- 下载并分析 JS 文件,查找隐藏路由、机密信息和逻辑
- 确认角色和权限(用户、管理员、API 密钥)
- 记录“异常”行为(命名、错误、时序方面的异常)
| 发现内容 | 后续操作 |
|---|---|
| 含有有趣代码的 JS 文件 | 污点分析(Sink -> Source) |
| OAuth/SAML 身份验证 | OAuth/SAML 检查清单 |
| 含有 ID 参数的 API | 阶段 3,重点测试 IDOR |
| 复杂业务逻辑(付款、优惠券) | 阶段 3,重点测试业务逻辑 |
| postMessage 监听器 | DOM 分析、postMessage-tracker |
阶段 3:发现漏洞
目标:找到漏洞。先使用基于错误的方法,再使用盲测方法。
根据测试目标选择的流程:
What input are you testing?
+-- ID parameter (user_id, order_id)
| -> IDOR checklist
+-- Search/filter/sort field
| -> SQLi, NoSQLi probing
+-- URL input / webhook / PDF gen
| -> SSRF checklist
+-- Text field reflected in page
| -> XSS (DOM or reflected)
+-- File upload
| -> SVG XSS, web shell, path traversal
+-- Price/quantity/coupon
| -> Business logic, race conditions
+-- Login / 2FA / password reset
| -> Auth bypass
+-- Profile update API
| -> Mass Assignment
+-- Template / wiki editor
| -> SSTI
+-- Nothing obvious
-> Fuzz with ffuf, try Error-based probing
错误与盲测的选择:
- 先尝试基于错误的方法(发送
'、"、{{7*7}}、${7*7})——留意 500 错误和堆栈跟踪 - 没有错误?尝试基于时间的方法(
SLEEP(10)、; sleep 10;)——留意响应时间 - 时间无差异?尝试 OOB(
curl attacker.com、interactsh)——留意 DNS 回调 - 还是没有?尝试布尔方法(
AND 1=1与AND 1=0)——留意内容长度差异
| 发现内容 | 后续操作 |
|---|---|
| 低影响行为(重定向、自我 XSS、Cookie 注入) | 将其串联起来——寻找可连接的利用组件 |
| 已确认的漏洞(XSS、IDOR、SQLi) | 阶段 4(证明影响并提升影响级别) |
| 被 WAF/CSP/403 阻止 | 使用绕过技术,然后重试 |
| 已知软件漏洞(CVE) | 使用 1-day 快速工作流 |
| 在此端点测试 20 分钟后仍无发现 | 切换目标(20 分钟规则) |
阶段 4:证明影响并提升影响级别
目标:证明最大的业务影响。将低影响漏洞提升到严重级别。
升级决策:
What did you find?
+-- XSS
| +-- Can steal cookie/token? -> Session hijack -> ATO
| +-- Cookie is HttpOnly? -> Force email change via XHR -> ATO
| +-- Self-XSS only? -> Find CSRF to trigger it
+-- IDOR
| +-- Can read PII? -> Automate scraping, show scale
| +-- Can change password/email? -> Direct ATO
| +-- UUID only? -> Find UUID leak source, then retry
+-- SSRF
| +-- DNS only? -> DON'T REPORT. Try cloud metadata
| +-- Can reach [REDACTED_IP]? -> Extract keys -> RCE
| +-- Internal port scan? -> Find Redis/K8s -> RCE
+-- SQLi
| +-- Error-based? -> Extract data (passwords, tokens)
| +-- Can INTO OUTFILE? -> Web shell -> RCE
| +-- Blind? -> Boolean/Time extraction
+-- Open Redirect
| +-- OAuth flow? -> Token theft -> ATO
| +-- javascript: scheme? -> XSS
+-- Blocked by defense
| -> Bypass (WAF/CSP/proxy/sanitizer/2FA)
+-- Low-impact, can't escalate alone
-> Find connector gadget for chain
证明影响后,检查:
- 攻击是否只需 0-1 次点击即可奏效?(尽量减少前置条件)
- 影响的是所有用户还是特定角色?
- 业务经济影响有多大?
阶段 5:验证并报告
目标:获得报酬,让分诊人员的工作更轻松。
报告前检查:
Run /validate (7-Question Gate)
+-- All 7 pass? -> Write report
+-- Any fail? -> KILL the finding. Don't waste time.
+-- Borderline? -> Run /triage for quick go/no-go
多工具复现要求(仅限严重 / 高危):
将发现标记为严重或高危之前,必须使用至少两种独立工具复现(采用不同的技术栈和 HTTP 库)。跨工具结果一致,才能排除命令行产生的伪影(例如,仅在 curl 中出现的时序差异在 Python requests 中消失,这属于伪影而非漏洞)。
独立复现示例:
curl+ Burpsend_http1_request(TLS 技术栈不同,标头规范化方式也不同)- Python
requests+ 通过ssl.wrap_socket使用原始套接字(一个库会规范化,另一个不会) - Burp Repeater + Python
urllib(预期两者在线路上的结果一致)
报告中的复现命令必须可直接粘贴到 Shell 中执行——分诊人员会原样复制。若 curl 版本需要特殊标志,或在某些系统上无法运行,请提供 Python 替代方案。
**授权测试中的经验:**三个严重级别的发现(Authentication.asmx 暴力破解、TE.CL 请求走私、NTLM Type-2 信息泄露)均分别通过 curl + Python 原始套接字 + Burp 命令行独立复现。跨工具的一致性说服了分诊人员相信这些发现并非伪影。
报告:
Run /report
+-- Platform-specific format (H1/Bugcrowd/Intigriti/Immunefi)
+-- Title: [Bug Class] in [Endpoint] allows [role] to [impact]
+-- Impact-first summary (sentence 1 = what attacker CAN do)
+-- Exact HTTP requests in Steps to Reproduce
+-- Under 600 words
+-- CVSS 3.1 score that MATCHES actual impact
提交后:
- 等待分诊期间:尝试进一步提升影响级别(A->B 信号法)
- 如果已部署修复:重新测试是否可绕过(不完整的补丁就是新漏洞)
- 使用
/remember记录发现,以便保存到狩猎记忆中
第 3 部分:导航与时机
非线性导航速查
| 我卡在这里,因为…… | 前往…… |
|---|---|
| 找不到任何子域名 | 阶段 1:尝试不同的侦察来源、Google Dorks |
| 找到了子域名,但不知道该测试什么 | 阶段 2:梳理应用、下载 JS、了解身份验证 |
| 正在测试,但毫无进展 | 阶段 3:切换漏洞类别(20 分钟轮换规则) |
| 找到了漏洞,但影响较低 | 阶段 4:尝试提升影响的路径或利用链 |
| WAF/CSP/403 阻止了我的载荷 | 尝试绕过技术,然后回到当前阶段 |
| 在一个参数上卡了 45 分钟 | 停下。这是死胡同。转到下一个端点。 |
| 测试期间发现了新的 API 端点 | 返回阶段 2:先梳理,再发起攻击 |
| 找到了一个漏洞 | A->B 信号:同一位开发者还犯了其他错误。花 20 分钟寻找同类问题。 |
20 分钟轮换计时
每隔 20 分钟问问自己:“我有进展吗?”
- 有 -> 继续
- 没有 -> 切换到下一个:端点 -> 子域名 -> 漏洞类别 -> 目标
- 在同一个目标上花了 2 周以上却毫无发现? -> 考虑切换项目
反驳处理流程(用户说“再多找一些”时)
当用户不同意你的停止时机时,例如:“我找到了 10 多个漏洞,你也应该找到一样多”“再仔细找找”或“你漏掉了一些东西”:
默认假设:用户是对的。你停得太早了。
在反驳并说“我认为已经查完了,因为 X”之前,请执行以下操作:
- 再阅读 3 个
hunt-*技能,查看你尚未加载的内容。选择与已观察到的攻击面相匹配的技能(例如,自定义登录 →hunt-auth-bypass;SOAP 端点 → 查找特定于该协议的技能;URL 参数 →hunt-ssrf)。 - 使用新技能的检查清单重新攻击同一攻击面。逐步完成新技能中的所有步骤,即使感觉重复也要照做。
- 边检查边记录否定结果——确认“这里没有漏洞”本身也是值得让用户看到的发现(这能证明覆盖范围)。
- 只有在完成 3 个新技能的检查清单后,才能提出反驳,而且只能列出具体测试过的内容。
**一次经授权的安全测试经验:**首次检查只发现了 5 个影响较低的问题,用户说:“我找到了 10 多个,再找找。”加载 hunt-auth-bypass 后(该技能之前虽已加载,却没有端到端地逐步执行),立即发现了 /_vti_bin/Authentication.asmx 这一旧版 SOAP 登录端点——这是此次安全测试中影响最大的漏洞。用户是对的;反驳只会是错的。
按阶段路由工具
| 阶段 | 工具 | 此顺序的原因 |
|---|---|---|
| 侦察:子域名 | subfinder -> amass -> puredns -> httpx | 先被动侦察(不触发检测)-> 解析 DNS -> 探测 HTTP 和技术栈 |
| 侦察:URL | gau + waymore -> katana -> uro | 先查存档(找出被遗忘的端点)-> 主动爬取(渲染 JS)-> 去重 |
| 侦察:JS | jsluice + mantra + trufflehog --only-verified | 提取 URL/密钥 -> 查找 API 密钥 -> 验证密钥是否实际可用 |
| 侦察:端口 | naabu(广泛扫描)-> rustscan(深度扫描) | 快速扫描前 1000 个端口 -> 对有价值的目标扫描全部 65535 个端口 |
| 侦察:扫描 | nuclei -tags cve -> nuclei -tags takeover | 先查已知 CVE -> 再查接管问题(立即处理) |
| 映射:参数 | arjun + paramspider + ParamMiner | 暴力枚举隐藏参数 + 挖掘存档 + 检查缓存标头 |
| 映射:JS 代码 | 下载 -> jsluice -> 在 VS Code/Cursor 中 grep | 提取 -> 静态分析 -> AI 辅助污点分析 |
| 映射:搜索语法 | 手动使用 Google Dorks | 针对每个目标定制查询,找出自动化工具遗漏的内容 |
| 发现:模糊测试 | ffuf -ac + cewl 自定义词表 | 自动校准过滤规则 + 针对目标定制的词语优于通用列表 |
| 发现:XSS | kxss -> dalfox | 先过滤(哪些参数会反射?)-> 再扫描(仅扫描会反射的参数) |
| 发现:SQLi | ghauri | 针对类似 ID 的参数进行现代盲注 SQLi 测试 |
| 发现:SSRF | interactsh-client | 用于盲 SSRF/XXE/RCE 的可自托管带外监听器 |
| 发现:WAF | wafw00f -> whatwaf | 识别 WAF 供应商 -> 测试绕过技术 |
| 利用:403 | byp4xx 或 nomore403 | 自动化执行 20 多种绕过技术 |
| 利用:接管 | subzy | 检查 CNAME 是否指向 70 多种易受攻击的服务 |
| 利用:云 | s3scanner + aws CLI | 扫描存储桶权限 -> 提取元数据凭证 |
| 利用:密钥 | trufflehog --only-verified | 仅保留经验证可用的密钥(无误报) |
会话结束检查清单
- 保存所有 Burp/Caido 项目文件
- 记录任何“奇怪但尚不可利用”的行为(未来可用的攻击入口)
- 更新笔记,记录失败的尝试(不要用相同技术重复测试)
- 使用
/remember记录发现
第 4 部分:方法纪律(防止误报)
大多数撤回的发现都源于四种反复出现的流程错误。每种错误都有一条硬性规则。
重要说明: 这些纪律规则关乎发现的正确性,而不是限制投入。它们告诉你哪些信号是真正的发现,哪些不是。它们并不是让你减少探测次数。如果你发现自己用这些规则作为提前停止的理由,那就是理解错了——加载
redteam-mindset(DO NOT STOP 首要指令)并继续。覆盖范围纪律与发现正确性纪律是相互独立的两个方面;两者都必须全面落实。
标记规范
测试反射、缓存投毒、参数污染或 OOB SSRF 时,注入的标记字符串必须唯一且醒目。
规则:
- 标记应为随机字母数字字符串,至少 8 个字符,不包含英文单词或协议关键词。
- 切勿使用
test、marker、evil、attacker、payload、javascript、script、AAAA、BBBB、你的域名,或任何可能自然出现在目标 HTML/JS/错误消息中的字符串。 - 好的标记:
cpmark987abc、x4hd2k9pq、类似dlsrcurl.<collab>.oastify.com的 Collaborator 子域名前缀,或__ZZ_MARKER_<random>_ZZ__。 - 声称发现反射前:在基线(不含标记)响应中搜索标记字符串。如果它自然出现,请更换标记。这项单一检查可发现 80% 的反射误报。
- 进行 OOB 测试时,为每个 Collaborator 负载添加不同的子标签(例如
dlsrcurl.<collab>、authsrc.<collab>),以便回调能识别触发的具体接收点。
**一次经授权的测试经历:**初始扫描报告称 X-Forwarded-Proto: javascript 会反射到多个 SharePoint 页面中。所谓的“反射”其实是 SP 帮助链接的 href 中自然出现了字面字符串 javascript(href="javascript:HelpWindowKey(...)")。这是由标记不唯一导致的误报。
响应正文差异规则
要声称绕过,必须有响应正文差异,而不只是状态码差异。
规则:
- 如果 200 OK 的正文与基线逐字节相同,就不算绕过。
- 如果 200 OK 的正文有 5 个字节的差异,也许算——请确认具体变化是什么(关联 ID?时间戳?实际内容?)。
- 声称绕过前,务必并排比较正文差异:
diff <(curl ... baseline) <(curl ... bypass)。 - 仅依据状态码的说法(例如“Host 头 X 返回 200,而不是 403”)是 Bug Bounty 平台上最常被驳回为 N/A 的类别。
一次经授权的测试经历:Host: target.example:[email protected] 返回了 HTTP 200,而基线返回 403。看起来像是 Host 头绕过。但正文逐字节相同(两者均为 8341 字节)——AWS ELB 将 Host 规范化为 target.example:80,丢弃了 @evil 部分。这并非绕过。
统计样本规则(适用于基于时间的说法)
单个离群值不是信号。网络抖动经常会产生 2 倍的离群值。
针对任何用户枚举 / 盲 SQLi / 盲 NoSQLi / 计时侧信道的说法,规则如下:
- 最小样本量:每组至少 n ≥ 10 次交错试验(对照组 + 测试组,随机排序,不能连续测试)。
- 计算每组的均值、中位数和 σ。
- 只有当可疑组的均值至少比对照组均值高 2σ 时,才算存在信号。
- n=1 测试中单个 2 倍离群值是网络抖动,不是信号。
**一次经授权的测试经历:**单次探测显示,Authentication.asmx Login 上 Administrator 的响应耗时为 1527 ms,而对照组约为 700 ms——看起来明显存在用户枚举信号。随后在 8 组中进行了 n=80 次交错试验,结果各组的均值都降至 685-716 ms,σ 为 25-74 ms。1527 ms 是网络抖动造成的。该发现已撤回。
Shell 循环禁令(>5 次迭代)
对于运行超过 5 次的任何迭代,请使用 Python(每次迭代都使用 try/except),不要使用 shell for 循环。
原因: zsh 数组展开在边缘情况下会静默失败。如果数组未由前一条命令填充,像 for x in "${arr[@]}" 这样的循环可能会执行 0 次,且不会报错。用户看到的输出看起来完整,实际上测试完全被跳过了。
规则:
- 在 shell 中循环处理 ≤5 个硬编码项:可以。
- 任何迭代列表、文件或计算范围的操作:使用 Python。
- 始终统计结果。如果预期有 100 次探测,但输出少于 50 行,说明循环吞掉了结果。
一次经授权的测试行动带来的教训: 一项 zsh 数组迭代动词篡改测试在 20 多次迭代中静默地没有执行任何 curl 调用(zsh 吞掉了数组)。输出看起来像是对每次探测都重复显示“HIT [GET] /_api/web → ”,但实际响应缺失。约 50 次探测的测试就这样丢失了。将测试切换到 Python,并为每次迭代显式记录日志后,才显示出真实结果。
验证
运行此自测,以确认方法论的质量门槛正常运作:
-
标记唯一性测试 — 确认基线检查能捕获假阳性:
echo "<a href='javascript:HelpWindowKey(1)'>Help</a>" > /tmp/test-baseline.html MARKER="javascript" grep -q "$MARKER" /tmp/test-baseline.html && echo "FAIL: marker appears in baseline — choose unique marker" || echo "PASS: marker is unique" rm -f /tmp/test-baseline.html -
正文差异测试 — 验证差异检查能捕获字节完全相同的响应:
echo "identical body" > /tmp/a.txt && cp /tmp/a.txt /tmp/b.txt diff /tmp/a.txt /tmp/b.txt >/dev/null && echo "PASS: identical bodies detected (no bypass)" || echo "FAIL: diff broken" rm -f /tmp/a.txt /tmp/b.txt -
统计抽样测试 — 验证 Python 可以计算均值/σ:
python3 -c " import statistics control = [700, 710, 690, 705, 715, 698, 702, 708, 695, 712] mean_c = statistics.mean(control) stdev_c = statistics.stdev(control) threshold = mean_c + 2*stdev_c suspect = 1527 print('PASS: signal detected' if suspect > threshold else 'PASS: no false signal (correct)') " 2>/dev/null || echo "FAIL: Python3 statistics module unavailable" -
Shell 循环禁令验证 — 确认 Python 迭代可靠运行:
python3 -c " items = ['a','b','c','d','e','f','g','h','i','j'] results = [] for item in items: results.append(f'processed:{item}') expected = 10 actual = len(results) print(f'PASS: {actual}/{expected} items processed' if actual == expected else f'FAIL: {actual}/{expected}') " 2>/dev/null || echo "FAIL: Python3 unavailable" -
模式确认检查 — 验证你理解了测试行动类型决策框架:
grep -q "PART 0" SKILL.md && echo "PASS: PART 0 mode-confirmation present" || echo "FAIL: PART 0 missing"
如果 5 项测试全部通过,则可以验证方法论纪律规则。测试 1-2 是真实测试行动中最常见的假阳性来源。
相关技能与链路
hunt-dispatch— 当 PART 0 模式得到确认时(redteam / wapt + blackbox|greybox)。工作流基元:测试行动类型的答案确定后,将任务交给hunt-dispatch,以识别目标特征并加载匹配的平台与 hunt-* 技能集;当 dispatch 输出其分类体系后,本技能不再是当前活动上下文。bug-bounty— 当用户笼统地询问“我该做什么”,或开始测试新目标时。工作流基元:bug-bounty是负责按主题指定要加载哪些hunt-*技能的协调器;本技能(bb-methodology)提供协调器运行时采用的 5 阶段工作流。triage-validation— 当发现问题完成第 4 阶段、即将撰写报告时。工作流基元:第 5 阶段明确调用/validate(7 问门槛);只有通过全部 7 个问题的发现问题才会交给report-writing。offensive-osint+web2-recon— 当第 1 阶段(侦察)处于活动状态时。工作流基元:第 1 阶段的“广泛方法”会将资产工具集工作交给offensive-osint,并将在线主机 + URL 流程交给web2-recon。
操作人员须知
根据测试行动经验,对引入的基础内容所作的补充。来自真实的 授权测试行动,以及本仓库 31+ 个技能领域的在线测试中进行的第 2 阶段 验证。上游方法论涵盖了 WHAT;本层则涵盖 WHEN-IT-ACTUALLY-WORKS 和 FAILURE-MODES。
方法论未提及的内容
引入的 5 阶段工作流是一份检查清单;真实测试行动需要随机应变。有时你会完全跳过某些阶段——客户交给你一个 URL 和一个 JWT,他们的内部团队已完成侦察,第 1 阶段就缩短为 10 分钟的特征识别。有时你会把 80% 的测试行动时间花在第 1 阶段,因为范围涉及一家拥有 200 项资产的金融服务母公司,而资产发现本身就是任务。方法论描绘的是每次测试行动中都存在的地形,而不是一套需要均匀执行的步骤。
实际中的模式确认
第 0 部分(本文件开头的漏洞赏金与 WAPT、红队模式判定)是硬性规则,但答案并不总是摆在眼前。请仔细阅读范围说明:
- “范围内资产” + “范围外资产” + “安全港” → 漏洞赏金规范。以验证为重,必须进行 OOB 验证,不得窃取数据。
- “攻击链” + “目标” + “夺旗” + “对手模拟” → 红队。隐蔽性、持久化、横向移动均属有效手段。
- “合规” + “PCI” + “HIPAA” + “高管报告” + “修复时间线” → WAPT。以覆盖率为导向,以交付物为核心,无论能否利用,所有发现都计入。
当措辞混杂时(这种情况很常见——客户经常编写 WAPT 风格的工作说明书,却称之为红队行动),在确认之前,默认采用漏洞赏金规范。这是验证要求最严格的模式;客户确认属于红队后,随时可以放宽。反过来——误以为可以按红队方式自由操作,结果实际是 WAPT——会导致交付时撤回发现。
不同目标类型的阶段优先级调整
5 个阶段的权重并不相同。行动类型决定时间分配:
| 行动类型 | 侦察 | 搜寻 | 验证与报告 |
|---|---|---|---|
| SaaS 漏洞赏金(范围明确) | 10% | 70% | 20% |
| 外部红队(范围广) | 40% | 30% | 30% |
| WAPT(已提供资产清单) | 0% | 60% | 40% |
| 企业本地部署(单一产品) | 5% | 50% | 45% |
如果你把 SaaS 漏洞赏金行动 50% 的时间都花在侦察上,那就是在拖延搜寻。如果你只把外部红队行动 10% 的时间花在侦察上,那就已经输了——在这类行动中,攻击面图谱本身就是交付物。
何时打破方法论
如果在侦察的前 30 分钟内发现一个严重级别为 Critical 的问题,**立即停止侦察,彻底验证该问题,报告后再继续侦察。**方法论要求“完成当前阶段后再进入下一阶段”,但按小时计算的价值曲线并不认同。行动开始后 24 小时内确认并报告的 Critical,价值高于一份你最终根本无暇利用的完整资产清单。
反过来也一样:如果你已经搜寻某个候选问题 4 小时以上,而它在第二个账户上无法复现,那这个候选问题就不成立。不要再花 4 小时试图让一个无法成立的候选问题复现。放弃它,在笔记中记录撤回原因,然后继续。
纪律规则不可妥协
本文件中的纪律规则——OOB Gate、Marker Discipline、Body-Diff Rule、Statistical-Sample Rule、Server-Policy-vs-State、Pre-Severity Gate、Shell-Loop Ban——不是方法论,而是质量门槛。方法论规定操作顺序;这些规则则保障每一步的验证质量。
在 Phase 2D 的强化实验室行动中,这些规则均已验证:面对伪装成漏洞的行为,8/8 条纪律规则都能正确触发(伪装成 XSS 的 URL 回显、伪装成反射的词语碰撞、响应体字节完全相同却仅凭状态码声称“绕过”,以及没有实际泄露数据却声称 200-OK 数据泄露)。跳过这些规则时,验证通过率会急剧下降。摩擦感正是这些规则的作用——如果某条规则让人觉得碍事,那正说明它在发挥作用。它淘汰的那些发现,有一半最终无论如何都会被判定为 N/A。
evidence-hygiene— Phase 5 收集 PoC 截图 / HAR 时使用。工作流的基本步骤:在截图中出现任何 Cookie / PII 之前,将任务交给evidence-hygiene执行脱敏流程。