
WindowsおよびLinuxのメモリダンプからMCP/JSON-RPCメッセージの候補をカービングし、生バイト、アドレス、検証用のSHA-256を保持するVolatility 3プラグインです。
MCPTraceは、WindowsおよびLinuxのメモリダンプからMCP/JSON-RPCメッセージ候補を抽出するためのVolatility 3プラグインです。プロセスメモリを調査してリクエスト、レスポンス、通知、ツール名、呼び出し引数を探し、復元された内容をメモリ内の位置とともに記録します。
このプロジェクトは、アナリストが検査および検証できる証拠に焦点を当てています。各アーティファクトは元のバイト列、プロセスID、仮想アドレス、エンコーディング、長さ、SHA-256ハッシュを保持します。結果はJSONLとしてエクスポートでき、さらなる分析や他のログとの比較に利用できます。MCPTraceは取得済みのメモリイメージ上で動作し、LLMや外部AI APIを必要としません。
tools/callの名前や引数を含む、MCP関連のメソッドとレスポンス形状を識別します。現在の分析対象はWindows x64とLinux x86-64です。プラグイン名はメモリイメージのオペレーティングシステムを指し、Volatilityの実行に使用するOSとは独立しています。
MCPTraceはVolatilityのプロセス列挙とアドレス変換を使用します。Windowsではプロセスの**Virtual Address Descriptor (VAD)を、LinuxではVirtual Memory Area (VMA)**を走査します。これらのマッピングが、調査対象となるプロセスのアドレス範囲を定義します。2つのアダプターは、メッセージの切り出し、相関付け、ポリシー、エクスポートのコードを共有しています。
読み取り可能な範囲内で、スキャナーはリテラルのJSON-RPCバージョンマーカーを検索し、その周辺の候補JSONオブジェクトを特定します。ネストされたオブジェクト、エスケープ文字、文字列内の波括弧、連続する読み取りチャンクにまたがるメッセージを処理します。重複キーやサポートされていない識別子を含むJSONは、暗黙的に再解釈されることなく拒否されます。MCPとの関連性は既知のメソッド名、レスポンス形状、関連するリクエストIDから判断され、完全なMCPスキーマ検証ではありません。
欠落したメモリは欠落したまま保持されます。リーダーはギャップをゼロで埋めたり、別々のVAD/VMAにまたがってバイト列を結合したりしません。--include-partialを指定すると、解析されなかったフラグメントを個別に表示できますが、欠落したIDや引数を捏造することはありません。ページテーブル情報を用いて大きな未マップ範囲をスキップでき、読み取り不能なアドレス範囲はスキャン統計に表示されたままになります。
相関付けは意図的に保守的に行われます。1のような数値IDは文字列ID"1"とは区別され、異なるプロセス内のメッセージは自動的にリンクされません。IDに関連付けられた複数の異なる表現は曖昧としてマークされます。候補の関係は、それ自体でセッション、メッセージの方向、実行タイムラインを再構築するものではありません。
**Python 3.10+**が必要です。インストールには固定されたフレームワーク依存関係volatility3==2.28.2が含まれます。リポジトリのplugins/ディレクトリを利用可能な状態に保ってください。Pythonパッケージはpipでインストールされますが、-p pluginsでVolatilityアダプターを読み込みます。
git clone https://github.com/Kowntaewook/MCPTrace.git
cd MCPTrace
python -m venv .venv
シェル用の環境をアクティベートします:
.\.venv\Scripts\Activate.ps1source .venv/bin/activate次に MCPTrace をインストールします:
python -m pip install .
仮想環境を有効化した状態で、リポジトリのルートから以下の例を実行してください。画像パスと PID は、実際の証拠と対象プロセスに置き換えてください。MCP クライアントとサーバーは別々のプロセスで動作する場合があるため、必要に応じて両方を調査してください。
Windows
MCPTrace を実行する前に、Volatility がイメージを解釈でき、そのプロセスを列挙できることを確認してください。Windows のシンボル準備にはネットワークアクセスが必要になる場合があります。
vol -f windows.raw windows.info.Info
vol -f windows.raw windows.pslist.PsList
mkdir output-windows
vol -p plugins -f windows.raw -o output-windows windows.mcptrace.MCPTrace --pid 4242 5252 --dump
Linux
ダンプの正確なカーネルビルドに一致する ISF シンボルを symbols/linux/ に配置します。
linux.pslist.PsList がカーネルまたはレイヤーの要件を解決できない場合は、MCPTrace の出力を解釈する前にイメージ/シンボルの設定を解決してください。
vol -s symbols -f linux.lime linux.pslist.PsList
mkdir output-linux
vol -p plugins -s symbols -f linux.lime -o output-linux linux.mcptrace.MCPTrace --pid 4242 --dump
--pid を省略するか、複数の PID を渡します: --pid 4242 5252。--dump はプロセスごとの JSONL ファイルを -o で指定したディレクトリにエクスポートします。vol -p plugins windows.mcptrace.MCPTrace -h(または Linux の同等のコマンド)を使用してください。結果テーブル全体を JSON でレンダリングするには、グローバルオプション -r json をプラグイン名の前に置きます。これは --dump によって生成されるプロセスごとの JSONL エクスポートとは別のものです。
vol -p plugins -f windows.raw -r json windows.mcptrace.MCPTrace --pid 4242 > findings.json
| オプション | 目的 |
|---|---|
--pid 4242 5252 | プロセスIDを選択する。省略した場合は、アダプターが列挙したすべてのプロセスを調査する。 |
--dump | 表示されたアーティファクトとスキャンサマリーを、グローバルな -o ディレクトリを使用してJSONLとしてエクスポートする。 |
--include-partial | 欠落フィールドを再構築せずに、未解析の生フラグメントを含める。 |
--include-rpc | MCPとの関連が確認されていない汎用的なJSON-RPC候補も表示する。 |
--policy PATH | ツール引数にローカルルールを適用する。Windows および Linux の例を参照。 |
--suspicious-only | ポリシー一致とサマリーのみを表示する。空でないポリシーが必要。 |
--max-records N | フィルタリング前にプロセスごとの候補レコード数を制限する。デフォルト: 10000。 |
--max-object-bytes N | 1つの完全なJSONオブジェクトのサイズを制限する。デフォルト: 65536 バイト。 |
--max-bytes N | プロセスごとに試行するアドレス範囲のバイト数を制限する。0 は無制限を意味する。 |
ポリシー検出結果は、アナリストが提供したルールとの一致を表す。一致は 悪意のある活動を立証するものではない。別のケースに適用する前に、 例に示されたパス、ホスト、ツール名を確認すること。
mcptrace.pid-4242.jsonl のようなファイルには、メタデータレコード、アーティファクトレコード、
および最終的なスキャンサマリーが含まれる。メタデータはプロセス、対象OS、およびアドレス
空間を識別する。アーティファクトレコードは、解析済みメッセージと復元された正確なバイトの
両方を保持する。
| フィールド | 意味 |
|---|---|
pid, virtual_address, region_start | プロセスと証拠の位置。アドレスはプロセスの仮想アドレスであり、イメージファイルのオフセットではない。 |
message, method, tool, request_id | 利用可能な場合の、解析済みメッセージ内容と選択されたフィールド。 |
raw_base64, byte_length, raw_sha256 | 元のバイト、その長さ、および検証用のSHA-256。 |
state, encoding | レコードが完全かフラグメントか、およびそのバイトのエンコード方法。 |
relation, candidate_virtual_addresses | 候補となる対応位置と、関係が曖昧かどうか。 |
findings | オプションの引数ポリシーチェックの結果。 |
アーティファクトを検証するには、raw_base64 をデコードし、その長さとハッシュを確認し、
対応するプロセスメモリレイヤーを通じてその範囲を再読み取りする。message を
JSONとして再フォーマットすると空白やエスケープが変わる可能性があるため、正確な
比較には保存されたバイトを使用すること。異なるメモリコピーは別々の証拠レコードとして
残る。
アーティファクトと併せてスキャンサマリーを読むこと。スキャンサマリーは、スキャンされた 領域、読み取り可能および読み取り不能なバイト、無効な領域、スキップされたプロセス、エラー、 および制限イベントを報告する。読み取り不能なバイトには、未使用の予約アドレス空間が 含まれる場合がある。メッセージが存在しないという結果は、MCP活動が一度も発生しなかった ことを証明するものではない。
ベンチマークでは 3つの新規Windows Server 2022 VMキャプチャ を使用した。各VMは、 公式Python MCP SDKをstdio経由で使用する2つのクライアント/サーバーペアを実行した。 実際のトラフィックは、WinPmemで物理RAMを取得する前に交換された。テストメッセージは 結果のイメージに注入されていない。
各条件は、初期化、通知、およびツール検出を含む 64回のツール呼び出しと133個の論理 メッセージ を完了した。ペイロードには、ASCII、韓国語/絵文字、エスケープ文字、空白、 および2 KiBの文字列が含まれていた。条件は以下のとおり:
復元数は、各キャプチャ内のクライアントとサーバーを合算し、論理メッセージを重複排除した ものである。表は、3つのキャプチャにわたる平均と範囲を示す。
| 条件 | メッセージ / 133: 平均 (範囲) | ツールペア / 64: 平均 (範囲) |
|---|---|---|
| 保持フレームリストなし | 59.7 (55-66) | 18.3 (15-21) |
| 保持フレーム対照 | 133.0 (133-133) | 64.0 (64-64) |
保持フレームなしの実行では、66、58、55 件のメッセージと、21、19、15 組の完全なツール要求/応答ペアが回収された。キャプチャ全体でプールすると、179/399 メッセージ、55/192 ペアとなる。保持ありの対照では、各キャプチャで 133 件のメッセージと 64 組のペアが回収された。両方のエンドポイントで見つかったペアが、必ずしも 1 つのプロセス内に完全な形で存在するとは限らない。
3 回のキャプチャのうち 2 回が候補探索の上限に達し、それぞれ 4 件と 3 件のバックトラック上限イベントを報告した。これらの実行は明示的に completed_with_limits とマークされ、引き続き表に含まれている。このイベントは、欠落した一意のメッセージ数を数えたものではない。最終的な 3 回のキャプチャでは、プロセス読み取りエラー、スキップされたターゲット、レコード/バイト予算の上限は観測されなかった。
各イメージは 3 回分析され、4 つの選択されたエンドポイントプロセスの 9 回の CLI スキャンが得られた。実行時間は中央値 53.95 秒、平均 53.94 秒、範囲 53.32〜54.48 秒であった。ランナーは 4 論理 CPU と約 16 GiB の RAM を報告した。
タイミングには、CLI の起動、Volatility の automagic、プロセススキャン、JSON レンダリング、JSONL エクスポートが含まれる。取得、初期シンボル準備、および別途のバイト検証は含まれない。イメージはスキャン前にすでにハッシュ化および検査済みであるため、これらはコールドキャッシュや全プロセス/フルイメージのスループット測定ではない。
エクスポートされた 1,339 レコード / 562,402 バイトはすべて、バイト、ハッシュ、仮想アドレス、VAD 境界に関するネイティブのプロセス層チェックに合格した。繰り返しスキャンではバイト単位で同一の JSONL が生成され、イメージハッシュは変化せず、一時 RAM イメージは分析後に削除された。評価可能な 2,480 件の方向性候補リンクのうち、誤ったリンクは観測されなかった。この数にはメモリコピー間のリンクも含まれる。
意図的に送信しなかった 3 つの対照も回収された。これは重要な解釈上の限界を示している。MCP 形式のオブジェクトは、送信されていなくてもメモリ内に存在し得る。証拠を評価する際には、ログ、キャッシュされた値、およびサンプルを考慮する必要がある。
どちらの条件にもメモリを変化させるログ記録が含まれており、保持フレームは有利な対照である。これらの結果は小規模な SDK フィクスチャを記述したものであり、一般的な再現率、適合率、攻撃検出性能ではない。ワークロードは以前の 8 回呼び出しの陽性検証とは異なるため、この 2 つの結果は制御された前後比較ではない。完全な測定値、キャプチャごとの統計、および再現手順は、ベンチマークレポートと機械可読な結果にある。
ベンチマークにより、時期尚早な上限カウンタのインクリメントが明らかになった。133 件の有効な SDK メッセージを含むローカルストリームは完全に回収されたが、228 件の候補上限イベントを生成した。現在、カウンタは、古い候補が除外された後に有界バックトラックが失敗した場合にのみインクリメントされる。探索の上限自体は変更されておらず、真の上限イベントは引き続き出力に表示される。初期の失敗した試行と修正は、ベンチマークレポートに記録されている。
測定された実装は、135 件の自動テスト、Ruff チェック、および Python 3.10 と 3.12 を用いた Windows と Ubuntu 上の CI に合格した。テストは、パース、正確なバイト保持、メモリギャップ、型付き ID の相関、プラットフォームアダプタ、エクスポート、およびベンチマークレポートをカバーしている。