attack-surface-mapping
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAttack Surface Mapping
攻击面测绘
Given one target and one application, draw the surface from what that application already exposes. Then stop. Testing lives in other skills.
This skill is the fast path. Success is a portrait plus a host/API inventory plus a key table plus response-class labels plus an object graph. A probe count is not success.
Field patterns for where the rest of the surface actually lives: SURFACE_PATTERNS.md.
给定一个目标和一个应用,从该应用已经暴露的内容绘制攻击面,然后停止。测试属于其他 skill。
本 skill 是快速路径。成功意味着一份画像 + 主机/API 清单 + 密钥表 + 响应类别标记 + 对象图。探测次数不是成功。
其余攻击面实际所在位置的字段模式:SURFACE_PATTERNS.md。
When
何时使用
- A new URL, a new app, or "I only see a login page"
- Need to know what to test before loading injection / auth / upload skills
- The agent is about to brute directories, spray quotes, or expand to unrelated hosts
Do not use this skill to expand an organization-wide host universe. Map the current application cluster. Finish it. Then, if scope allows, take the next cluster.
Authorization and destruction bounds: hack start gate. Stay in scope.
- 一个新 URL、一个新应用,或“我只看到登录页面”
- 在加载 injection / auth / upload 等 skill 之前,需要知道要测什么
- agent 正要爆破目录、喷洒引号或扩展到无关主机
不要使用本 skill 去扩展组织级的主机范围。只测绘当前应用集群,完成它。然后,如果授权范围允许,再处理下一个集群。
授权与破坏边界:以 hack 的起始门禁为准。保持在授权范围内。
What must exist (not a file tree)
必须具备的事实(不是文件树)
Before any vulnerability skill, these facts must be retrievable. Persist them in whatever the local workspace already uses for notes and evidence — an existing task folder, a proxy project, session notes, a ticket. Do not invent a new directory layout when one is already in play.
| Fact | Keep |
|---|---|
| Portrait | 3–5 sentences, not an essay |
| Hosts | Business hosts, gateways, API domains this app already named |
| Endpoints | Method, path, params, auth required? |
| Keys | Signing salt, ciphertext id + frontend pubkey, hidden/admin route, hardcoded demo account. Record |
| Response class | Login-gate / differential / unauthenticated exception |
| Object graph | list → detail → attachment / export / approval |
Requests, diffs, and screenshots stay where they were captured when that store is already the working set. Empty inventory plus "I will brute paths next" is a failed mapping.
在任何漏洞 skill 之前,这些事实必须可检索。将它们持久化到本地工作区已经用于笔记和证据的地方——现有任务文件夹、代理项目、会话笔记、工单。如果已有目录结构,不要另建新的目录布局。
| 事实 | 保留内容 |
|---|---|
| 画像 | 3–5 句话,不是一篇长文 |
| 主机 | 该应用已提到的业务主机、网关、API 域名 |
| 端点 | 方法、路径、参数、是否需要认证 |
| 密钥 | 签名盐、密文 ID + 前端公钥、隐藏/管理后台路由、硬编码演示账号。若没有,每行记录 |
| 响应类别 | 登录门禁 / 差异响应 / 未认证异常 |
| 对象图 | 列表 → 详情 → 附件 / 导出 / 审批 |
请求、差异和截图保留在它们被捕获的地方,只要该存储已经是工作集合。空清单加上“我接下来要爆破路径”就是失败的测绘。
Fast path
快速路径
Portrait
→ find the business plane (login is a shell)
→ inventory from the app (JS / traffic / docs), keys not just paths
→ classify responses
→ grow the object graph from responses
→ same-skin / same-gate collapse
→ surface-done → hand offDo not insert directory brute, full-template scanning, or password spraying into this loop.
Portrait
→ find the business plane (login is a shell)
→ inventory from the app (JS / traffic / docs), keys not just paths
→ classify responses
→ grow the object graph from responses
→ same-skin / same-gate collapse
→ surface-done → hand off不要在这个循环中插入目录爆破、全模板扫描或密码喷洒。
1. Portrait (mandatory, before any request spray)
1. 画像(强制,在任何请求喷洒之前)
Three to five sentences:
- Who uses this (consumer / merchant / operator)
- Core objects (order, ticket, coupon, document, tenant)
- Which fields hold money, privilege, or state
- What an unauthenticated caller can already touch
Cannot write it → capture one real page's traffic first. Do not scan into a blank portrait.
Mini-program, native app, GraphQL, WebSocket, batch export, agent-with-tools, template preview, file convert, command RPC: treat as this site's surface, not a sidenote.
3–5 句话:
- 谁在使用(消费者 / 商家 / 运营者)
- 核心对象(订单、票据、优惠券、文档、租户)
- 哪些字段包含金钱、权限或状态
- 未认证调用者已经可以触及什么
写不出来 → 先捕获一个真实页面的流量。不要对着空白的画像开始扫描。
小程序、原生应用、GraphQL、WebSocket、批量导出、带工具的 agent、模板预览、文件转换、命令 RPC:都视为本站点攻击面,不是边角料。
2. Find the business plane
2. 找到业务平面
A login page is a shell. The surface is the post-login business host or the same-host gateway behind the form. Seeing a login page is not a reason to change assets.
Find the plane without logging in:
- Query: /
service=/redirect_uri=/callback=/returnUrl=/jumpUrl=next= - Client: /
env.js/baseURL/apiHost//prod-api/VUE_APP_*REACT_APP_* - Transport: 302 ,
LocationX-Frame-Options: ALLOW-FROM - Naming: same-product /
api/admin/ product hostgateway
Someone else's SSO / CAS / OAuth page: do not audit the identity product. Follow it back to this product's business plane. Criterion: the login page's owner is not this business.
Alive vs dead:
| Treat as alive | Treat as dead |
|---|---|
| 401, 403, login wall, admin challenge | Timeout, parking page, no business response |
| Management console challenge | Default CDN / empty static shell with no script |
Alive ≠ grind the form. Captcha OCR, slider farms, and login-box dictionaries are not mapping.
Form checks that are in-scope for mapping (once, then stop): empty password, skip-password step, extra fields on the login API ( / / ), business paths already visible next to the form (list / detail / stats). Username and password boxes are not business parameters.
tenantcorpIdmoduleId登录页只是一个外壳。攻击面是登录后的业务主机,或表单背后的同主机网关。看到登录页不是更换资产的理由。
不登录也能找到业务平面:
- Query: /
service=/redirect_uri=/callback=/returnUrl=/jumpUrl=next= - Client: /
env.js/baseURL/apiHost//prod-api/VUE_APP_*REACT_APP_* - Transport: 302 ,
LocationX-Frame-Options: ALLOW-FROM - Naming: same-product /
api/admin/ product hostgateway
别人的 SSO / CAS / OAuth 页面:不要审计身份产品。沿它回到本产品的业务平面。判断标准:登录页的所有者不是本业务。
存活 vs 无效:
| 视为存活 | 视为无效 |
|---|---|
| 401、403、登录墙、管理挑战 | 超时、停放页、无业务响应 |
| 管理控制台挑战 | 默认 CDN / 没有脚本的空静态壳 |
存活 ≠ 死磕表单。验证码 OCR、滑块农场和登录框字典都不是测绘。
在测绘范围内允许的表单检查(只做一次,然后停止):空密码、跳过密码步骤、登录 API 上的额外字段( / / )、表单旁边已经可见的业务路径(list / detail / stats)。用户名和密码框不是业务参数。
tenantcorpIdmoduleId3. Inventory from the application
3. 从应用建立清单
Frontend present: open a business page → collect scripts (including async chunks and sourcemaps) → extract APIs and keys → capture traffic to fill gaps → persist endpoints and keys in the local evidence store.
JS extracts more than paths. For each row, write the value or :
/api/none| Extract | Why it is surface |
|---|---|
| Endpoint list |
Signing salt, hardcoded key, | Replay without a session |
Ciphertext id + frontend public key ( | Neighbor-id is encryptable |
| Hidden / admin routes in the router, unpublished chunks | APIs the UI never shows |
| Hardcoded demo account, test tenant, experience entry | A key, not a login-form dictionary |
| Command / template / expression / file-convert / RPC-with-exec / agent tools | Execution plane; do not invent params if none exist |
No frontend / JS blocked: Swagger, OpenAPI, captured traffic, HTML inline, known gateway prefixes. Do not idle waiting for a full JS dump.
Frontend present but inventory empty → directory brute is forbidden.
Docs and debug planes, if this app already linked them: api-recon-and-docs. Exposed VCS / backups: insecure-source-code-management. Both are this cluster's extra planes, not a new search.
有前端: 打开一个业务页面 → 收集脚本(包括异步 chunk 和 sourcemap)→ 提取 API 和密钥 → 捕获流量补缺口 → 将端点和密钥持久化到本地证据存储。
JS 能提取的不只是 路径。对每一行,写下值或 :
/api/none| 提取项 | 为什么它是攻击面 |
|---|---|
| 端点列表 |
签名盐、硬编码密钥、不需要 cookie 的 | 无会话重放 |
密文 ID + 前端公钥( | 相邻 ID 可被加密 |
| 路由中的隐藏 / 管理后台路由、未发布的 chunk | UI 从不展示的 API |
| 硬编码演示账号、测试租户、体验入口 | 是一个密钥,不是登录框字典 |
| 命令 / 模板 / 表达式 / 文件转换 / 带执行的 RPC / 工具类 agent | 执行平面;如果没有参数就不要编造参数 |
没有前端 / JS 被阻止: 使用 Swagger、OpenAPI、已捕获流量、HTML 内联、已知网关前缀。不要空等完整的 JS 转储。
有前端但清单为空 → 目录爆破是被禁止的。
如果该应用已经链接了文档和调试平面:api-recon-and-docs。暴露的 VCS / 备份:insecure-source-code-management。两者都是本集群的额外平面,不是新的搜索。
4. Classify responses before any probe
4. 在任何探测前先对响应分类
| Response | Class | Mapping action |
|---|---|---|
One sentence "please log in" / | Login gate | Do not mark as an injection surface |
Has list / total / business fields, even | Differential | Keep on the test list |
| Error, 500, timeout, or length/timing off baseline | Differential | Keep; unstable diff → stop after one or two compares |
| Missing a parameter dumps a roster or detail | Unauthenticated exception | Highest-priority unauth surface |
An empty list is "structure returned, count is 0", not a login gate.
| 响应 | 类别 | 测绘动作 |
|---|---|---|
一句话“请登录” / | 登录门禁 | 不要标记为注入攻击面 |
有列表 / total / 业务字段,即使 | 差异响应 | 保留在测试列表中 |
| 报错、500、超时,或长度/时间偏离基线 | 差异响应 | 保留;差异不稳定 → 比较一两次后停止 |
| 缺少参数就返回花名册或详情 | 未认证异常 | 最高优先级的未认证攻击面 |
空列表是“返回了结构,计数为 0”,不是登录门禁。
5. Object graph is surface
5. 对象图就是攻击面
Identifiers in any field name ( / / / / / ciphertext PK) are surface.
iduserIdtenantIdfileKeyopenidWalk, and write it down:
list → detail → attachment / export / preview / approvalParent authorized, child often not. After a list passes, the next surface is the attachment, not a new host.
Anything a response newly names — id, download URL, token, internal host, role field — goes onto this site's queue immediately. Do not drop it when changing pages.
任何字段名中的标识符( / / / / / 密文主键)都是攻击面。
iduserIdtenantIdfileKeyopenid遍历并记录下来:
list → detail → attachment / export / preview / approval父级已授权,子级往往没有。列表通过后,下一个攻击面是附件,而不是新主机。
响应中新出现的任何东西——id、下载 URL、token、内部主机、角色字段——立即加入本站点的队列。切换页面时不要丢掉它。
6. Collapse same-skin and same-gate
6. 合并同皮肤与同网关
Fingerprint-same (title, skeleton, build hash, API prefix, login chain): pick 2–3 representatives. Siblings only get a glance: new path / new port / another app / another / / business plane. No new plane → do not open a full matrix.
jumpservice=moduleIdSame-gate (all four):
- Business paths already extracted
- Unauthenticated exceptions already probed
- Remaining business endpoints return the same login-code family
- No unauthenticated other-subject data, and no missing-param dump
Then stop this gate. Siblings with the same + same code: glance for new paths or a code change. Auth endpoints (issue session / reset / rebind / ticket-swap) still go on the list if present; they are not "please log in, so skip".
baseURLSame host is not same-skin. Extra paths on the same host always expand.
No business script, default server page, or leftover behind the same login-code family: falsify once and leave. Do not pad with a full matrix.
指纹相同(标题、骨架、构建哈希、API 前缀、登录链):选 2–3 个代表。兄弟节点只扫一眼:新路径 / 新端口 / 另一个应用 / 另一个 / / 业务平面。没有新平面 → 不要铺开完整矩阵。
jumpservice=moduleId同网关(全部四条):
- 业务路径已被提取
- 未认证异常已被探测
- 其余业务端点返回同一登录码族
- 没有未认证的其他主体数据,也没有缺参转储
然后停止这个网关。相同 + 相同代码的兄弟节点:扫一眼新路径或代码变化。认证端点(发会话 / 重置 / 重新绑定 / 票据交换)如果存在仍要列入清单;它们不是“请登录,所以跳过”。
baseURL同主机不是同皮肤。同一主机上的额外路径总是要扩展。
同一登录码族后面没有业务脚本、默认服务器页面或遗留物:证伪一次然后离开。不要用完整矩阵凑数。
7. Surface-done (then hand off)
7. 攻击面完成(然后交接)
Mapping is done when:
- Portrait exists, or this is recorded as a shell with no business object
- Endpoint inventory exists (full or degraded); keys have values or — in the local evidence store, not a prescribed path
none - Response classes labeled; unauthenticated exceptions ticked
- Object graph recorded, or recorded as unlistable
- Same-skin / same-gate leftovers glanced, not rematrixed
- Auth endpoints listed if the inventory has issue-session / reset / rebind / ticket-swap / 2FA — listed, not yet exploited
Then load hack for effort order and the matching category skill. Do not start testing inside this file.
满足以下条件时测绘完成:
- 画像存在,或已被记录为没有业务对象的外壳
- 端点清单存在(完整或降级);密钥有值或 ——保存在本地证据存储中,不是指定的路径
none - 响应类别已标记;未认证异常已勾选
- 对象图已记录,或记录为不可列举
- 同皮肤 / 同网关残留已扫一眼,没有重新铺矩阵
- 如果清单中有发会话 / 重置 / 重新绑定 / 票据交换 / 2FA,则列出认证端点——只列出,尚未利用
然后加载 hack 以确定投入顺序和匹配的分类 skill。不要在这个文件里开始测试。
Handoff
交接
| Surface you drew | Load |
|---|---|
| Unauthenticated other-subject data, object ids | auth-sec, idor-broken-object-authorization |
| Issue-session / reset / rebind / ticket-swap | authbypass-authentication-flaws |
| Differential filters, URL-fetch params, templates | injection-checking |
| Upload / preview / convert | upload-insecure-files |
| Money / coupon / stock / approval | business-logic-vuln |
| REST / GraphQL / gateway docs | api-sec |
| Public middleware admin | unauthorized-access-common-services |
| 你绘制的攻击面 | 加载 |
|---|---|
| 未认证的其他主体数据、对象 ID | auth-sec、idor-broken-object-authorization |
| 发会话 / 重置 / 重新绑定 / 票据交换 | authbypass-authentication-flaws |
| 差异过滤、URL 拉取参数、模板 | injection-checking |
| 上传 / 预览 / 转换 | upload-insecure-files |
| 金钱 / 优惠券 / 库存 / 审批 | business-logic-vuln |
| REST / GraphQL / 网关文档 | api-sec |
| 公开中间件管理后台 | unauthorized-access-common-services |
Anti-patterns
反模式
- Opening with directory brute or full-template scanning
- Grinding captcha / default passwords on login HTML
- Seeing a login page and changing assets
- Script extracted only paths; salts, ciphertext ids, hidden routes, demo accounts unread
- Treating 401 / 403 / login wall as dead
- Pouring a full matrix into the same login-code family
- Expanding to a new cluster while this application's live surface is unfinished
- Calling mapping "done" because the homepage returned 200
- Minting a new notes tree when the workspace or proxy project already holds the evidence
- 以目录爆破或全模板扫描开头
- 死磕登录 HTML 上的验证码 / 默认密码
- 看到登录页就更换资产
- 脚本只提取了路径;盐、密文 ID、隐藏路由、演示账号未读取
- 把 401 / 403 / 登录墙视为无效
- 对同一登录码族铺开完整矩阵
- 当前应用的活跃攻击面尚未完成时就扩展到新集群
- 因为首页返回 200 就宣称测绘“完成”
- 当工作区或代理项目已经持有证据时,新建一套笔记目录