attack-surface-mapping について
attack-surface-mappingは、脆弱性テストの前に単一のWebアプリの露出面を整理するセキュリティスキルです。エージェントがスコープを守りながら、ホスト、エンドポイント、キー、応答分類、オブジェクト関係を記録します。
主な機能
- 01アプリの概要を作成
- 02ホスト、エンドポイント、キーの一覧化
- 03応答の分類
- 04業務オブジェクトの関係を追跡
- 05重複する画面と認証ゲートを整理
- 06整理した対象をテストへ引き継ぎ
活用シーン
- 01新たに見つかったアプリの調査
- 02脆弱性テスト前の対象一覧作成
- 03最初にログイン画面だけが見えるアプリの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill attack-surface-mappingインストール後、Claude Code で/attack-surface-mappingを入力して読み込まれたか確認します。
同梱ファイルSURFACE_PATTERNS.md
詳細
攻撃対象領域のマッピング
1 つのターゲットと1 つのアプリケーションを対象に、そのアプリケーションがすでに公開している情報から攻撃対象領域を描きます。その後は終了です。テストはほかのスキルで行います。
このスキルは最短ルートです。成功の条件は、全体像、ホスト/API の一覧、キーの表、レスポンスクラスのラベル、オブジェクトグラフがそろっていることです。プローブの回数は成功の指標ではありません。
攻撃対象領域の残りがどこにあるかを見つけるための現場パターンは、SURFACE_PATTERNS.md を参照してください。
使用するタイミング
- 新しい URL、新しいアプリケーション、または「ログインページしか見えない」とき
- インジェクション/認証/アップロードのスキルを使う前に、何をテストすべきか把握する必要があるとき
- エージェントがディレクトリを総当たりしたり、クォートを大量に送りつけたり、無関係なホストに対象を広げようとしているとき
このスキルを使って、組織全体のホスト一覧を広げてはいけません。現在のアプリケーションクラスターをマッピングして完了してください。その後、スコープが許す場合に次のクラスターに進みます。
許可と破壊行為の制限については、hack の開始ゲートを参照してください。スコープ内に留まってください。
必要なもの(ファイルツリーではありません)
脆弱性に関するスキルを使う前に、以下の事実を取得できるようにしておく必要があります。メモや証拠を保存する際は、既存のタスクフォルダー、プロキシプロジェクト、セッションメモ、チケットなど、ローカルワークスペースですでに使われている場所を利用してください。すでに運用中の場所がある場合は、新しいディレクトリ構成を作らないでください。
| 事実 | 記録する内容 |
|---|---|
| 全体像 | エッセイではなく、3~5 文 |
| ホスト | このアプリケーションがすでに示している業務ホスト、ゲートウェイ、API ドメイン |
| エンドポイント | メソッド、パス、パラメーター、認証が必要か |
| キー | 署名ソルト、暗号文 ID とフロントエンド公開鍵、非公開/管理者向けルート、ハードコードされたデモアカウント。存在しない場合は行ごとに none と記録 |
| レスポンスクラス | ログインゲート/差異あり/未認証例外 |
| オブジェクトグラフ | 一覧 → 詳細 → 添付ファイル/エクスポート/承認 |
リクエスト、差分、スクリーンショットは、すでに作業用データとして使われている保存先がある場合、その取得先に残してください。インベントリが空のまま「次はパスを総当たりする」と言うのは、マッピングに失敗しています。
最短ルート
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. 全体像(必須。リクエストを大量送信する前に実施)
3~5 文で、以下を記述します。
- 誰が使うか(消費者/加盟店/運用担当者)
- 中心となるオブジェクト(注文、チケット、クーポン、ドキュメント、テナント)
- 金銭、権限、状態を保持するフィールド
- 未認証の呼び出し元がすでに触れられるもの
書けない場合は、まず実際のページのトラフィックを 1 つ取得してください。全体像が空のままスキャンを始めないでください。
ミニプログラム、ネイティブアプリ、GraphQL、WebSocket、一括エクスポート、ツールを持つエージェント、テンプレートプレビュー、ファイル変換、コマンド RPC は、付随的なものではなく、このサイトの攻撃対象領域として扱ってください。
2. 業務プレーンを見つける
ログインページは外殻です。攻撃対象領域となるのは、ログイン後の業務ホスト、またはフォームの背後にある同一ホスト上のゲートウェイです。ログインページが見えても、対象資産を変える理由にはなりません。
ログインせずに業務プレーンを見つけます。
- クエリ:
service=/redirect_uri=/callback=/returnUrl=/jumpUrl=/next= - クライアント:
env.js/baseURL/apiHost//prod-api/VUE_APP_*/REACT_APP_* - 通信:302
Location、X-Frame-Options: ALLOW-FROM - 命名:同一製品の
api/admin/gateway/ 製品ホスト
他社の SSO/CAS/OAuth ページの場合、その ID 製品を監査してはいけません。この製品の業務プレーンまでたどってください。判断基準は、ログインページの所有者がこの業務の提供者ではないことです。
稼働中か停止中か:
| 稼働中として扱う | 停止中として扱う |
|---|---|
| 401、403、ログイン画面、管理者チャレンジ | タイムアウト、パーキングページ、業務レスポンスがない |
| 管理コンソールのチャレンジ | デフォルトの CDN/スクリプトがない空の静的外殻 |
稼働中だからといって、フォームを延々と試すわけではありません。CAPTCHA の OCR、スライダーファーム、ログインボックスの辞書攻撃はマッピングではありません。
マッピングの範囲内で行うフォームの確認(1 回だけ行い、その後は停止):空のパスワード、パスワードを省略するステップ、ログイン API にある追加フィールド(tenant / corpId / moduleId)、フォームの近くですでに見えている業務パス(一覧/詳細/統計)。ユーザー名とパスワードの入力欄は業務パラメーターではありません。
3. アプリケーションからのインベントリ
フロントエンドあり: 業務ページを開く → スクリプトを収集する(非同期チャンクとソースマップを含む)→ API とキーを抽出する → 不足分を補うためにトラフィックを取得する → エンドポイントとキーをローカルの証拠ストアに保存する。
JS は /api/ パス以外も抽出します。各行について、値または none を記入します。
| 抽出対象 | 露出面である理由 |
|---|---|
/api/ パス、RPC コマンド番号、GraphQL オペレーション | エンドポイント一覧 |
署名用ソルト、ハードコードされたキー、Cookie を必要としない sign | セッションなしでリプレイ可能 |
暗号文 ID + フロントエンドの公開鍵(modulus/JSEncrypt) | 隣接 ID を暗号化可能 |
| ルーター内の非表示/管理者用ルート、未公開チャンク | UI に表示されない API |
| ハードコードされたデモアカウント、テストテナント、エクスペリエンスのエントリ | ログインフォーム用の辞書ではなく、キー |
| コマンド/テンプレート/式/ファイル変換/実行機能付き RPC/エージェントツール | 実行プレーン。存在しないパラメーターを捏造しないこと |
フロントエンドなし/JS がブロックされている場合: Swagger、OpenAPI、取得済みトラフィック、HTML のインライン要素、既知のゲートウェイプレフィックスを確認します。JS の完全なダンプを待ち続けないでください。
フロントエンドがあるのにインベントリが空 → ディレクトリブルートフォースは禁止です。
このアプリですでにリンクされている場合は、ドキュメントとデバッグプレーンを確認します:api-recon-and-docs。VCS の露出/バックアップについては、insecure-source-code-management を参照してください。どちらもこのクラスターにおける追加プレーンであり、新たな検索ではありません。
4. プローブを行う前にレスポンスを分類する
| レスポンス | 分類 | マッピング時の対応 |
|---|---|---|
「ログインしてください」という一文/NotLogin のみで、リスト/合計/名簿/詳細がない | ログインゲート | インジェクション対象の露出面としてマークしない |
リスト/合計/業務フィールドがある(total=0 を含む) | 差分あり | テスト対象リストに残す |
| エラー、500、タイムアウト、またはベースラインと長さ/タイミングが異なる | 差分あり | 対象に残す。不安定な差分は比較を1~2回行った時点で停止する |
| パラメーターがないと名簿または詳細が出力される | 未認証の例外 | 最優先の未認証露出面 |
空のリストは「構造が返され、件数が0」であり、ログインゲートではありません。
5. オブジェクトグラフも露出面
フィールド名に含まれる識別子(id/userId/tenantId/fileKey/openid/暗号文 PK)は露出面です。
たどって、記録します。
list → detail → attachment / export / preview / approval
親へのアクセスが認可されていても、子へのアクセスは認可されていないことがよくあります。リストを確認した後の次の露出面は添付ファイルであり、新しいホストではありません。
レスポンスによって新たに示されたもの(ID、ダウンロード URL、トークン、内部ホスト、ロールフィールドなど)は、すぐにこのサイトのキューに追加します。ページを移動しても削除しないでください。
6. 同じ外観と同じゲートをまとめる
フィンガープリントが同じ(タイトル、スケルトン、ビルドハッシュ、API プレフィックス、ログインチェーン)なら、代表を2~3件選びます。同じグループのものは、新しいパス/新しいポート/別のアプリ/別の jump/service=/moduleId の業務プレーンだけをざっと確認します。新しいプレーンがなければ、完全なマトリクスを開かないでください。
同じゲート(次の4項目すべてに該当):
- 業務パスをすでに抽出している
- 未認証の例外をすでにプローブしている
- 残りの業務エンドポイントが同じログインコード群を返す
- 未認証で他の対象者のデータを取得できず、パラメーター欠落による出力もない
このゲートの確認を終了します。同じ baseURL +同じコードの同一グループは、新しいパスまたはコードの変化だけをざっと確認します。認証エンドポイント(セッション発行/リセット/再バインド/チケット交換)が存在する場合は、引き続きリストに加えます。「ログインしてください、だからスキップ」には該当しません。
同じホストでも、同じ外観とは限りません。同じホスト上の追加パスは、必ず確認対象を拡大します。
業務スクリプトもなく、デフォルトのサーバーページ、または同じログインコード群の背後に残るものだけなら、一度だけ反証を試みて終了します。完全なマトリクスで水増ししないでください。
7. サーフェスのマッピングを完了してから引き継ぐ
以下を満たしたらマッピングは完了です。
- ポートレートが存在する、またはビジネスオブジェクトを持たないシェルとして記録されている
- エンドポイント一覧が存在する(完全なもの、または不完全なもの)。キーには値または
noneが設定されている。規定のパスではなく、ローカルのエビデンスストアに保存されている - レスポンスの種類にラベルが付けられている。認証不要の例外にはチェックが付いている
- オブジェクトグラフが記録されている、または一覧化できないものとして記録されている
- 同じスキン/同じゲートに残る項目をざっと確認しているが、マトリックスを作り直していない
- 一覧に issue-session/reset/rebind/ticket-swap/2FA が含まれている場合、認証エンドポイントを列挙している。列挙のみで、まだ悪用していない
次に、取り組む順序と該当するカテゴリスキルを確認するため、hack を読み込みます。このファイル内ではテストを開始しないでください。
引き継ぎ
| マッピングしたサーフェス | 読み込むもの |
|---|---|
| 認証なしで取得できる他ユーザーのデータ、オブジェクト ID | auth-sec、idor-broken-object-authorization |
| issue-session/reset/rebind/ticket-swap | authbypass-authentication-flaws |
| 差分フィルター、URL フェッチ用パラメーター、テンプレート | injection-checking |
| アップロード/プレビュー/変換 | upload-insecure-files |
| 金銭/クーポン/在庫/承認 | business-logic-vuln |
| REST/GraphQL/ゲートウェイのドキュメント | api-sec |
| 公開ミドルウェアの管理機能 | unauthorized-access-common-services |
アンチパターン
- ディレクトリブルートやテンプレート全体のスキャンから始める
- ログイン HTML に対して CAPTCHA やデフォルトパスワードを延々と試す
- ログインページを見て、アセットを変更する
- スクリプトでパスだけを抽出し、ソルト、暗号文 ID、非表示ルート、デモアカウントは未確認のままにする
- 401/403/ログイン画面を行き止まりと見なす
- 同じログインコードのファミリーに対して、マトリックス全体を延々と投入する
- このアプリケーションの稼働中のサーフェスが未完了のまま、新しいクラスターに対象を広げる
- ホームページが 200 を返しただけで、マッピングを「完了」とする
- ワークスペースまたはプロキシプロジェクトにすでにエビデンスがあるのに、新しいメモツリーを作る