mcpField
W
web2-recon

web2-recon

github.com/uphiago安全1.3k42 次安装8 周前更新
代码仓库

关于 web2-recon

web2-recon 是面向漏洞赏金研究者的 Web 资产侦察流程指南,从子域发现到 URL 分类和目标评分,帮助整理并优先检查攻击面。

主要功能

  1. 01子域与存活主机发现
  2. 02URL 与 API 端点分类
  3. 03JavaScript 端点和密钥检查
  4. 04目录模糊测试与端口扫描
  5. 05目标评分和持续监控

适用场景

  1. 01启动漏洞赏金目标的初步侦察
  2. 02从 URL 列表筛选 API 和参数
  3. 03检查 JavaScript 包中的端点与密钥

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/uphiago/recon-skills --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 alltools 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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 周

深入测试前的强制淘汰信号
  1. 最高赏金 < $500 → 不值得花时间
  2. 所有近期报告都是 N/A 或重复报告 → 该目标已被其他狩猎者充分测试
  3. 范围仅限静态营销页面 → 没有攻击面
  4. 公司员工少于 5 人且没有收入 → 不会付钱
  5. 规则明确排除你计划测试的漏洞类型

技术栈检测(2 分钟)

# Response headers reveal backend
curl --max-time 30 --connect-timeout 10 -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 路由)
DjangoIDOR(ModelViewSet,无对象权限)SSTI(mark_safe)
FlaskSSTI(render_template_string)SSRF(requests 库)
Laravel批量赋值($fillable)IDOR(Eloquent,无所有权检查)
Express(Node.js)原型污染路径遍历
Spring BootActuator 端点(/actuator/env)SSTI(Thymeleaf)
ASP.NETViewState 反序列化开放重定向(ReturnUrl)
Next.js通过 Server Actions 实现 SSRF通过 redirect() 实现开放重定向
GraphQL自省 → 绕过变更操作的身份验证通过 node(id:) 实现 IDOR
WordPress插件 SQLiREST API 身份验证绕过;CORS 凭据反射

持续监控设置

每个目标设置一次。在其他狩猎者之前向你发出提醒。

新子域提醒(每日 cron)
#!/bin/bash
TARGET="target.com"
KNOWN="/tmp/$TARGET-subs-known.txt"

subfinder -d $TARGET -silent > /tmp/$TARGET-subs-fresh.txt
curl --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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
# nmap often fails with "nse_main.lua not found" on minimal containers — naabu works.
# 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)
原始端口连通性测试(naabu 不可用时)
# Quick single-port check via bash /dev/tcp — works anywhere bash is available
for port in 22 80 443 3306 5432 6379 8080 8081 8443 27017; do
  timeout 3 bash -c "echo >/dev/tcp/$TARGET/$port" 2>&1 && echo "PORT $port OPEN" || echo "PORT $port CLOSED/FILTERED"
done

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 intools/)
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
JS 包 API 密钥提取(兼容 BusyBox 的备用方案)

BusyBox grep 不支持 -P(PCRE/Perl 正则表达式)。在 Alpine 容器中对 JS 包进行正则匹配时,请使用 Python3:

# Extract Firebase API keys from JS bundle
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/static/js/main.*.js" 2>/dev/null | python3 -c "
import sys, re
content = sys.stdin.read()
for k in re.findall(r'AIza[0-9A-Za-z_-]{35}', content):
    print(f'Firebase API Key: {k}')
for m in re.findall(r'(?:apiUrl|apiKey|authDomain|databaseURL|projectId)[\"\']?\s*[:=]\s*[\"]([^\"\']+)[\"]', content):
    print(f'Config: {m}')
for u in re.findall(r'https?://[a-zA-Z0-9._-]+\.(?:firebaseio|firestore|googleapis|herokuapp)\.com[^\"\\s,]*', content):
    print(f'URL: {u}')
for s in re.findall(r'(?:secret|jwt[_-]?secret|token)[\"\']?\s*[:=]\s*[\"]([a-zA-Z0-9_\-]{16,})[\"]', content):
    print(f'Potential secret: {s}')
" 2>/dev/null

# For React SPAs with chunked bundles — find the main bundle first
main_js=$(curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET:8080/" 2>/dev/null | grep -Eo 'src="([^"]+\.js)"' | sed 's/src="//;s/"//' | head -1)
[ -n "$main_js" ] && curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET:8080/$main_js" | python3 -c "
import sys, re
content = sys.stdin.read()
for m in re.findall(r'https?://[^\"\\s,;\\)]+', content):
    if '://' in m and not 'fonts.' in m:
        print(f'URL: {m}')
for m in re.findall(r'apiUrl[\"\\']?\s*[:=]\s*[\"\\']([^\"\\']+)[\"\\']', content):
    print(f'apiUrl: {m}')
" 2>/dev/null

此技术可以发现使用非标准端口的 API 后端,这些后端不会出现在导航中, 也不遵循 DNS 命名惯例。

针对目标进行 GitHub 搜索

# 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 分钟侦察流程

双轨并行侦察(已验证适用于多目标批次)

在多个行业中测试 15–20 个以上目标时,请采用双轨方法:

轨道 1 — 手动快速探测(轨道 2 运行时同步进行)

  1. 对每个域名运行 curl --max-time 10 --connect-timeout 5 -sI,检查其是否存活及服务器标头(每 5 个域名约需 30 秒)
  2. 立即检查有价值的信号:WordPress 链接标头、CORS 来源、有意思的 Cookie
  3. 趁着对有意思的域名还有印象,运行 subfinder
  4. 立即追踪存活的子域名(app.、dashboard.、staging. 等)

轨道 2 — 自动扫描器(后台运行)

  • 启动一个带有限延迟和 5 个并行任务的 Python 扫描器。
  • 扫描器负责系统化工作:为每个域名检测 WP、测试 CORS、检查敏感文件、枚举子域名
  • 定期检查进度;扫描完成时,你已经掌握了高价值发现

这样做的原因:

  • 手动探测能在前 5 分钟内发现高价值目标(严重级别的 CORS 问题、WP 用户、暴露的预发布环境)
  • 自动扫描器会验证其余目标,而无需你把注意力浪费在无响应的目标上
  • 手动发现的子域名可以在扫描器仍运行时立即探测
  • 在 Wave 5 中(20 个目标、4 个行业),这种方法在 15 分钟的手动工作中发现了 3 个严重级别的 CORS 问题、11 个暴露的 WP 用户和 95 个子域名
第 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。启用代理并浏览应用:

  1. 注册一个账户
  2. 执行主要用户操作(创建/读取/更新/删除资源)
  3. 在 Burp 历史记录中记录所有 API 调用
  4. 查找 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 崩溃时)

projectdiscovery 的 Go 二进制文件(dnsx、httpx、naabu)偶尔会因 cgo 与系统解析器交互而在 macOS arm64 上触发 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 备用方案
# Preferred: dnsx (concurrent, 50-100x faster at scale)
dnsx -silent -l subs.txt -a -resp-only -o resolved.txt

# Fallback: dig (sequential, only if dnsx binary unavailable)
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 --max-time 30 --connect-timeout 10 -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 年攻击面)

API 规范端点是任何现代 .NET / Node / Python / Java 后端中价值最高的侦察目标。规范会以 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 进行逐用户测试的输入列表。
  • 规范 → 批量构造赋值 payload — components.schemas.UserUpdateDto 会列出 isAdmin、emailVerified、tenantId、role。
  • 规范 → 发现隐藏端点 — /internal/*、/debug/*、/v0/*、/legacy/* 路由有文档记录,却从未受到身份验证保护。
  • 规范 → 注入类别播种 — 每个参数的类型 + 格式 + 枚举值 + 最大长度,意味着 payload 在到达接收点前就能通过验证。在 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。


验证

  1. 核心侦察工具 — 确认已安装关键工具:
    which subfinder httpx nuclei katana 2>/dev/null | wc -l | xargs -I{} echo "{} of 4 core tools found"
    
  2. HTTP 探测 — 确认 httpx 可正常工作:
    echo "example.com" | httpx -silent -status-code 2>/dev/null && echo "PASS: httpx operational" || echo "NOTE: httpx not installed"
    

所有测试均用于验证 web2 侦察是否就绪。


注意事项

  • 侦察后不进行分类 — 收集 10,000 个子域名,却不优先确定要测试哪些,这只是数据收集,不是侦察。
  • HTTP 探测未测试 HTTPS — 许多服务只会通过 HTTPS 响应。两种协议都要测试。
  • 收集截图后不进行分析 — 只有在检查自动生成的截图后,它们才有用。独特的登录页面、错误消息和 CMS 标识符才是有价值的信息。
  • 端口扫描后不识别服务 — 开放的 8443 端口可能对应任何服务。抓取 Banner 并识别实际服务。
  • 侦察数据过时 — 超过 30 天的子域名数据会越来越不可靠。每次参与测试时都要更新侦察数据。

相关技能与链路

  • 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 payload 库的 payload 类别查询。
  • bb-methodology — 当侦察完成且阶段 1 转入阶段 2(映射)时使用。工作流基元:将活动主机和 URL 集交回 bb-methodology 阶段 2 进行端点映射,并交由阶段 3 路由漏洞发现工作。

评论

支持 Markdown