web2-recon
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWEB2 RECON PIPELINE
WEB2 侦察工作流
Full asset discovery from nothing to a prioritized URL list ready for hunting.
从无到有完成全资产发现,生成可用于漏洞挖掘的优先级URL列表。
SETUP (one-time)
环境配置(一次性操作)
bash
undefinedbash
undefined1. Set your Chaos API key (get free key at chaos.projectdiscovery.io)
1. 设置你的Chaos API密钥(可在chaos.projectdiscovery.io获取免费密钥)
export CHAOS_API_KEY="your-key-here"
export CHAOS_API_KEY="your-key-here"
Add to ~/.zshrc or ~/.bashrc for persistence:
将其添加到~/.zshrc或~/.bashrc以持久化配置:
echo 'export CHAOS_API_KEY="your-key-here"' >> ~/.zshrc
echo 'export CHAOS_API_KEY="your-key-here"' >> ~/.zshrc
2. Update nuclei templates (run weekly)
2. 更新nuclei模板(每周运行一次)
nuclei -update-templates
nuclei -update-templates
3. Configure subfinder with API keys for more sources
3. 为subfinder配置多源API密钥
mkdir -p ~/.config/subfinder
cat > ~/.config/subfinder/config.yaml << 'EOF'
mkdir -p ~/.config/subfinder
cat > ~/.config/subfinder/config.yaml << 'EOF'
Get free keys at: virustotal.com, securitytrails.com, censys.io, shodan.io
免费密钥获取地址:virustotal.com, securitytrails.com, censys.io, shodan.io
virustotal: [YOUR_VT_KEY]
securitytrails: [YOUR_ST_KEY]
censys_apiid: YOUR_CENSYS_ID
censys_secret: YOUR_CENSYS_SECRET
shodan: [YOUR_SHODAN_KEY]
EOF
virustotal: [YOUR_VT_KEY]
securitytrails: [YOUR_ST_KEY]
censys_apiid: YOUR_CENSYS_ID
censys_secret: YOUR_CENSYS_SECRET
shodan: [YOUR_SHODAN_KEY]
EOF
4. Verify all tools installed
4. 验证所有工具已安装
which subfinder httpx dnsx nuclei katana waybackurls gau dalfox ffuf anew gf interactsh-client
---which subfinder httpx dnsx nuclei katana waybackurls gau dalfox ffuf anew gf interactsh-client
---THE 5-MINUTE RULE
5分钟规则
If a target shows nothing interesting after 5 minutes of recon, move on. Don't burn hours on dead surface.
5-minute kill signals:
- All subdomains return 403 or static marketing pages
- No API endpoints visible in URLs
- No JavaScript bundles with interesting endpoint paths
- nuclei returns 0 medium/high findings
- No forms, no authentication, no user data
如果目标在5分钟侦察后未发现任何有价值内容,立即切换目标。不要在无攻击面的目标上浪费时间。
5分钟终止信号:
- 所有子域名返回403状态码或静态营销页面
- URL中无可见API端点
- JS包中无有价值的端点路径
- nuclei扫描未发现中/高危漏洞
- 无表单、无认证机制、无用户数据
STANDARD RECON PIPELINE
标准侦察工作流
Pre-Hunt: Always Run First
预挖掘:必须首先执行
bash
TARGET="target.com"bash
TARGET="target.com"Step 0: Passive — crt.sh certificate transparency (no API key needed)
步骤0:被动侦察 — crt.sh证书透明度(无需API密钥)
curl -s "https://crt.sh/?q=%.${TARGET}&output=json"
| jq -r '.[].name_value'
| sed 's/*.//g'
| sort -u > /tmp/subs.txt echo "[+] crt.sh: $(wc -l < /tmp/subs.txt) subdomains"
| jq -r '.[].name_value'
| sed 's/*.//g'
| sort -u > /tmp/subs.txt echo "[+] crt.sh: $(wc -l < /tmp/subs.txt) subdomains"
curl -s "https://crt.sh/?q=%.${TARGET}&output=json"
| jq -r '.[].name_value'
| sed 's/*.//g'
| sort -u > /tmp/subs.txt echo "[+] crt.sh: $(wc -l < /tmp/subs.txt) 个子域名"
| jq -r '.[].name_value'
| sed 's/*.//g'
| sort -u > /tmp/subs.txt echo "[+] crt.sh: $(wc -l < /tmp/subs.txt) 个子域名"
Step 1: Chaos API (ProjectDiscovery — most comprehensive source)
步骤1:Chaos API(ProjectDiscovery — 数据源最全面)
curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains"
-H "Authorization: $CHAOS_API_KEY"
| jq -r '.[]' >> /tmp/subs.txt
-H "Authorization: $CHAOS_API_KEY"
| jq -r '.[]' >> /tmp/subs.txt
echo "[+] Chaos returned $(wc -l < /tmp/subs.txt) subdomains"
curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains"
-H "Authorization: $CHAOS_API_KEY"
| jq -r '.[]' >> /tmp/subs.txt
-H "Authorization: $CHAOS_API_KEY"
| jq -r '.[]' >> /tmp/subs.txt
echo "[+] Chaos 返回 $(wc -l < /tmp/subs.txt) 个子域名"
Step 2: subfinder (passive multi-source)
步骤2:subfinder(多源被动侦察)
subfinder -d $TARGET -silent | anew /tmp/subs.txt
assetfinder --subs-only $TARGET | anew /tmp/subs.txt
echo "[+] Total subdomains after all sources: $(wc -l < /tmp/subs.txt)"
subfinder -d $TARGET -silent | anew /tmp/subs.txt
assetfinder --subs-only $TARGET | anew /tmp/subs.txt
echo "[+] 所有数据源汇总后子域名总数:$(wc -l < /tmp/subs.txt)"
Step 3: DNS resolution + live host check
步骤3:DNS解析 + 存活主机检测
cat /tmp/subs.txt | dnsx -silent | httpx -silent -status-code -title -tech-detect | tee /tmp/live.txt
echo "[+] Live hosts: $(wc -l < /tmp/live.txt)"
cat /tmp/subs.txt | dnsx -silent | httpx -silent -status-code -title -tech-detect | tee /tmp/live.txt
echo "[+] 存活主机数量:$(wc -l < /tmp/live.txt)"
Step 4: URL crawl
步骤4:URL爬取
cat /tmp/live.txt | awk '{print $1}' | katana -d 3 -jc -kf all -silent | anew /tmp/urls.txt
cat /tmp/live.txt | awk '{print $1}' | katana -d 3 -jc -kf all -silent | anew /tmp/urls.txt
Step 5: Historical URLs
步骤5:历史URL
echo $TARGET | waybackurls | anew /tmp/urls.txt
gau $TARGET --subs | anew /tmp/urls.txt
echo "[+] Total URLs: $(wc -l < /tmp/urls.txt)"
echo $TARGET | waybackurls | anew /tmp/urls.txt
gau $TARGET --subs | anew /tmp/urls.txt
echo "[+] URL总数:$(wc -l < /tmp/urls.txt)"
Step 6: Nuclei scan
步骤6:Nuclei扫描
nuclei -l /tmp/live.txt -t ~/nuclei-templates/ -severity critical,high,medium -o /tmp/nuclei.txt
undefinednuclei -l /tmp/live.txt -t ~/nuclei-templates/ -severity critical,high,medium -o /tmp/nuclei.txt
undefinedOutput to Organized Directory
输出到结构化目录
bash
TARGET="target.com"
RECON_DIR="recon/$TARGET"
mkdir -p $RECON_DIRbash
TARGET="target.com"
RECON_DIR="recon/$TARGET"
mkdir -p $RECON_DIRAll outputs go here:
所有输出文件将保存到此处:
/tmp/subs.txt → $RECON_DIR/subdomains.txt
/tmp/live.txt → $RECON_DIR/live-hosts.txt
/tmp/urls.txt → $RECON_DIR/urls.txt
/tmp/nuclei.txt → $RECON_DIR/nuclei.txt
---/tmp/subs.txt → $RECON_DIR/subdomains.txt
/tmp/live.txt → $RECON_DIR/live-hosts.txt
/tmp/urls.txt → $RECON_DIR/urls.txt
/tmp/nuclei.txt → $RECON_DIR/nuclei.txt
---ATTACK SURFACE TRIAGE
攻击面筛选
Find Interesting Targets in URL List
在URL列表中定位有价值目标
bash
undefinedbash
undefinedParameters worth testing
值得测试的参数
cat /tmp/urls.txt | grep -E "?&=" | tee /tmp/interesting-params.txt
cat /tmp/urls.txt | grep -E "?&=" | tee /tmp/interesting-params.txt
API endpoints
API端点
cat /tmp/urls.txt | grep -E "/api/|/v1/|/v2/|/v3/|/graphql|/rest/|/gql" | tee /tmp/api-endpoints.txt
cat /tmp/urls.txt | grep -E "/api/|/v1/|/v2/|/v3/|/graphql|/rest/|/gql" | tee /tmp/api-endpoints.txt
File upload endpoints
文件上传端点
cat /tmp/urls.txt | grep -E "upload|file|attachment|document|image|avatar|photo|media" | tee /tmp/uploads.txt
cat /tmp/urls.txt | grep -E "upload|file|attachment|document|image|avatar|photo|media" | tee /tmp/uploads.txt
Admin/internal paths
管理员/内部路径
cat /tmp/urls.txt | grep -E "/admin|/internal|/debug|/test|/staging|/dev|/management|/console" | tee /tmp/admin-paths.txt
cat /tmp/urls.txt | grep -E "/admin|/internal|/debug|/test|/staging|/dev|/management|/console" | tee /tmp/admin-paths.txt
Authentication endpoints
认证端点
cat /tmp/urls.txt | grep -E "/oauth|/login|/auth|/sso|/saml|/oidc|/callback|/token" | tee /tmp/auth-paths.txt
undefinedcat /tmp/urls.txt | grep -E "/oauth|/login|/auth|/sso|/saml|/oidc|/callback|/token" | tee /tmp/auth-paths.txt
undefinedgf Patterns (Quick Classification)
gf规则(快速分类)
bash
undefinedbash
undefinedInstall gf patterns: https://github.com/tomnomnom/gf
cat /tmp/urls.txt | gf xss | tee /tmp/xss-candidates.txt
cat /tmp/urls.txt | gf ssrf | tee /tmp/ssrf-candidates.txt
cat /tmp/urls.txt | gf idor | tee /tmp/idor-candidates.txt
cat /tmp/urls.txt | gf sqli | tee /tmp/sqli-candidates.txt
cat /tmp/urls.txt | gf redirect | tee /tmp/redirect-candidates.txt
cat /tmp/urls.txt | gf lfi | tee /tmp/lfi-candidates.txt
cat /tmp/urls.txt | gf rce | tee /tmp/rce-candidates.txt
---cat /tmp/urls.txt | gf xss | tee /tmp/xss-candidates.txt
cat /tmp/urls.txt | gf ssrf | tee /tmp/ssrf-candidates.txt
cat /tmp/urls.txt | gf idor | tee /tmp/idor-candidates.txt
cat /tmp/urls.txt | gf sqli | tee /tmp/sqli-candidates.txt
cat /tmp/urls.txt | gf redirect | tee /tmp/redirect-candidates.txt
cat /tmp/urls.txt | gf lfi | tee /tmp/lfi-candidates.txt
cat /tmp/urls.txt | gf rce | tee /tmp/rce-candidates.txt
---JS ANALYSIS
JS分析
SecretFinder (API keys, tokens in JS bundles)
SecretFinder(检测JS包中的API密钥、令牌)
bash
undefinedbash
undefinedActivate venv
激活虚拟环境
source ~/tools/SecretFinder/.venv/bin/activate
source ~/tools/SecretFinder/.venv/bin/activate
Scan a single JS file
扫描单个JS文件
python3 ~/tools/SecretFinder/SecretFinder.py -i "https://target.com/static/js/main.js" -o cli
python3 ~/tools/SecretFinder/SecretFinder.py -i "https://target.com/static/js/main.js" -o cli
Scan all JS URLs found in recon
扫描侦察过程中发现的所有JS URL
cat /tmp/urls.txt | grep ".js$" | head -50 | while read url; do
echo "=== $url ==="
python3 ~/tools/SecretFinder/SecretFinder.py -i "$url" -o cli 2>/dev/null
done
deactivate
undefinedcat /tmp/urls.txt | grep ".js$" | head -50 | while read url; do
echo "=== $url ==="
python3 ~/tools/SecretFinder/SecretFinder.py -i "$url" -o cli 2>/dev/null
done
deactivate
undefinedLinkFinder (Endpoints hidden in JS)
LinkFinder(发现JS中隐藏的端点)
bash
source ~/tools/LinkFinder/.venv/bin/activatebash
source ~/tools/LinkFinder/.venv/bin/activateSingle JS file
单个JS文件
python3 ~/tools/LinkFinder/linkfinder.py -i "https://target.com/app.js" -o cli
python3 ~/tools/LinkFinder/linkfinder.py -i "https://target.com/app.js" -o cli
All pages (crawls JS from HTML)
所有页面(从HTML中爬取JS)
DIRECTORY FUZZING
目录模糊测试
ffuf — Standard Fuzzing
ffuf — 标准模糊测试
bash
undefinedbash
undefinedDirectory discovery on a live host
对存活主机进行目录探测
ffuf -u "https://target.com/FUZZ"
-w ~/wordlists/common.txt
-mc 200,201,204,301,302,307,401,403
-ac
-t 40
-o /tmp/ffuf-dirs.json
-w ~/wordlists/common.txt
-mc 200,201,204,301,302,307,401,403
-ac
-t 40
-o /tmp/ffuf-dirs.json
ffuf -u "https://target.com/FUZZ"
-w ~/wordlists/common.txt
-mc 200,201,204,301,302,307,401,403
-ac
-t 40
-o /tmp/ffuf-dirs.json
-w ~/wordlists/common.txt
-mc 200,201,204,301,302,307,401,403
-ac
-t 40
-o /tmp/ffuf-dirs.json
API endpoint discovery
API端点探测
ffuf -u "https://target.com/api/FUZZ"
-w ~/wordlists/api-endpoints.txt
-mc 200,201,204,301,302
-ac
-t 20
-w ~/wordlists/api-endpoints.txt
-mc 200,201,204,301,302
-ac
-t 20
ffuf -u "https://target.com/api/FUZZ"
-w ~/wordlists/api-endpoints.txt
-mc 200,201,204,301,302
-ac
-t 20
-w ~/wordlists/api-endpoints.txt
-mc 200,201,204,301,302
-ac
-t 20
IDOR fuzzing with authenticated request
带认证请求的IDOR模糊测试
Create req.txt with Authorization: Bearer TOKEN
创建包含Authorization: Bearer TOKEN的req.txt文件
ffuf -request /tmp/req.txt
-request-proto https
-w <(seq 1 10000)
-fc 404
-ac
-t 10
-request-proto https
-w <(seq 1 10000)
-fc 404
-ac
-t 10
---ffuf -request /tmp/req.txt
-request-proto https
-w <(seq 1 10000)
-fc 404
-ac
-t 10
-request-proto https
-w <(seq 1 10000)
-fc 404
-ac
-t 10
---TARGET SCORING — GO / NO-GO
目标评分 — 执行/放弃
Score before spending time. Skip if score < 4.
| Criterion | Points |
|---|---|
| Max bounty >= $5K | +2 |
| Large user base (>100K) or handles money | +2 |
| Program launched < 60 days ago | +2 |
| Complex features: API, OAuth, file upload, GraphQL | +1 |
| Recent code/feature changes (GitHub, changelog) | +1 |
| Private program (less competition) | +1 |
| Tech stack you know | +1 |
| Source code available | +1 |
| Prior disclosed reports to study | +1 |
< 4: Skip
4-5: Only if nothing better available
6-8: Good — spend 1-3 days
>= 9: Excellent — spend up to 1 week
在投入时间前先评分。评分低于4分则跳过。
| 评估标准 | 分值 |
|---|---|
| 最高赏金≥5000美元 | +2 |
| 用户基数大(>10万)或涉及资金处理 | +2 |
| 项目启动时间<60天 | +2 |
| 具备复杂功能:API、OAuth、文件上传、GraphQL | +1 |
| 近期有代码/功能变更(GitHub、更新日志) | +1 |
| 私有项目(竞争较少) | +1 |
| 熟悉目标技术栈 | +1 |
| 源代码可获取 | +1 |
| 有已公开的报告可供参考 | +1 |
<4分: 跳过
4-5分: 仅在无更好目标时考虑
6-8分: 优质目标 — 投入1-3天
≥9分: 极佳目标 — 最多投入1周
Pre-Dive Hard Kill Signals
预挖掘终止信号
- Max bounty < $500 → not worth your time
- All recent reports are N/A or duplicate → hunters saturated it
- Scope is only a static marketing page → no attack surface
- Company < 5 employees with no revenue → won't pay
- Explicitly excludes your planned bug class in rules
- 最高赏金<500美元 → 不值得投入时间
- 近期报告均为无效或重复 → 已被其他挖掘者饱和
- 测试范围仅为静态营销页面 → 无攻击面
- 公司员工<5人且无营收 → 不会支付赏金
- 规则明确排除你计划测试的漏洞类型
TECH STACK DETECTION (2 min)
技术栈检测(2分钟)
bash
undefinedbash
undefinedResponse headers reveal backend
响应头可暴露后端信息
curl -sI https://target.com | grep -iE "server|x-powered-by|x-aspnet|x-runtime|x-generator"
curl -sI https://target.com | grep -iE "server|x-powered-by|x-aspnet|x-runtime|x-generator"
Common signals:
常见信号:
Server: nginx + X-Powered-By: PHP/7.4 → PHP backend
Server: nginx + X-Powered-By: PHP/7.4 → PHP后端
Server: gunicorn OR X-Powered-By: Express → Python/Node.js
Server: gunicorn OR X-Powered-By: Express → Python/Node.js
X-Powered-By: ASP.NET → .NET
X-Powered-By: ASP.NET → .NET
Server: Apache Tomcat → Java
Server: Apache Tomcat → Java
X-Runtime: Ruby → Ruby on Rails
X-Runtime: Ruby → Ruby on Rails
Framework from JS bundle paths:
从JS包路径识别框架:
/_next/static/ → Next.js
/_next/static/ → Next.js
/static/js/main.chunk.js → CRA (React)
/static/js/main.chunk.js → CRA(React)
/packs/ → Ruby on Rails + Webpacker
/packs/ → Ruby on Rails + Webpacker
/__nuxt/ → Nuxt.js (Vue)
/__nuxt/ → Nuxt.js(Vue)
undefinedundefinedStack → Primary Bug Class Map
技术栈 → 主要漏洞类型映射
| Stack | Hunt First | Hunt Second |
|---|---|---|
| Ruby on Rails | Mass assignment | IDOR ( |
| Django | IDOR (ModelViewSet, no object perms) | SSTI (mark_safe) |
| Flask | SSTI (render_template_string) | SSRF (requests lib) |
| Laravel | Mass assignment ($fillable) | IDOR (Eloquent, no ownership) |
| Express (Node.js) | Prototype pollution | Path traversal |
| Spring Boot | Actuator endpoints (/actuator/env) | SSTI (Thymeleaf) |
| ASP.NET | ViewState deserialization | Open redirect (ReturnUrl) |
| Next.js | SSRF via Server Actions | Open redirect via redirect() |
| GraphQL | Introspection → auth bypass on mutations | IDOR via node(id:) |
| WordPress | Plugin SQLi | REST API auth bypass |
| 技术栈 | 优先挖掘 | 次要挖掘 |
|---|---|---|
| Ruby on Rails | 批量赋值 | IDOR( |
| Django | IDOR(ModelViewSet,无对象权限) | SSTI(mark_safe) |
| Flask | SSTI(render_template_string) | SSRF(requests库) |
| Laravel | 批量赋值($fillable) | IDOR(Eloquent,无所有权验证) |
| Express(Node.js) | 原型污染 | 路径遍历 |
| Spring Boot | Actuator端点(/actuator/env) | SSTI(Thymeleaf) |
| ASP.NET | ViewState反序列化 | 开放重定向(ReturnUrl) |
| Next.js | Server Actions导致的SSRF | redirect()导致的开放重定向 |
| GraphQL | 自省→突变操作绕过认证 | node(id:)导致的IDOR |
| WordPress | 插件SQL注入 | REST API认证绕过 |
CONTINUOUS MONITORING SETUP
持续监控配置
Set up once per target. Alerts you before other hunters.
为每个目标配置一次,让你比其他挖掘者更早收到告警。
New Subdomain Alerts (daily cron)
新子域名告警(每日定时任务)
bash
#!/bin/bash
TARGET="target.com"
KNOWN="/tmp/$TARGET-subs-known.txt"
subfinder -d $TARGET -silent > /tmp/$TARGET-subs-fresh.txt
curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains" \
-H "Authorization: $CHAOS_API_KEY" \
| jq -r '.[]' >> /tmp/$TARGET-subs-fresh.txtbash
#!/bin/bash
TARGET="target.com"
KNOWN="/tmp/$TARGET-subs-known.txt"
subfinder -d $TARGET -silent > /tmp/$TARGET-subs-fresh.txt
curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains" \
-H "Authorization: $CHAOS_API_KEY" \
| jq -r '.[]' >> /tmp/$TARGET-subs-fresh.txtDiff against known
对比已知子域名
NEW=$(comm -23 <(sort /tmp/$TARGET-subs-fresh.txt) <(sort $KNOWN 2>/dev/null))
if [ -n "$NEW" ]; then
echo "NEW SUBDOMAINS: $NEW"
echo "$NEW" >> $KNOWN
fi
NEW=$(comm -23 <(sort /tmp/$TARGET-subs-fresh.txt) <(sort $KNOWN 2>/dev/null))
if [ -n "$NEW" ]; then
echo "新子域名:$NEW"
echo "$NEW" >> $KNOWN
fi
Schedule: crontab -e → 0 8 * * * /bin/bash ~/monitors/subs-watch.sh
定时配置:crontab -e → 0 8 * * * /bin/bash ~/monitors/subs-watch.sh
undefinedundefinedGitHub Commit Watch
GitHub提交监控
bash
#!/bin/bash
REPO="TargetOrg/target-app"
LAST_SHA="/tmp/$REPO-last-sha.txt"
CURRENT=$(curl -s "https://api.github.com/repos/$REPO/commits?per_page=1" | jq -r '.[0].sha')
KNOWN=$(cat $LAST_SHA 2>/dev/null)
if [ "$CURRENT" != "$KNOWN" ]; then
echo "New commit on $REPO: $CURRENT"
echo $CURRENT > $LAST_SHA
# Get changed files
curl -s "https://api.github.com/repos/$REPO/commits/$CURRENT" \
| jq -r '.files[].filename' | grep -E "auth|middleware|route|permission|role|admin"
fibash
#!/bin/bash
REPO="TargetOrg/target-app"
LAST_SHA="/tmp/$REPO-last-sha.txt"
CURRENT=$(curl -s "https://api.github.com/repos/$REPO/commits?per_page=1" | jq -r '.[0].sha')
KNOWN=$(cat $LAST_SHA 2>/dev/null)
if [ "$CURRENT" != "$KNOWN" ]; then
echo "$REPO有新提交:$CURRENT"
echo $CURRENT > $LAST_SHA
# 获取变更文件
curl -s "https://api.github.com/repos/$REPO/commits/$CURRENT" \
| jq -r '.files[].filename' | grep -E "auth|middleware|route|permission|role|admin"
fiSchedule: */30 * * * * /bin/bash ~/monitors/github-watch.sh
定时配置:*/30 * * * * /bin/bash ~/monitors/github-watch.sh
---
---PORT SCANNING (often skipped — don't skip)
端口扫描(常被忽略 — 请勿跳过)
bash
undefinedbash
undefinednaabu — fast port scanner from ProjectDiscovery
naabu — ProjectDiscovery出品的快速端口扫描器
Finds non-standard ports: 8080, 8443, 3000, 8888, 9000, etc.
发现非标准端口:8080、8443、3000、8888、9000等
cat /tmp/live.txt | awk '{print $1}' | naabu -port 80,443,8080,8443,3000,4000,5000,8000,8888,9000,9090,9200,6379 -silent | tee /tmp/open-ports.txt
cat /tmp/live.txt | awk '{print $1}' | naabu -port 80,443,8080,8443,3000,4000,5000,8000,8888,9000,9090,9200,6379 -silent | tee /tmp/open-ports.txt
Why this matters: admin panels, debug services, internal APIs often run on alt ports
重要性:管理面板、调试服务、内部API常运行在非标准端口
Example wins: :8080/actuator/env (Spring Boot), :9200/_cat/indices (Elasticsearch), :6379 (Redis)
案例::8080/actuator/env(Spring Boot)、:9200/_cat/indices(Elasticsearch)、:6379(Redis)
undefinedundefinedSECRET SCANNING IN JS BUNDLES
JS包中的密钥扫描
bash
undefinedbash
undefinedtrufflehog — high-signal secret detection with entropy analysis
trufflehog — 基于熵分析的高准确率密钥检测工具
Scans JS files and git repos
扫描JS文件和Git仓库
pip install trufflehog3 2>/dev/null || true
trufflehog filesystem --only-verified recon/$TARGET/ 2>/dev/null
pip install trufflehog3 2>/dev/null || true
trufflehog filesystem --only-verified recon/$TARGET/ 2>/dev/null
SecretFinder — manual JS bundle scan (already in tools/)
SecretFinder — 手动扫描JS包(已在工具集中)
source ~/tools/SecretFinder/.venv/bin/activate
cat /tmp/urls.txt | grep ".js$" | head -100 | while read url; do
python3 ~/tools/SecretFinder/SecretFinder.py -i "$url" -o cli 2>/dev/null
done
deactivate
source ~/tools/SecretFinder/.venv/bin/activate
cat /tmp/urls.txt | grep ".js$" | head -100 | while read url; do
python3 ~/tools/SecretFinder/SecretFinder.py -i "$url" -o cli 2>/dev/null
done
deactivate
Quick grep for common patterns in downloaded JS
快速 grep 下载的JS中的常见密钥模式
wget -q -r -l 1 -A "*.js" -P /tmp/js-files/ "https://$TARGET" 2>/dev/null
grep -rn "api_key|apiKey|client_secret|access_token|private_key|AWS_SECRET|AKIA" /tmp/js-files/ 2>/dev/null
undefinedwget -q -r -l 1 -A "*.js" -P /tmp/js-files/ "https://$TARGET" 2>/dev/null
grep -rn "api_key|apiKey|client_secret|access_token|private_key|AWS_SECRET|AKIA" /tmp/js-files/ 2>/dev/null
undefinedGITHUB DORKING FOR TARGET
目标的GitHub Dorking
bash
undefinedbash
undefinedSearch GitHub for hardcoded secrets before hunting the app
在挖掘应用前,先在GitHub上搜索硬编码密钥
TARGET_ORG="TargetOrgName" # Check their GitHub org
TARGET_ORG="TargetOrgName" # 确认目标的GitHub组织
Useful dorks (search on github.com):
实用Dorks(在github.com搜索):
org:TARGET_ORG password
org:TARGET_ORG password
org:TARGET_ORG api_key
org:TARGET_ORG api_key
org:TARGET_ORG "Authorization: Bearer"
org:TARGET_ORG "Authorization: Bearer"
org:TARGET_ORG .env
org:TARGET_ORG .env
org:TARGET_ORG "BEGIN RSA PRIVATE KEY"
org:TARGET_ORG "BEGIN RSA PRIVATE KEY"
CLI with gh (GitHub CLI):
使用GitHub CLI(gh)执行命令行搜索:
gh search code "api_key" --owner "$TARGET_ORG" --json path,repository 2>/dev/null | jq '.'
gh search code "password" --owner "$TARGET_ORG" --json path,repository 2>/dev/null | head -20
gh search code "api_key" --owner "$TARGET_ORG" --json path,repository 2>/dev/null | jq '.'
gh search code "password" --owner "$TARGET_ORG" --json path,repository 2>/dev/null | head -20
GitDorker (if installed):
如果已安装GitDorker:
python3 ~/tools/GitDorker/GitDorker.py -t GITHUB_TOKEN -d ~/tools/GitDorker/Dorks/alldorksv3 -q "$TARGET" -org
undefinedpython3 ~/tools/GitDorker/GitDorker.py -t GITHUB_TOKEN -d ~/tools/GitDorker/Dorks/alldorksv3 -q "$TARGET" -org
undefined30-MINUTE RECON PROTOCOL
30分钟侦察流程
Minutes 0-5: Read Program Page
0-5分钟:阅读项目页面
Note:
- ALL in-scope assets (every domain listed)
- Out-of-scope list (read carefully — common trap)
- Safe harbor statement
- Impact types accepted (some exclude "low")
- Average bounty amount (signals program generosity)注意:
- 所有测试范围内的资产(列出的每个域名)
- 测试范围外的列表(仔细阅读 — 常见陷阱)
- 安全港声明
- 接受的漏洞影响类型(部分排除"低危")
- 平均赏金金额(反映项目慷慨程度)Minutes 5-15: Asset Discovery
5-15分钟:资产发现
Run the standard pipeline above. Focus on live.txt output.
运行上述标准工作流,重点关注live.txt输出。
Minutes 15-25: Surface Map
15-25分钟:攻击面映射
Run gf patterns and the interesting-params grep above.
运行gf规则和上述interesting-params的grep命令。
Minutes 25-30: Manual Exploration
25-30分钟:手动探索
Open Burp Suite. Browse the app with proxy on:
- Register an account
- Perform main user actions (create/read/update/delete resources)
- Note all API calls in Burp history
- Look for endpoints not in your URL list
打开Burp Suite,开启代理浏览应用:
- 注册账号
- 执行主要用户操作(创建/读取/更新/删除资源)
- 在Burp历史中记录所有API调用
- 查找URL列表中未包含的端点
After 30 min: Prioritize
30分钟后:优先级排序
Priority 1: API endpoints with ID parameters → IDOR candidates
Priority 2: File upload features → XSS/RCE candidates
Priority 3: OAuth/SSO flows → auth bypass candidates
Priority 4: Search/filter with user input → SQLi/SSRF/SSTI candidates
Priority 5: Admin/debug endpoints → auth bypass candidates优先级1:带ID参数的API端点 → IDOR候选目标
优先级2:文件上传功能 → XSS/RCE候选目标
优先级3:OAuth/SSO流程 → 认证绕过候选目标
优先级4:含用户输入的搜索/过滤功能 → SQLi/SSRF/SSTI候选目标
优先级5:管理员/调试端点 → 认证绕过候选目标Toolchain fallback (when dnsx
/ httpx
crash)
dnsxhttpx工具链降级方案(当dnsx
/httpx
崩溃时)
dnsxhttpxThe projectdiscovery Go binaries (, , ) occasionally on macOS arm64 due to a cgo / system-resolver interaction. The crash signature is identical regardless of install method — both and produce binaries that segfault at the same address. Smoke-test once before relying on them in a real engagement:
dnsxhttpxnaabuSIGSEGVbrew installgo install github.com/projectdiscovery/<tool>@latestbash
dnsx -version # if SIGSEGV: use the dig fallback below
httpx -version # if SIGSEGV: use the curl fallback belowProjectDiscovery的Go二进制工具(、、)偶尔会在macOS arm64上因cgo/系统解析器交互问题触发崩溃。无论安装方式如何(或),崩溃特征一致。在正式侦察前先进行冒烟测试:
dnsxhttpxnaabuSIGSEGVbrew installgo install github.com/projectdiscovery/<tool>@latestbash
dnsx -version # 如果触发SIGSEGV:使用下方的dig降级方案
httpx -version # 如果触发SIGSEGV:使用下方的curl降级方案dnsx
→ dig
fallback
dnsxdigdnsx
→ dig
降级方案
dnsxdigbash
undefinedbash
undefinedReplaces: dnsx -l subs.txt -a -resp -silent
替代命令:dnsx -l subs.txt -a -resp -silent
while read s; do
ips=$(dig +short +tries=1 +time=3 "$s"
| grep -E '^[0-9.]+$'
| paste -sd, -) [ -n "$ips" ] && echo "$s|$ips" done < subs.txt
| grep -E '^[0-9.]+$'
| paste -sd, -) [ -n "$ips" ] && echo "$s|$ips" done < subs.txt
undefinedwhile read s; do
ips=$(dig +short +tries=1 +time=3 "$s"
| grep -E '^[0-9.]+$'
| paste -sd, -) [ -n "$ips" ] && echo "$s|$ips" done < subs.txt
| grep -E '^[0-9.]+$'
| paste -sd, -) [ -n "$ips" ] && echo "$s|$ips" done < subs.txt
undefinedhttpx
→ curl
fallback
httpxcurlhttpx
→ curl
降级方案
httpxcurlbash
undefinedbash
undefinedReplaces: httpx -l subs.txt -silent -status-code -title -tech-detect
替代命令:httpx -l subs.txt -silent -status-code -title -tech-detect
while read s; do
resp=$(curl -s -L -m 5 -o /tmp/body
-w "%{http_code}|%{url_effective}|%{header_server}"
"https://$s") code=$(echo "$resp" | cut -d'|' -f1) if [ "$code" != "000" ]; then title=$(grep -oE '<title[^>]>[^<]</title>' /tmp/body | head -1 | sed 's/<[^>]*>//g') echo "$s|$resp|$title" fi done < subs.txt
-w "%{http_code}|%{url_effective}|%{header_server}"
"https://$s") code=$(echo "$resp" | cut -d'|' -f1) if [ "$code" != "000" ]; then title=$(grep -oE '<title[^>]>[^<]</title>' /tmp/body | head -1 | sed 's/<[^>]*>//g') echo "$s|$resp|$title" fi done < subs.txt
**Trade-off:** Serial vs. concurrent. The fallback handles ~24 subdomains in 14 seconds; the same workload on `httpx` with default 50 threads finishes in 2-3 seconds. For VDP-scale recon (< 100 subdomains) the fallback is fine. For mass recon (1000+) fix the toolchain first.
Verified against HackerOne's own VDP in `docs/verification/recon-hackerone-vdp.md`.
---while read s; do
resp=$(curl -s -L -m 5 -o /tmp/body
-w "%{http_code}|%{url_effective}|%{header_server}"
"https://$s") code=$(echo "$resp" | cut -d'|' -f1) if [ "$code" != "000" ]; then title=$(grep -oE '<title[^>]>[^<]</title>' /tmp/body | head -1 | sed 's/<[^>]*>//g') echo "$s|$resp|$title" fi done < subs.txt
-w "%{http_code}|%{url_effective}|%{header_server}"
"https://$s") code=$(echo "$resp" | cut -d'|' -f1) if [ "$code" != "000" ]; then title=$(grep -oE '<title[^>]>[^<]</title>' /tmp/body | head -1 | sed 's/<[^>]*>//g') echo "$s|$resp|$title" fi done < subs.txt
**权衡:** 串行vs并发。降级方案处理约24个子域名需14秒;而`httpx`默认50线程处理相同任务仅需2-3秒。对于VDP规模的侦察(<100个子域名),降级方案足够;对于大规模侦察(>1000个),请先修复工具链问题。
已在`docs/verification/recon-hackerone-vdp.md`中针对HackerOne的VDP进行验证。
---API Spec / Swagger / OpenAPI Discovery (2024-2026 surface)
API规范/Swagger/OpenAPI发现(2024-2026攻击面)
API spec endpoints are the single highest-leverage recon target on any modern .NET / Node / Python / Java backend. The spec discloses every endpoint, HTTP methods, parameter names + types + formats, models, validation rules — a complete attack-map in JSON. Default routes are commonly left enabled in production. Add this wordlist to the directory-fuzzing phase (after the standard pass).
common.txtAPI规范端点是现代.NET/Node/Python/Java后端中价值最高的侦察目标。规范会披露所有端点、HTTP方法、参数名称+类型+格式、模型、验证规则 — 相当于一份完整的JSON格式攻击地图。默认路由常被保留在生产环境中。将此词表添加到目录模糊测试阶段(在标准扫描之后)。
common.txtDefault discovery path wordlist (paste into swagger-paths.txt
)
swagger-paths.txt默认发现路径词表(粘贴到swagger-paths.txt
)
swagger-paths.txtundefinedundefinedNSwag / Swashbuckle (ASP.NET Core)
NSwag / Swashbuckle(ASP.NET Core)
/swagger
/swagger/
/swagger/index.html
/swagger/ui/index.html
/swagger/v1/swagger.json
/swagger/v2/swagger.json
/swagger/v3/swagger.json
/swagger/docs/v1
/swagger/docs/v2
/swagger-ui
/swagger-ui/
/swagger-ui.html
/swagger-resources
/swagger-resources/configuration/ui
/nswag
/nswag/index.html
/api/swagger
/api/swagger.json
/api/swagger/v1/swagger.json
/api/openapi
/api/openapi.json
/api/v1/swagger.json
/api/v2/swagger.json
/api-docs
/api-docs/swagger.json
/swagger
/swagger/
/swagger/index.html
/swagger/ui/index.html
/swagger/v1/swagger.json
/swagger/v2/swagger.json
/swagger/v3/swagger.json
/swagger/docs/v1
/swagger/docs/v2
/swagger-ui
/swagger-ui/
/swagger-ui.html
/swagger-resources
/swagger-resources/configuration/ui
/nswag
/nswag/index.html
/api/swagger
/api/swagger.json
/api/swagger/v1/swagger.json
/api/openapi
/api/openapi.json
/api/v1/swagger.json
/api/v2/swagger.json
/api-docs
/api-docs/swagger.json
OpenAPI generic
OpenAPI通用路径
/openapi
/openapi.json
/openapi.yaml
/openapi.yml
/openapi/v1.json
/openapi/v2.json
/openapi/v3.json
/.well-known/openapi.json
/openapi
/openapi.json
/openapi.yaml
/openapi.yml
/openapi/v1.json
/openapi/v2.json
/openapi/v3.json
/.well-known/openapi.json
Java / Spring (Springfox / springdoc)
Java / Spring(Springfox / springdoc)
/v2/api-docs
/v3/api-docs
/v3/api-docs.yaml
/v3/api-docs/swagger-config
/swagger-ui/index.html
/v2/api-docs
/v3/api-docs
/v3/api-docs.yaml
/v3/api-docs/swagger-config
/swagger-ui/index.html
Python (FastAPI / Flask-RESTPlus / Connexion / DRF)
Python(FastAPI / Flask-RESTPlus / Connexion / DRF)
/docs
/docs/
/redoc
/redoc/
/openapi.json
/swagger.json
/swagger/?format=openapi
/swagger.yaml
/docs
/docs/
/redoc
/redoc/
/openapi.json
/swagger.json
/swagger/?format=openapi
/swagger.yaml
Express / Node / Hapi
Express / Node / Hapi
/api-docs
/api-docs.json
/swagger.json
/swagger-stats
/graphql-docs
/api-docs
/api-docs.json
/swagger.json
/swagger-stats
/graphql-docs
GraphQL adjacent (often co-located)
GraphQL相关(常共存)
/graphql
/graphiql
/playground
/altair
/voyager
/graphql/console
/graphql-explorer
/graphql
/graphiql
/playground
/altair
/voyager
/graphql/console
/graphql-explorer
ReDoc / RapiDoc / Stoplight / alt UIs
ReDoc / RapiDoc / Stoplight / 替代UI
/redoc
/redoc.html
/redoc-ui.html
/rapidoc
/rapidoc.html
/stoplight
/elements
/redoc
/redoc.html
/redoc-ui.html
/rapidoc
/rapidoc.html
/stoplight
/elements
Misc / dev-leftover
其他/开发遗留路径
/actuator
/actuator/openapi
/actuator/mappings
/q/openapi
/q/swagger-ui
/docs/swagger.json
/api/v1/docs
/api/v2/docs
/internal/swagger
/admin/swagger
/management/swagger
undefined/actuator
/actuator/openapi
/actuator/mappings
/q/openapi
/q/swagger-ui
/docs/swagger.json
/api/v1/docs
/api/v2/docs
/internal/swagger
/admin/swagger
/management/swagger
undefinedIntegration with the standard pipeline
与标准工作流集成
bash
undefinedbash
undefinedAfter live-hosts.txt is built (Phase 1 / 2), run:
生成live-hosts.txt后(阶段1/2),执行:
ffuf -w swagger-paths.txt -u "https://FUZZ.target.com" -mc 200,302 -fs 0 -t 50 -o swagger-hits.json
ffuf -w swagger-paths.txt -u "https://FUZZ.target.com" -mc 200,302 -fs 0 -t 50 -o swagger-hits.json
Or with httpx for content-aware filtering:
或使用httpx进行内容感知过滤:
httpx -l live-hosts.txt -path swagger-paths.txt -mc 200 -mr "swagger|openapi" -json | tee swagger-hits.jsonl
httpx -l live-hosts.txt -path swagger-paths.txt -mc 200 -mr "swagger|openapi" -json | tee swagger-hits.jsonl
For every hit:
针对每个命中结果:
jq '.paths | keys' swagger.json > endpoints.txt
jq '.components.schemas' swagger.json > schemas.json # mass-assignment field candidates
undefinedjq '.paths | keys' swagger.json > endpoints.txt
jq '.components.schemas' swagger.json > schemas.json # 批量赋值字段候选目标
undefinedWhy this matters for recon-to-hunting handoff
为何这对侦察到挖掘的过渡至关重要
- Spec → mass IDOR/BOLA — becomes the input list for
jq '.paths | keys' swagger.json/Autorizeper-user testing.ffuf - Spec → mass-assignment payload construction — enumerates
components.schemas.UserUpdateDto,isAdmin,emailVerified,tenantId.role - Spec → hidden endpoint discovery — ,
/internal/*,/debug/*,/v0/*routes documented but never auth-gated./legacy/* - Spec → injection-class seeding — every parameter's type + format + enum + max-length means payloads pass validation before reaching the sink. Especially valuable against ASP.NET Core where the model binder rejects malformed input before any controller logic.
- 规范→批量IDOR/BOLA — 可作为
jq '.paths | keys' swagger.json/Autorize用户权限测试的输入列表。ffuf - 规范→批量赋值载荷构建 — 会枚举
components.schemas.UserUpdateDto、isAdmin、emailVerified、tenantId等字段。role - 规范→隐藏端点发现 — 、
/internal/*、/debug/*、/v0/*等路由已被文档化但未做认证限制。/legacy/* - 规范→注入类漏洞测试 — 每个参数的类型+格式+枚举+最大长度意味着载荷在到达漏洞触发点前会通过验证。这在ASP.NET Core中尤为重要,模型绑定器会在控制器逻辑执行前拒绝格式错误的输入。
Tools
工具推荐
- — natively ingests OpenAPI spec, generates requests against the API.
kiterunner - (Swagger Jacker) — purpose-built for Swagger spec exploitation.
sj - (brinhosa) — Swagger-UI mass scanner.
apidetector - (vavkamil) — detects vulnerable Swagger UI versions (CVE-2018-25031 family).
XSSwagger - — built-in templates for default spec paths.
nuclei -t http/exposures/apis/
- — 原生支持OpenAPI规范,可生成针对API的请求。
kiterunner - (Swagger Jacker) — 专为Swagger规范 exploitation设计的工具。
sj - (brinhosa) — Swagger-UI批量扫描工具。
apidetector - (vavkamil) — 检测易受攻击的Swagger UI版本(CVE-2018-25031系列)。
XSSwagger - — 内置的默认规范路径检测模板。
nuclei -t http/exposures/apis/
Anti-pattern reminder
反模式提醒
A 404/403 on does NOT mean no spec is exposed. Many .NET projects route the spec under rather than . Always test the full path list, not just the root.
/swagger/api/swagger/v1/swagger.json/swaggerFull attack-chain analysis is in → .
hunt-api-misconfigNSwag / Swagger / OpenAPI Spec Exposure/swagger/api/swagger/v1/swagger.json/swagger完整攻击链分析见 → 。
hunt-api-misconfigNSwag / Swagger / OpenAPI Spec ExposureRelated Skills & Chains
相关技能与工作流
- — When recon needs concrete probes / wordlists / regexes beyond the basic pipeline. Workflow primitive: this skill produces the URL set;
offensive-osintprovides the secret regexes, GraphQL/Swagger paths, and identity-fabric probes you apply to that URL set.offensive-osint - — When you need a severity rubric for what you discovered. Workflow primitive: after recon outputs
osint-methodology/subdomains.txt/live-hosts.txt, score each asset againsturls.txt's findings rubric to decide what gets a finding versus what stays in the asset graph.osint-methodology - — When recon surfaces stale CNAMEs / dangling DNS. Workflow primitive: any subdomain in
hunt-subdomainwhose CNAME points to S3 / GitHub Pages / Heroku / Shopify / Azure should auto-route tosubdomains.txtfor takeover validation.hunt-subdomain - — When the URL set is classified by
security-arsenaland ready for active testing. Workflow primitive:gfoutput names become payload-class queries againstgf xss/ssrf/sqli/idor's payload library.security-arsenal - — When recon completes and Phase 1 transitions to Phase 2 (Mapping). Workflow primitive: hand the live host + URL set back to
bb-methodologyPhase 2 for endpoint mapping and Phase 3 vulnerability discovery routing.bb-methodology
- — 当侦察需要超出基础工作流的具体探针/词表/正则时。工作流逻辑:本技能生成URL集合;
offensive-osint提供可应用于该集合的密钥正则、GraphQL/Swagger路径、身份架构探针。offensive-osint - — 当需要为发现的内容制定严重程度评估标准时。工作流逻辑:侦察输出
osint-methodology/subdomains.txt/live-hosts.txt后,根据urls.txt的发现评估标准为每个资产评分,决定哪些内容可作为漏洞报告提交,哪些仅保留在资产图谱中。osint-methodology - — 当侦察发现过期CNAME/悬空DNS时。工作流逻辑:
hunt-subdomain中任何CNAME指向S3/GitHub Pages/Heroku/Shopify/Azure的子域名,应自动路由到subdomains.txt进行接管验证。hunt-subdomain - — 当URL集合已通过
security-arsenal分类并准备进行主动测试时。工作流逻辑:gf的输出名称可作为gf xss/ssrf/sqli/idor载荷库的载荷类查询条件。security-arsenal - — 当侦察完成,从阶段1过渡到阶段2(映射)时。工作流逻辑:将存活主机+URL集合交还给
bb-methodology阶段2进行端点映射,再进入阶段3的漏洞发现路由。bb-methodology
Operator Notes (Claude-BugHunter)
操作员笔记(Claude-BugHunter)
Engagement-derived + 2026-specific additions to the vendored foundation. Wisdom from real authorized engagements + Phase 2 verification across this repo's 31+ skill-area live tests. The upstream pipeline covers the WHAT; this layer covers the WHEN-IT-WORKS-vs-WHEN-IT-DOESN'T.
基于真实参与的项目 + 2026年特定补充的经验总结。 来自真实授权项目的经验 + 本仓库31+技能领域的阶段2验证。上游工作流覆盖了"做什么";本层覆盖了"何时有效vs何时无效"。
Cross-TLD pivot discipline
跨TLD转换原则
Phase 2C's HackerOne VDP recon walked from (24 subdomains) into a sister TLD (12 more subdomains found in JS bundle references). Operators who only enumerate miss attack surface that the target legitimately operates on a different domain.
hackerone.comhacker.one*.target.comAlways grep JS bundles for plausible sibling TLDs:
bash
undefined阶段2C的HackerOne VDP侦察从(24个子域名)扩展到了姊妹TLD (在JS包引用中发现了12个额外子域名)。仅枚举的操作员会错过目标在其他域名上合法运营的攻击面。
hackerone.comhacker.one*.target.com务必在JS包中搜索合理的姊妹TLD:
bash
undefinedpull all JS, grep for sibling-TLD candidates
拉取所有JS,搜索姊妹TLD候选
for url in $(cat live-hosts.txt); do
curl -s "$url" | grep -oE 'src="[^"]+.js"' | sed 's/src="//;s/"//'
done | sort -u > js-urls.txt
for url in $(cat live-hosts.txt); do
curl -s "$url" | grep -oE 'src="[^"]+.js"' | sed 's/src="//;s/"//'
done | sort -u > js-urls.txt
then on each JS file
然后对每个JS文件进行搜索
for j in $(cat js-urls.txt); do
curl -s "$j" | grep -oE '[a-z0-9.-]+.(io|app|one|dev|test|cloud|ai|co)' | sort -u
done | sort -u > sibling-tld-candidates.txt
Common sibling-TLD patterns: `target.com → target.io / target.app / target.one / target.dev / target.test / target-corp.com / target-cdn.net`. Always validate via WHOIS or by checking if the cert chain trusts the same internal CA before treating the sister TLD as in-scope.for j in $(cat js-urls.txt); do
curl -s "$j" | grep -oE '[a-z0-9.-]+.(io|app|one|dev|test|cloud|ai|co)' | sort -u
done | sort -u > sibling-tld-candidates.txt
常见姊妹TLD模式:`target.com → target.io / target.app / target.one / target.dev / target.test / target-corp.com / target-cdn.net`。在将姊妹TLD视为测试范围前,务必通过WHOIS或检查证书链是否信任同一内部CA进行验证。Subdomain wordlist priorities by 2026
2026年子域名词表优先级
Top discovery prefixes by hit rate against enterprise VDPs in our 2024-2026 corpus:
mta-sts.* api.* docs.*
dev-* staging-* *-qa
*-stage *-uat events.*
portal.* customer.* partner.*
vendor.* internal-* admin-*
employee-* hr.* jobs.*
sso.* auth.* id.*Internal-looking subdomains often expose more surface than the marketing site — and frequently have weaker auth than the main app because they're scoped for "trusted" external users. Always send a probe to the long-tail wordlist after the standard subfinder run completes.
partner.target.comvendor-portal.target.com根据2024-2026年企业VDP的命中率,顶级发现前缀如下:
mta-sts.* api.* docs.*
dev-* staging-* *-qa
*-stage *-uat events.*
portal.* customer.* partner.*
vendor.* internal-* admin-*
employee-* hr.* jobs.*
sso.* auth.* id.*内部风格的子域名通常比营销网站暴露更多攻击面 — 和的认证机制往往比主应用更弱,因为它们面向"可信"外部用户。在标准subfinder运行完成后,务必使用长尾词表进行探测。
partner.target.comvendor-portal.target.comLive-host probe: how to fingerprint stack quickly
存活主机探针:快速识别技术栈
curl -sI <host>- — apache / nginx / cloudflare / kestrel (= .NET Core) / openresty / envoy
Server: - — PHP version, ASP.NET version, Express.js
X-Powered-By: - ,
X-Drupal-Cache— DrupalX-Generator: Drupal 9 - — WordPress
X-Generator: WordPress - — CDN chain (1.1 varnish, 1.1 cloudfront)
Via: - names —
Set-Cookie:(Java),JSESSIONID(PHP),PHPSESSID(.NET),ASP.NET_SessionId(Express),connect.sid(Laravel)laravel_session
JS bundle filename patterns:
- = Next.js
/_next/static/ - = Nuxt
/_nuxt/ - with hash filenames = Vite
/assets/static/ - = Create React App
/static/js/main.*.chunk.js - = Angular CLI
runtime.*.js + polyfills.*.js + main.*.js
The first 10s of recon should yield a stack guess; the rest is targeting. If your fingerprint contradicts itself (Server says nginx, Set-Cookie says ASP.NET) you've found a reverse proxy front-end — note the origin app for later smuggling/cache attacks.
curl -sI <host>- — apache / nginx / cloudflare / kestrel(=.NET Core) / openresty / envoy
Server: - — PHP版本、ASP.NET版本、Express.js
X-Powered-By: - ,
X-Drupal-Cache— DrupalX-Generator: Drupal 9 - — WordPress
X-Generator: WordPress - — CDN链(1.1 varnish、1.1 cloudfront)
Via: - 名称 —
Set-Cookie:(Java)、JSESSIONID(PHP)、PHPSESSID(.NET)、ASP.NET_SessionId(Express)、connect.sid(Laravel)laravel_session
JS包文件名模式:
- = Next.js
/_next/static/ - = Nuxt
/_nuxt/ - 带哈希文件名 = Vite
/assets/static/ - = Create React App
/static/js/main.*.chunk.js - = Angular CLI
runtime.*.js + polyfills.*.js + main.*.js
侦察的前10秒应能推测出技术栈;后续工作则是针对性测试。如果指纹信息矛盾(Server显示nginx,Set-Cookie显示ASP.NET),说明你发现了反向代理前端 — 记录源应用以便后续进行请求走私/缓存攻击。
GitHub Pages 404 vs takeover signal
GitHub Pages 404与接管信号的关键区别
Critical distinction operators get wrong:
- "Page not found · GitHub Pages" with HTTP 404 means the repo EXISTS — NOT a takeover.
- "There isn't a GitHub Pages site here" means the repo was deleted — TAKEOVER candidate.
Same distinction for CloudFront:
- "Error - 404" with = distribution exists, origin returned 404 — NOT a takeover.
Server: CloudFront - "The request could not be satisfied" with = origin missing entirely — potential takeover.
X-Cache: Error from cloudfront
Phase 2C verified both patterns live. Always check the EXACT response body string before filing a takeover finding — the takeover-scanner tools (subzy, subjack) match on multiple fingerprints and frequently false-positive on the "still owned, just empty" case.
操作员常混淆的重要区别:
- "Page not found · GitHub Pages" 伴随HTTP 404状态码 → 仓库存在 — 不可接管。
- "There isn't a GitHub Pages site here" → 仓库已删除 — 可接管候选目标。
CloudFront的情况类似:
- "Error - 404" 伴随→ 分发存在,源站返回404 — 不可接管。
Server: CloudFront - "The request could not be satisfied" 伴随→ 源站完全缺失 — 潜在可接管目标。
X-Cache: Error from cloudfront
阶段2C已对两种模式进行了实时验证。在提交接管漏洞报告前,务必检查响应体的精确字符串 — 接管扫描工具(subzy、subjack)会匹配多个指纹,常在"仍被拥有但为空"的情况下误报。
Toolchain fallback
工具链降级方案
Already covered in this file's Phase 2C addition. Quick reminder: dnsx/httpx may segfault on macOS arm64; the dig+curl fallback works for < 100-host runs in ~14 seconds. Don't burn an hour debugging Go binary panics when the fallback gets you to the same URL set.
已在本文档的阶段2C补充部分覆盖。快速提醒:dnsx/httpx可能在macOS arm64上崩溃;dig+curl降级方案处理<100个主机需约14秒。不要浪费时间调试Go二进制崩溃问题,降级方案可帮你获得相同的URL集合。