Skip to content
Security
Skill

/attack-surface-mapping

Draw a testable attack surface from one authorized target URL or one application. Use when the user says 攻击面, 供给面, 画攻击面, map the surface, application recon, find the business host, JS inventory, or when the only visible page is login. Derive hosts, APIs, keys, and the object

From plugin
hack-skills
2.2k103 skills
Install
$ npx -y skills add yaklang/hack-skills --skill attack-surface-mapping --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/attack-surface-mapping

Context preview

The summary Claude sees to decide when to auto-load this skill.

Draw a testable attack surface from one authorized target URL or one application. Use when the user says 攻击面, 供给面, 画攻击面, map the surface, application recon, find the business host, JS inventory, or when the only visible page is login. Derive hosts, APIs, keys, and the object

SKILL.md

attack-surface-mapping.SKILL.md
name: attack-surface-mapping
description: >-
  Draw a testable attack surface from one authorized target URL or one
  application. Use when the user says 攻击面, 供给面, 画攻击面, map the surface,
  application recon, find the business host, JS inventory, or when the only
  visible page is login. Derive hosts, APIs, keys, and the object graph from
  what the app already exposes. Do not open with directory brute or payload
  spray. Use when the user runs /attack-surface-mapping.

Attack 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](./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](../hack/SKILL.md) start gate. Stay in scope.

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 `none` per row if absent | | 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.

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 off

Do not insert directory brute, full-template scanning, or password spraying into this loop.

1. Portrait (mandatory, before any request spray)

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.

2. Find the business plane

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 `Location`, `X-Frame-Options: ALLOW-FROM`
  • Naming: same-product `api` / `admin` / `gateway` / product host

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 (`tenant` / `corpId` / `moduleId`), business paths already visible next to the form (list / detail / stats). Username and password boxes are not business parameters.

3. Inventory from the application

**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 `/api/` paths. For each row, write the value or `none`:

| Extract | Why it is surface | |---|---| | `/api/` paths, RPC cmd numbers, GraphQL operations | Endpoint list | | Signing salt, hardcoded key, `sign` that does not need a cookie | Replay without a session | | Ciphertext id + frontend public key (`modulus` / JSEncrypt) | 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](../api-recon-and-docs/SKILL.md). Exposed VCS / backups: [insecure-source-code-mana

Read more
Ships withhack-skills

Master Entry → Category Entries → Deep Topic Skills One master entry, six category entries, and 102 deep topic skills across 14 security domains.

Get the whole plugin

Other skills on hack-skills.