mcpField
H
hunt-schema-enumeration

hunt-schema-enumeration

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

关于 hunt-schema-enumeration

面向 API 安全测试人员的黑盒架构枚举技能,利用结构化错误信息和查询响应发现表名、字段名及接口路径。内容涵盖 PostgREST、验证错误与 GraphQL,并说明验证结果及其局限。

主要功能

  1. 01利用 PostgREST 提示发现表名
  2. 02从验证错误提取字段信息
  3. 03执行 GraphQL 内省查询
  4. 04通过词表模糊测试表名
  5. 05提供结果确认与误报辨别

适用场景

  1. 01绘制 PostgREST API 的数据表结构
  2. 02检查接口错误是否泄露字段要求
  3. 03在 GraphQL 内省受限时查找类型线索
  4. 04为后续授权写操作测试定位接口

安装

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

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-schema-enumeration

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

详细介绍

适用场景

目标 API 会返回结构化错误消息(JSON),提示有效的表名、字段名或端点路径。这是针对 REST/GraphQL API 最有效的黑盒侦察方法——一次模糊测试请求就能揭示整个数据库架构。

最常见于:PostgREST(Supabase)、FastAPI(.NET)、Zod(Next.js/Node)、tRPC、GraphQL,以及任何在生产环境中启用了验证错误详情的框架。


阶段 1 — PostgREST 错误提示枚举

PostgREST 是 Supabase/PostgreSQL 的 REST API 层。查询不存在的表时,它会返回一条提示,其中包含真实表名。

SUPABASE_URL="https://PROJECT.supabase.co"
ANON_KEY="eyJ..."

# Fuzz with common table names — read the hints
for table in users profiles posts products orders data config settings; do
  echo "=== $table ==="
  curl --max-time 30 --connect-timeout 10 -sk "${SUPABASE_URL}/rest/v1/${table}?select=*&limit=1" \
    -H "apikey: ${ANON_KEY}" \
    -H "Authorization: Bearer ${ANON_KEY}" 2>/dev/null | python3 -c "
import sys,json
d=json.load(sys.stdin)
hint=d.get('hint','')
if hint: print(f'  -> {hint}')
"
done

# The response pattern:
# {"hint":"Perhaps you meant the table 'public.real_table_name'"}
# {"hint":"Perhaps you meant the table 'public.user_sessions'"}

构建用于定向模糊测试的词表:

# Common patterns found in field:
# - Game apps: hands, scores, sessions, players, items, inventory
# - SaaS: subscriptions, subscribers, billing, invoices, teams, api_keys  
# - Health: patients, appointments, assessments, prescriptions
# - Gov: citizens, certificates, documents, protocols
# - Finance: transactions, accounts, wallets, withdrawals, deposits

阶段 2 — 挖掘 Zod/FastAPI 验证错误

现代框架会返回详细的验证错误,暴露所有预期字段。

FastAPI(.NET/Go)
# POST with empty body or wrong fields
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://api.target.com/endpoint" \
  -H "Content-Type: application/json" -d '{}' 2>/dev/null
# Response reveals ALL required fields:
# {"errors":{"usuario":["required"],"senha":["required"]}}
Zod(Next.js/Node)
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/api/workspaces" \
  -H "Content-Type: application/json" -d '{}' 2>/dev/null
# Response: {"error":{"name":"ZodError","message":"[\n  {\"expected\":\"string\",\"path\":[\"name\"]}\n]"}}

阶段 3 — GraphQL 内省

# Standard introspection query
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://target.com/graphql" \
  -H "Content-Type: application/json" \
  -d '{"query":"{__schema{types{name fields{name type{name}}}}}"}' 2>/dev/null

# Even if introspection is disabled, error messages reveal type names:
# "Cannot query field 'x' on type 'User'. Did you mean 'users'?"

阶段 4 — 积极进行表名模糊测试

生成一个综合词表,其中包含:

# 1. From JS bundle analysis
grep -Eo 'from\(["\x60][a-zA-Z_]+["\x60]\)' /tmp/target.js | sort -u

# 2. From common patterns
# Singular/plural: user/users, post/posts, product/products
# Snake/camel: user_sessions, userSessions, UserSessions
# Domain-specific: appointments, patients, assessments, certificates

# 3. Systematic fuzz
for table in $(cat /tmp/wordlist.txt); do
  curl --max-time 30 --connect-timeout 10 -sk -w "%{http_code}" "${BASE}/rest/v1/${table}?select=count" \
    -H "apikey: ${KEY}" 2>/dev/null | tee -a /tmp/fuzz_results.txt
done

验证

  • 确认命中 PostgREST:响应为 [](空数组 = 表存在,但 RLS 阻止读取)或返回了数据
  • 确认命中 Zod:错误列出了预期的确切字段名和类型
  • 确认命中 FastAPI:返回 422,且 detail 数组列出了缺失字段
  • 误报:通用的 404 HTML 页面(不是 JSON 错误)

下一步

  • 如果 PostgREST 提示揭示了表 → 继续使用 hunt-write-gap(测试 PATCH/POST/DELETE)
  • 如果 Zod 错误揭示了字段 → 测试 hunt-business-logic(批量赋值、篡改价格)
  • 如果 FastAPI 揭示了身份验证架构 → 测试 jwt-attack 或 api-noauth-hunt
  • 架构枚举总会引向下一步攻击,不会是最终步骤

验证

运行此自测,确认已准备好进行架构枚举搜寻:

  1. 技能完整性 — 确认技能文件可读且格式正确:

    grep -q "name: hunt-schema-enumeration" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL"
    grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL"
    
  2. 类别检查 — 确认技能包含类别:

    grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
    
  3. 陷阱部分 — 确认已记录陷阱:

    grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
    

这 3 项测试可验证技能结构正确且已准备好使用。


陷阱

  • 枚举架构但未发现敏感字段 — 了解 API 架构属于侦察。需要证明存在可利用的字段/变更操作。
  • 通过内省获取 GraphQL 架构 — 内省是功能,不是漏洞(除非生产环境明确禁用了它)。
  • 通过错误消息获取数据库架构 — SQL 错误泄露表名属于信息泄露,而不是特定于架构的问题。应根据泄露内容评估。
  • OpenAPI 规范可公开访问 — /swagger.json 或 /openapi.json 是为 API 使用者提供的公开资源。应根据暴露的管理/内部端点评估。

评论

支持 Markdown