mcpField
A
attack-path-stitcher

attack-path-stitcher

github.com/transilienceaiセキュリティ5981.4k 回インストール13 週間前に更新
リポジトリ

attack-path-stitcher について

Attack Path Stitcher は、資産ごとの検証済み所見を、証拠に基づく攻撃経路グラフにまとめるセキュリティスキルです。確定経路と推定経路を分け、cloud-agent task #6 向けに JSON、DOT、Markdown のレポートを出力します。

主な機能

  1. 01資産とピボットのグラフ構築
  2. 02証拠に基づく7種類の検出器
  3. 03確定経路と推定経路の分離
  4. 04crown_jewel への到達性分析
  5. 05JSON、DOT、Markdown の出力
  6. 06読み取り専用処理とグラフ規模制限

活用シーン

  1. 01資産間の認証情報再利用の追跡
  2. 02crown_jewel への外部侵入口の特定
  3. 03確定経路と推定経路の順位付き確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/transilienceai/communitytools --skill attack-path-stitcher

インストール後、Claude Code で/attack-path-stitcherを入力して読み込まれたか確認します。

同梱ファイルreference/edge-detectors.md

詳細

攻撃経路の連結

Validation Run タスク(#3)では、資産ごとに確認済みの所見が生成されます。実際の攻撃者リスクは攻撃チェーンにあります。資産 A の所見によって認証情報が漏えいし、それを使って資産 B の所見が可能になり、さらに資産 C へと侵入範囲が広がります。このスキルは、そのグラフを構築します。

cloud-agent タスク #6 にマウントされています。

トリガー

毎日の Cron(デフォルトは 03:00 UTC)。Validation Run タスクのバッチ完了後に再実行する場合もあります。

ワークフロー

  1. 入力を読み込みます。
    • validated/*.json — すべてのエンゲージメントにわたる、確認済みの所見。
    • artifacts/org-surface.json — 組織全体のサーフェスグラフ(資産、サービス、ネットワークゾーン、信頼関係)。
    • findings/finding-NNN/evidence/raw-source.txt — 連結時に認証情報/トークンを抽出するために使用します。
  2. 資産ノードを構築します。 org-surface.json 内の資産ごとに 1 つのノードを作成し、tier、services、network_zone、trust_relationships を属性として設定します。
  3. エッジを構築します — 検出されたピボットごとに 1 つのエッジを作成します。7 つの検出器については reference/edge-detectors.md を参照してください。
    • 認証情報の再利用(A で漏えいした認証情報を B の認証に再利用)
    • 共有シークレット/API キー(同じシークレットが 2 つの資産の証拠に存在)
    • 信頼ゾーンをまたぐ推移的なアクセス(ゾーン X 内の A から、同じゾーン X 内の B へ暗黙的に到達可能)
    • AD パスのホップ(kerberoast/DC sync/RBCD のチェーン)
    • クラウド IAM ロールチェーン(侵害された資産から assume-role)
    • SSRF → 内部資産への到達(A の SSRF によって B の内部エンドポイントに到達)
    • サプライチェーン(source-code-scanning の SBOM に基づき、A が B の依存関係にある)
  4. 到達可能性の閉包を計算します。 crown_jewel ティアの各ノードについて、エッジを逆方向にたどる BFS を実行し、そこへ到達できる外部公開ノードをすべて見つけます。これらを「エントリーポイント」としてマークします。
  5. グラフを artifacts/attack-paths.json に、人が読める DOT ファイルを artifacts/attack-paths.dot に書き込みます(Graphviz でレンダリングできます)。

実装はグラフの構築を処理する tools/chain-merger.py を通じて実行されます。このスキルはツールが参照するルールを提供し、反復処理はツールが行います。

出力

{OUTPUT_DIR}/
  artifacts/
    attack-paths.json     # nodes, edges, entry_points, crown_jewel_paths
    attack-paths.dot      # Graphviz source
    attack-paths.md       # ranked list of distinct paths (human read)

attack-paths.json のスキーマ:

{
  "generated_at": "2026-05-13T03:00:00Z",
  "nodes": [
    {"id": "asset42", "tier": "revenue", "services": ["http/443"], "zone": "dmz",
     "external": true, "findings": ["finding-012", "finding-018"], "max_cvss": 9.8}
  ],
  "edges": [
    {"src": "asset42", "dst": "asset77", "detector": "credential-reuse",
     "via_findings": ["finding-012", "finding-019"],
     "evidence": "credential (userpass) present in evidence of asset42 and asset77",
     "feasibility": 1.0}
  ],
  "entry_points": ["asset42", "asset05"],
  "confirmed_paths": [
    {"jewel": "asset99", "paths": [
      {"hops": ["asset42", "asset77", "asset99"],
       "edges": [{"src":"asset42","dst":"asset77","detector":"credential-reuse","feasibility":1.0,"via_findings":["finding-012"]},
                 {"src":"asset77","dst":"asset99","detector":"ssrf-reach","feasibility":1.0,"via_findings":["finding-024"]}],
       "feasibility": 1.0, "max_cvss": 9.8, "path_class": "confirmed"}
    ]}
  ],
  "inferred_paths": [
    {"jewel": "asset99", "paths": [
      {"hops": ["asset05", "asset99"], "edges": [...],
       "feasibility": 0.5, "max_cvss": 7.5, "path_class": "inferred"}
    ]}
  ],
  "truncation": {
    "edge_cap_hit": false, "depth_truncated_count": 0,
    "topn_dropped_count": 0, "max_depth": 8, "edge_cap": 50000
  }
}

RFP §3.3 への準拠における重要事項:confirmed_paths に含まれるのは、すべてのエッジの実現可能性が 1.0 であり、かつ各エッジが少なくとも 1 つの検証済みの所見を引用しているパスのみです。これらが RFP で求められる「確認済みの攻撃パス」です。inferred_paths には、PoC の証拠がないトポロジー/サプライチェーンのホップが含まれます。これらはアナリストのレビュー用に提示されますが、risk-prioritiser による修復 SLA の分類からは除外されます。

ルール

  1. エッジには根拠が必要です。 ピボットを裏付ける証拠が少なくとも1件の検出結果に含まれている場合にのみ、エッジを記録します。推測によるエッジは作成しません。
  2. 双方向性を前提にしてはいけません。 A から B に到達できても、B から A に到達できるとは推論しません。それぞれの方向に個別の証拠が必要です。
  3. (src, dst, detector) で重複を排除します。 同じホップを可能にする検出結果が複数ある場合は、1つのエッジにまとめ、via_findings にすべての検出結果を列挙します。
  4. 実現可能性は {1.0, 0.5, 0.25} のいずれかです。 信頼性の高い PoC の再実行は 1.0、条件付き(競合、タイミング、特定のユーザーなど)は 0.5、理論上(論理的には成立するが、実証されていない)は 0.25 です。
  5. パスの列挙数を制限します。 各クラウンジュエルについて、クラスごとに(確認済みと推定を分けて)上位10件のパスを、feasibility × max_cvss / hop_count の降順で返します。優先順位付けの後続処理向けに、グラフ全体は attack-paths.json に保存されます。
  6. 読み取り専用です。 Stitcher は PoC を再実行せず、findings/ にも触れません。読み取りのみを行います。
  7. グラフのサイズを制限します。 エッジの構築は50,000件で停止し、パス検索の深さは --max-depth(デフォルトは8ホップ)で上限を設けます。後続の利用側がパスの欠落を検出できるよう、JSON に truncation.edge_cap_hit、truncation.depth_truncated_count、truncation.topn_dropped_count を出力します。
  8. 確認済みと推定の区別は必須です。 すべてのエッジの実現可能性が1.0であり、かつ各エッジの via_findings が空でない場合にのみ、そのパスを confirmed_paths に含めます。信頼ゾーンのみ、共有シークレットのみ、サプライチェーンのみの連鎖は inferred_paths に含めます。この区分によって、「確認済みの攻撃パス」という RFP-§3.3 の主張が保証されます。
  9. 入力時にスキーマを適用します。 tools/chain-merger.py は、finding_id または asset が欠落している行、あるいは verdict != "VALID" の行を validated/{id}.json から破棄し、stderr に WARN を出力します。上流のバリデーターは projects/rfp-3.2/task-03-validation-run.md のスキーマに準拠する必要があります。

参考資料

  • reference/edge-detectors.md — 具体的なシグナルパターンを含む7つの検出ルールです。
  • projects/rfp-3.3/task-06-attack-path-stitcher.md — cloud-agent の実行時契約です。

コメント