关于 web2-recon
web2-recon 是面向漏洞赏金研究者的安全技能,用于发现 Web 资产并筛选出优先级 URL 列表。它结合侦察流程、目标评分和持续变更监控。
主要功能
- 01发现子域名与在线主机
- 02筛选 URL 与攻击面
- 03检查 JavaScript 端点和密钥
- 04目标评分与停止信号
- 05监控子域名与代码提交
适用场景
- 01漏洞测试前构建 URL 列表
- 02按项目和攻击面优先级筛选目标
- 03监控目标新增资产与代码提交
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill web2-recon安装后在 Claude Code 中输入/web2-recon确认已加载。
详细介绍
WEB2 侦察流水线
从零开始全面发现资产,生成可用于狩猎的优先级 URL 列表。
设置(一次性)
# 1. Set your Chaos API key (get free key at chaos.projectdiscovery.io)
export CHAOS_API_KEY="your-key-here"
# Add to ~/.zshrc or ~/.bashrc for persistence:
echo 'export CHAOS_API_KEY="your-key-here"' >> ~/.zshrc
# 2. Update nuclei templates (run weekly)
nuclei -update-templates
# 3. Configure subfinder with API keys for more sources
mkdir -p ~/.config/subfinder
cat > ~/.config/subfinder/config.yaml << 'EOF'
# Get free keys at: 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
# 4. Verify all tools installed
which subfinder httpx dnsx nuclei katana waybackurls gau dalfox ffuf anew gf interactsh-client
5 分钟规则
如果目标经过 5 分钟侦察后仍没有任何有趣发现,就换一个目标。别在没有成果的攻击面上浪费数小时。
5 分钟止损信号:
- 所有子域名都返回 403 或静态营销页面
- URL 中看不到 API 端点
- 没有包含有趣端点路径的 JavaScript 包
- nuclei 返回 0 个中危/高危发现
- 没有表单、身份验证或用户数据
标准侦察流水线
狩猎前:始终先运行
TARGET="target.com"
# Step 0: Passive — crt.sh certificate transparency (no API key needed)
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"
# Step 1: Chaos API (ProjectDiscovery — most comprehensive source)
curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains" \
-H "Authorization: $CHAOS_API_KEY" \
| jq -r '.[]' >> /tmp/subs.txt
echo "[+] Chaos returned $(wc -l < /tmp/subs.txt) subdomains"
# Step 2: subfinder (passive multi-source)
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)"
# Step 3: DNS resolution + live host check
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)"
# Step 4: URL crawl
cat /tmp/live.txt | awk '{print $1}' | katana -d 3 -jc -kf all -silent | anew /tmp/urls.txt
# Step 5: Historical URLs
echo $TARGET | waybackurls | anew /tmp/urls.txt
gau $TARGET --subs | anew /tmp/urls.txt
echo "[+] Total URLs: $(wc -l < /tmp/urls.txt)"
# Step 6: Nuclei scan
nuclei -l /tmp/live.txt -t ~/nuclei-templates/ -severity critical,high,medium -o /tmp/nuclei.txt
输出到有序目录
TARGET="target.com"
RECON_DIR="recon/$TARGET"
mkdir -p $RECON_DIR
# All 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
攻击面分流
在 URL 列表中查找有趣的目标
# Parameters worth testing
cat /tmp/urls.txt | grep -E "[?&](id|user|file|path|url|redirect|next|src|token|key|api_key)=" | tee /tmp/interesting-params.txt
# API endpoints
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
# Admin/internal paths
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
gf 模式(快速分类)
# Install 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
JS 分析
SecretFinder(JS 包中的 API 密钥、令牌)
# Activate venv
source ~/tools/SecretFinder/.venv/bin/activate
# Scan a single JS file
python3 ~/tools/SecretFinder/SecretFinder.py -i "https://target.com/static/js/main.js" -o cli
# Scan all JS URLs found in recon
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
LinkFinder(隐藏在 JS 中的端点)
source ~/tools/LinkFinder/.venv/bin/activate
# Single JS file
python3 ~/tools/LinkFinder/linkfinder.py -i "https://target.com/app.js" -o cli
# All pages (crawls JS from HTML)
python3 ~/tools/LinkFinder/linkfinder.py -i "https://target.com" -d -o cli
deactivate
目录模糊测试
ffuf — 标准模糊测试
# Directory 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
# API endpoint discovery
ffuf -u "https://target.com/api/FUZZ" \
-w ~/wordlists/api-endpoints.txt \
-mc 200,201,204,301,302 \
-ac \
-t 20
# IDOR fuzzing with authenticated request
# Create req.txt with Authorization: Bearer TOKEN
ffuf -request /tmp/req.txt \
-request-proto https \
-w <(seq 1 10000) \
-fc 404 \
-ac \
-t 10
目标评分 — 继续/放弃
投入时间前先评分。分数低于 4 就跳过。
| 标准 | 分数 |
|---|---|
| 最高赏金 >= $5K | +2 |
| 用户群体庞大(>100K)或处理资金 | +2 |
| 项目上线时间 < 60 天 | +2 |
| 功能复杂:API、OAuth、文件上传、GraphQL | +1 |
| 近期代码/功能变更(GitHub、更新日志) | +1 |
| 私有项目(竞争较少) | +1 |
| 熟悉其技术栈 | +1 |
| 可获取源代码 | +1 |
| 有过往已披露报告可供研究 | +1 |
< 4: 跳过 4-5: 仅在没有更好的选择时考虑 6-8: 不错 — 投入 1-3 天 >= 9: 极佳 — 最多投入 1 周
深入调查前的强制止损信号
- 最高赏金 < $500 → 不值得花时间
- 所有近期报告都是 N/A 或重复报告 → 其他猎手已饱和
- 范围仅限静态营销页面 → 没有攻击面
- 公司员工少于 5 人且没有收入 → 不会支付赏金
- 规则明确排除了你计划寻找的漏洞类别
技术栈检测(2 分钟)
# Response headers reveal backend
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: gunicorn OR X-Powered-By: Express → Python/Node.js
# X-Powered-By: ASP.NET → .NET
# Server: Apache Tomcat → Java
# X-Runtime: Ruby → Ruby on Rails
# Framework from JS bundle paths:
# /_next/static/ → Next.js
# /static/js/main.chunk.js → CRA (React)
# /packs/ → Ruby on Rails + Webpacker
# /__nuxt/ → Nuxt.js (Vue)
技术栈 → 首选漏洞类别映射
| 技术栈 | 优先狩猎 | 次选狩猎 |
|---|---|---|
| Ruby on Rails | 批量赋值 | IDOR(:id 路由) |
| 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 | 内省 → mutations 上的身份验证绕过 | 通过 node(id:) 实现 IDOR |
| WordPress | 插件 SQLi | REST API 身份验证绕过 |
持续监控设置
每个目标设置一次。抢在其他猎手之前收到提醒。
新子域名提醒(每日 cron)
#!/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.txt
# Diff 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
# Schedule: crontab -e → 0 8 * * * /bin/bash ~/monitors/subs-watch.sh
GitHub 提交监控
#!/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"
fi
# Schedule: */30 * * * * /bin/bash ~/monitors/github-watch.sh
端口扫描(经常被跳过——别跳过)
# naabu — fast port scanner from ProjectDiscovery
# Finds non-standard ports: 8080, 8443, 3000, 8888, 9000, etc.
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
# Example wins: :8080/actuator/env (Spring Boot), :9200/_cat/indices (Elasticsearch), :6379 (Redis)
扫描 JS 包中的机密信息
# trufflehog — high-signal secret detection with entropy analysis
# Scans JS files and git repos
pip install trufflehog3 2>/dev/null || true
trufflehog filesystem --only-verified recon/$TARGET/ 2>/dev/null
# SecretFinder — manual JS bundle scan (already in tools/)
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
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
针对目标进行 GitHub Dork 搜索
# Search GitHub for hardcoded secrets before hunting the app
TARGET_ORG="TargetOrgName" # Check their GitHub org
# Useful dorks (search on github.com):
# org:TARGET_ORG password
# org:TARGET_ORG api_key
# org:TARGET_ORG "Authorization: Bearer"
# org:TARGET_ORG .env
# org:TARGET_ORG "BEGIN RSA PRIVATE KEY"
# CLI with gh (GitHub CLI):
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):
python3 ~/tools/GitDorker/GitDorker.py -t GITHUB_TOKEN -d ~/tools/GitDorker/Dorks/alldorksv3 -q "$TARGET" -org
30 分钟侦察流程
第 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)
第 5-15 分钟:资产发现
运行上面的标准流水线。重点查看 live.txt 输出。
第 15-25 分钟:绘制攻击面图
运行 gf 模式和上面的有趣参数 grep。
第 25-30 分钟:手动探索
打开 Burp Suite,启用代理后浏览应用:
- 注册一个账户
- 执行主要用户操作(创建/读取/更新/删除资源)
- 在 Burp 历史记录中记下所有 API 调用
- 查找 URL 列表中没有的端点
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
工具链回退(dnsx / httpx 崩溃时)
在 macOS arm64 上,ProjectDiscovery 的 Go 二进制文件(dnsx、httpx、naabu)偶尔会因 cgo 与系统解析器交互而触发 SIGSEGV。无论通过哪种方式安装,崩溃特征都相同——brew install 和 go install github.com/projectdiscovery/<tool>@latest 生成的二进制文件都会在同一地址发生段错误。在真实测试任务中依赖它们之前,请先进行一次冒烟测试:
dnsx -version # if SIGSEGV: use the dig fallback below
httpx -version # if SIGSEGV: use the curl fallback below
dnsx → dig 回退
# Replaces: 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
httpx → curl 回退
# Replaces: 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
**权衡:**串行与并发。回退方案处理约 24 个子域名需要 14 秒;相同任务使用默认 50 个线程的 httpx,只需 2-3 秒。对于 VDP 规模的侦察(< 100 个子域名),回退方案足够用。对于大规模侦察(1000+),请先修复工具链。
已通过 HackerOne 自有的 VDP 验证,详见 docs/verification/recon-hackerone-vdp.md。
API 规范 / Swagger / OpenAPI 发现(2024-2026 年情况)
在任何现代 .NET / Node / Python / Java 后端中,API 规范端点都是最有价值的侦察目标。规范会以 JSON 格式披露每个端点、HTTP 方法、参数名称与类型及格式、模型和验证规则,构成完整的攻击地图。生产环境中常常未关闭默认路由。请将此字典加入目录模糊测试阶段(完成标准的 common.txt 扫描后)。
默认发现路径字典(粘贴到 swagger-paths.txt)
# 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
# OpenAPI generic
/openapi
/openapi.json
/openapi.yaml
/openapi.yml
/openapi/v1.json
/openapi/v2.json
/openapi/v3.json
/.well-known/openapi.json
# Java / Spring (Springfox / springdoc)
/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)
/docs
/docs/
/redoc
/redoc/
/openapi.json
/swagger.json
/swagger/?format=openapi
/swagger.yaml
# Express / Node / Hapi
/api-docs
/api-docs.json
/swagger.json
/swagger-stats
/graphql-docs
# GraphQL adjacent (often co-located)
/graphql
/graphiql
/playground
/altair
/voyager
/graphql/console
/graphql-explorer
# ReDoc / RapiDoc / Stoplight / alt UIs
/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
与标准流程集成
# After live-hosts.txt is built (Phase 1 / 2), run:
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 -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
这为何对侦察到漏洞搜寻的交接至关重要
- 规范 → 大规模 IDOR/BOLA 测试 —
jq '.paths | keys' swagger.json的结果可作为Autorize/ffuf针对不同用户进行测试的输入列表。 - 规范 → 构造大规模批量赋值载荷 —
components.schemas.UserUpdateDto会列出isAdmin、emailVerified、tenantId、role。 - 规范 → 发现隐藏端点 —
/internal/*、/debug/*、/v0/*、/legacy/*等路由有记录,但从未经过身份验证门控。 - 规范 → 注入类别测试的种子 — 每个参数的类型、格式、枚举值和最大长度意味着载荷可通过验证并到达接收点。对于 ASP.NET Core 尤其有价值,因为模型绑定器会在任何控制器逻辑运行前拒绝格式错误的输入。
工具
kiterunner— 原生导入 OpenAPI 规范,并针对 API 生成请求。sj(Swagger Jacker)— 专为利用 Swagger 规范而设计。apidetector(brinhosa)— Swagger-UI 大规模扫描器。XSSwagger(vavkamil)— 检测存在漏洞的 Swagger UI 版本(CVE-2018-25031 系列)。nuclei -t http/exposures/apis/— 内置默认规范路径模板。
反模式提醒
在 /swagger 上遇到 404/403 并不意味着没有暴露规范。许多 .NET 项目会将规范路由设为 /api/swagger/v1/swagger.json,而非 /swagger。请始终测试完整路径列表,而不只是根路径。
完整攻击链分析见 hunt-api-misconfig → NSwag / Swagger / OpenAPI Spec Exposure。
相关技能与链路
offensive-osint— 当侦察需要超出基础流程的具体探测、字典或正则表达式时使用。工作流基本步骤:此技能生成 URL 集;offensive-osint提供适用于该 URL 集的机密正则表达式、GraphQL/Swagger 路径和身份伪造探测。osint-methodology— 当你需要为发现的内容确定严重性等级时使用。工作流基本步骤:侦察输出subdomains.txt/live-hosts.txt/urls.txt后,依据osint-methodology的发现分级标准为每项资产评分,以确定哪些应作为发现项,哪些保留在资产图谱中。hunt-subdomain— 当侦察发现过时的 CNAME 或悬空 DNS 时使用。工作流基本步骤:subdomains.txt中任何 CNAME 指向 S3 / GitHub Pages / Heroku / Shopify / Azure 的子域名,都应自动转交给hunt-subdomain进行接管验证。security-arsenal— 当 URL 集经gf分类并准备好进行主动测试时使用。工作流基本步骤:将gf xss/ssrf/sqli/idor输出的名称作为查询条件,针对security-arsenal的载荷库检索对应载荷类别。bb-methodology— 当侦察完成、Phase 1 转入 Phase 2(映射)时使用。工作流基本步骤:将存活主机和 URL 集交回bb-methodologyPhase 2,用于端点映射,并按 Phase 3 路由至漏洞发现。
操作人员须知(Claude-BugHunter)
基于实战项目的补充内容 + 针对 2026 年的特定补充,添加到引入的基础内容之上。 来自真实授权项目的经验 + 对本仓库 31+ 个技能领域实测的 Phase 2 验证。 上游流程涵盖 WHAT;此层涵盖 WHEN-IT-WORKS-vs-WHEN-IT-DOESN'T。
跨顶级域名跳转规范
Phase 2C 的 HackerOne VDP 侦察从 hackerone.com(24 个子域名)扩展到关联的顶级域名 hacker.one(从 JS 包引用中又发现 12 个子域名)。只枚举 *.target.com 的操作人员会漏掉目标在其他域名上合法运营的攻击面。
始终在 JS 包中搜索可能的关联顶级域名:
# pull all JS, grep for sibling-TLD candidates
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
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
常见的关联顶级域名模式:target.com → target.io / target.app / target.one / target.dev / target.test / target-corp.com / target-cdn.net。在将关联顶级域名视为范围内之前,始终通过 WHOIS 验证,或检查证书链是否信任同一个内部 CA。
2026 年子域名字典优先级
在我们的 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.*
看起来像内部系统的子域名往往比营销网站暴露更多攻击面——partner.target.com 和 vendor-portal.target.com 经常比主应用的身份验证更薄弱,因为它们面向“受信任”的外部用户。标准 subfinder 运行完成后,始终使用长尾字典进行探测。
存活主机探测:如何快速识别技术栈
curl -sI <host> 响应头包含 80% 的指纹信息:
Server:— apache / nginx / cloudflare / kestrel(= .NET Core)/ openresty / envoyX-Powered-By:— PHP 版本、ASP.NET 版本、Express.jsX-Drupal-Cache、X-Generator: Drupal 9— DrupalX-Generator: WordPress— WordPressVia:— CDN 链路(1.1 varnish、1.1 cloudfront)Set-Cookie:名称 —JSESSIONID(Java)、PHPSESSID(PHP)、ASP.NET_SessionId(.NET)、connect.sid(Express)、laravel_session(Laravel)
JS 包文件名模式:
/_next/static/= Next.js/_nuxt/= Nuxt- 文件名带哈希的
/assets/static/= Vite /static/js/main.*.chunk.js= Create React Appruntime.*.js + polyfills.*.js + main.*.js= Angular CLI
侦察的前 10 秒应该足以初步判断技术栈;其余时间用于确定目标。如果指纹信息互相矛盾(Server 显示 nginx,Set-Cookie 显示 ASP.NET),说明前端存在反向代理——记下源站应用,以便后续进行请求走私或缓存攻击。
GitHub Pages 404 与接管信号
操作人员容易混淆的关键区别:
- HTTP 404 响应显示 "Page not found · GitHub Pages",表示仓库仍然存在——不是接管。
- 显示 "There isn't a GitHub Pages site here",表示仓库已被删除——可作为接管目标。
CloudFront 也有同样的区别:
- 显示 "Error - 404",且有
Server: CloudFront= 分发仍然存在,只是源站返回了 404——不是接管。 - 显示 "The request could not be satisfied",且有
X-Cache: Error from cloudfront= 源站已完全缺失——可能存在接管风险。
Phase 2C 已在线验证这两种模式。提交接管问题之前,务必检查响应正文中的确切字符串——接管扫描工具(subzy、subjack)会匹配多种特征,经常会把“仍归原所有者所有,只是内容为空”的情况误报。
工具链备用方案
本文件的 Phase 2C 补充内容已涵盖此项。快速提醒:dnsx/httpx 在 macOS arm64 上可能发生段错误;对于少于 100 个主机的运行,dig+curl 备用方案大约需要 14 秒即可完成。备用方案能得到相同的 URL 集合,就别花一小时排查 Go 二进制的崩溃问题。