HN 日本語サマリー

← 一覧へ戻る
セキュリティ

PHP2Shell: 悪用試行と緩和策の動向

PHP2Shell: Exploitation Attempts and Remediation Trends (wiz.io)

116 pointsby acossta41 コメント

要約

Wiz Researchは、PHP2Shellの脆弱性(CVE-2026-109618、CVE-2026-109619)に関する悪用試行と緩和策の動向を報告しています。観測されたエクスプロイト試行は限定的で、完全なエンドツーエンドの悪用を示す一般公開されたPoCは確認されていません。一方で、脆弱なインターネット公開マシンは減少し、組織の緩和策が進んでいる兆候が見られます。

全文翻訳

PHP2Shell: 悪用試行と緩和策の動向

先週、PHPにおける2つの主要な脆弱性(CVE-2026-109618、CVE-2026-109619)について報告しました。それ以来、セキュリティ業界の多くの関係者と共に、Wiz Researchチームは実際の環境での関連活動を監視し、公開されているエクスプロイトコードをレビューしてきました。これまでのところ、テレメトリでは限定的な数の悪用試行が観測されており、任意のターゲットに対する完全なエンドツーエンドの悪用を示す公開PoCは特定されていません。しかし、一部のパートナーからは、様々なターゲットに対して機能するエクスプロイトが非公開で開示されており、我々も内部で実験を続けています。成功した悪用のデモンストレーションビデオはphp2shell.comで公開されています。

この記事では、実際の環境やハニーポットデータで観測された緩和策の取り組みと悪用試行の現状をまとめ、これらの活動に関する継続的な調査結果を共有します。

新たな証拠が現れ次第、この投稿を更新していきます。

観測された露出傾向

PHP2Shellの公開(2026年10月21日)以降、Wizのテレメトリでは、過去数日間でPHP2Shellに脆弱なインターネット公開マシンの日ごとの台数が約67%減少しました。また、脆弱なインターネット公開マシンのうち、PHPバージョン7.3以前を実行している割合は、5日間で8.3%から5.7%に低下しました。これは、公式のバックポートを受け取らなかった古いバージョンを実行している観測対象のシェアを測定したものです。

この期間中、深刻な影響を受けた組織(少なくとも1つの公開された脆弱なインスタンスを持つ組織と定義)の数は約47.9%減少しました(下のグラフを参照)。参考までに、我々のデータによると、PHP自体はデータセット内の65%の組織で使用されています。

これらの観測結果を合わせると、組織がパッチ適用、アップグレード、影響を受けるマシンの廃止、インターネットアクセスの制限などを組み合わせて、その露出を削減していることが示唆されます(このデータは全体的な傾向を示すものであり、各緩和策の相対的な貢献度を確立するものではありません。スキャンカバレッジや観測対象の母集団のサイズも、時間の経過とともに報告される全体的な数値に影響を与える可能性があります)。

公開から1週間後、当初影響を受けていた組織の53%未満がPHP2Shellに対して脆弱なままです。

Wiz Researchが観測した悪用試行

これまでに、この文脈で以下の種類の活動を観測しました。

  1. PHP2Shellのエクスプロイトメカニズムを使用した試行で、公開PoCの技術と一致するもの。

  2. 脆弱性とは無関係のPHP2Shellブランドのツールで、セッションポイズニングとアプリケーション内の別のローカルファイルインクルージョン(LFI)脆弱性に依存するもの。

PHP2Shellのエクスプロイトメカニズムを使用した試行

PHPベースのソフトウェアを標的とするオープンソースのエクスプロイトキットの2つのバリアントを観測しました。キャプチャした試行では、どちらもエクスプロイトチェーンを完了しませんでした。古いバリアントはリクエストサイズの制限に遭遇するか、期待されるメモリ枯渇状態を生成できませんでした。新しいバリアントはPHPのメモリを一貫して枯渇させましたが、続行に必要なメモリアドレスを取得できませんでした。

バリアント1:レガシーチェーン

PHP-CGIハニーポットへの最初のリクエストは3.37.227[.]134から来ました。これはキットの古いチェーン(archive/legacy-8m/exploit.pyの下にある)とその付属ステージスクリプトに一致していました。最初のエクスプロイトステージは、約12MBのパディングで満たされたbigという名前のフィールドを含む、1,005個のパートからなるマルチパートボディを使用しました。

キットの注釈によると、このステージはセッションリセット中にメモリを枯渇させ、後続のリクエストでセッション状態を利用可能にしようとします。

我々のハニーポットでは、そのコードに到達する前に失敗しました。宣言されたリクエストサイズが設定された8MBのpost_max_size制限を超えていたため、PHPはマルチパートボディの処理をスキップし、以下のようにログに記録しました。

PHP Warning: PHP Startup: Unable to load dynamic library 'zip' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20230831/zip (/usr/local/lib/php/extensions/no-debug-non-zts-20230831/zip/zip.so), /usr/local/lib/php/extensions/no-debug-non-zts-20230831/zip.so) in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library 'gd' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20230831/gd (/usr/local/lib/php/extensions/no-debug-non-zts-20230831/gd/gd.so), /usr/local/lib/php/extensions/no-debug-non-zts-20230831/gd.so) in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library 'mysqli' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20230831/mysqli (/usr/local/lib/php/extensions/no-debug-non-zts-20230831/mysqli/mysqli.so), /usr/local/lib/php/extensions/no-debug-non-zts-20230831/mysqli.so) in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_mysql' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_mysql (/usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_mysql/pdo_mysql.so), /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_mysql.so) in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_sqlite' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_sqlite (/usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_sqlite/pdo_sqlite.so), /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pdo_sqlite.so) in Unknown on line 0

作成者はその後、このチェーンをキットのアーカイブディレクトリに移動しました。

Roundcubeに対する後続の試行

後続の試行で、103.151.172[.]95がレガシーチェーンから長いシーケンスを送信しました。これには、他のApacheワーカーを占有することを意図した遅延接続が含まれていました。

ワーカーが1つだけ利用可能になったとき、エクスプロイトはそれぞれ3,000バイトのフィールドを1,001個含むリクエストを送信することでヒープシェーピングを試みました。これらのリクエストは、必要なメモリ枯渇フローをトリガーしませんでした。したがって、この試行が意図したメモリ枯渇状態に達したという証拠はありません。

バリアント2:現在のチェーン

キャプチャしたIPアドレスのほとんどは、pure/mk_a1.pyとpure/mk_leak_b.pyから構築された新しいチェーンを使用しました。このバリアントは複数の試行で観測されました。

このバリアントはさらに進みました。その最初のエラーは一貫してPHPのメモリ枯渇を引き起こしました。後続のエラーで、プロセスメモリのリークを試みるものは、キャプチャしたすべての実行で失敗しました。

サーバーは、PHPが制限に達したことを示す致命的なエラーをログに記録しました。例:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 131072 bytes) in /var/www/html/php2shell/pure/mk_a1.py on line 1

これは、A1がハニーポットで意図したメモリ枯渇状態に達したことを確認します。これだけでは、次のステージに必要な古いセッション状態が保持されたことを確認するものではありません。

リクエストを同じワーカーに維持する

チェーンは、連続するエクスプロイトリクエストが同じApache子プロセスに到達することに依存します。その可能性を高めるために、キットは他のワーカーを不完全なリクエストで占有しようとします。各接続は大きなボディを宣言し、1バイトを送信して停止します。

アドレス178.249.214[.]6は、エクスプロイトステージを送信する前に、これらの接続を399個、GETリクエストを400個開きました。このアドレスはVPN出口ノードであり、ソースから推測できることは限られています。

ステージA1:メモリ枯渇のトリガー

A1は、ヌルバイトセッションID、長く深くネストされた配列名を持つ860個の空のファイルパート、およびいくつかのパディングフィールドグループを含むチャンク化されたマルチパートリクエストです。

このリクエストは、セッションIDが解放されたメモリを指す可能性のある時点で、セッション処理中にメモリを枯渇させるように設計されています。

キャプチャしたすべてのA1リクエストはHTTP 500を返し、PHPエラーは以下と一致しました。

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 131072 bytes) in /var/www/html/php2shell/pure/mk_a1.py on line 1

これは、A1がハニーポットで意図したメモリ枯渇状態に達したことを確認します。これだけでは、次のステージに必要な古いセッション状態が保持されたことを確認するものではありません。

ステージB1:メモリリークの試行

B1は、約1秒後に続きました。これは、PHPSESSID=a、PHP_SESSION_UPLOAD_PROGRESS=k0、および2つの大きなパディングフィールドを含む別のチャンク化されたマルチパートリクエストを送信しました。

このリクエストがPHPが古いセッション状態をリセットする前に同じワーカーに到達した場合、PHPは解放されたヒープの内容をPHPSESSIDレスポンスCookieに書き込むことができます。キットはその後、そのCookieからヒープとlibphpのアドレスを抽出し、最終的なエクスプロイトステージを準備します。

そのようなリークは観測されませんでした。1回の実行を除き、接続は応答なしで閉じました。残りの実行は通常の32文字のセッションCookieを返しました。ソースのいずれも最終的なエクスプロイトステージを送信しませんでした。

リークが失敗した理由

リークの失敗は、より広範な課題を浮き彫りにしています。つまり、PHPのバージョンやデプロイメント構成全体で確実に機能する汎用エクスプロイトを構築することは困難です。キットのB1レイアウトは、公式のphp:8.4.26-apacheイメージと128MBのメモリ制限に合わせて計算されました。ハニーポットのような他のインスタンスでは、異なるビルドから同じPHPバージョンを実行し、追加の拡張機能と64MBのメモリ制限を使用していました。これらの違いは、ヒープレイアウトとメモリ再利用に影響を与え、リークが期待どおりに機能しない可能性があります。

信頼性の高いワーカーピンニングは、さらなる課題です。連続するエクスプロイトリクエストは、必要なセッション状態が持続する間に同じApache子プロセスに到達する必要があります。リクエストタイムアウト、ネットワーク遅延、ワーカーの可用性がこのシーケンスを妨げる可能性があります。我々のテストでは、リクエストタイムアウトとネットワーク遅延の組み合わせが、インターネット接続を介してチェーンを完了させるのを妨げるのに十分でした。

これまでのところ、異なるデプロイメント間でのワーカーピンニングまたは情報リークのいずれかに対する公開されている汎用ソリューションを特定できていません。単に公開PoCをコピーして大規模に実行しても、構成固有のエクスプロイトを信頼性の高い運用キットに変えるために必要な作業には対処できません。これらの障壁は時間の経過とともに低下すると予想されます。一部の攻撃者は、チェーンを適応させ、より堅牢なツールを構築するための専門知識を持っています。

その他の試行

15.204.59[.]70および162.35.99[.]94からのエクスプロイト試行の失敗も確認しましたが、これらのスキャナーはAdel Karimiのハニーポットを正常に悪用しました。これは、CISAがPHP2ShellをKEVリストに含める決定に寄与した可能性が高いです(https://www.cisa.gov/news-events/alerts/2026/10/26/cisa-adds-two-known-exploited-vulnerabilities-catalog)。

脆弱性とは無関係のPHP2Shellブランドのツール

PHP2Shellエクスプロイトとラベル付けされたツールも観測しましたが、実際にはどちらの脆弱性も悪用しようとはしていませんでした。このようなトラフィックの最も早いものは、85.11.187[.]35から発信され、WoYinDao/CVE-2026-109618-CVSS-9.2-Criticalの「Chain A」のGoポートに一致していました。

このツールは、長年存在するセッションポイズニング技術を使用し、アップロード進捗機能を通じてセッションファイルにPHPコードを書き込もうとしました。以下のリクエストは省略されています。

POST /index.php HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 1000
Content-Type: multipart/form-data; boundary=--------------------------972119170270911706174217

----------------------------972119170270911706174217
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain

<?php phpinfo(); ?>
----------------------------972119170270911706174217--

その後、セッションファイルをインクルードすることでコードを実行しようとしました。

GET /lfi_sink.php?file=../../../../tmp/sess_test HTTP/1.1
Host: 127.0.0.1:8080

決定的なのは、lfi_sink.phpはPoCのラボ環境によって提供される脆弱なエンドポイントであることです。このツールは、そのエンドポイントがターゲットに存在することを前提としています。これがない場合、または同等のローカルファイルインクルージョン(LFI)脆弱性がない場合、チェーンはコードを実行できません。

パディングされたバリアントはメモリ枯渇検出をトリガーしましたが、コード実行の成功は観測されませんでした。PHP2Shellのブランドにもかかわらず、この活動は無関係な技術と脆弱なアプリケーションエンドポイントに依存していました。

結論

我々のテレメトリでは、まだPHP2Shellのエンドツーエンドの悪用が成功した例は観測されていません。しかし、Adel Karimiの公開レポートとサポートデータは、エクスプロイトトラフィック、メモリ開示、およびその後のハニーポットでのコード実行を相関させる、これまでに見た中で最も堅牢な公開証拠を提供しています。特に、それらのターゲットは有利なシングルワーカーApache mod_php構成を使用していたため、その結果は他のデプロイメント全体での信頼性を確立するものではありません。

我々の観測によると、メモリ枯渇をトリガーするだけではエクスプロイトチェーンを完了するには不十分です。PHPビルド、メモリ制限、ワーカーの動作の違いは、後続のステージが機能しない原因となる可能性があります。機会主義的な攻撃者にとっての課題は、現在利用可能な公開PoCを同様に信頼性の高い運用ツールに変えるか、または独自に開発することです。PHP2Shellは短期的および長期的なリスクであり続けると我々は考えており、PHPセキュリティアップデートの適用または他の手段による緩和策の実施は、引き続き不可欠です。

IOCs

| Type | Indicator | First Seen | Last Seen | Description |
| --- |
| IPv4 | 85.11.187[.]35 | 2026-10-21 | 2026-10-21 | Exploitation attempt |
| IPv4 | 172.206.2[.]199 | 2026-10-25 | 2026-10-25 | Scanner + exploitation attempt |
| IPv4 | 3.37.227[.]134 | 2026-10-21 | 2026-10-21 | Exploitation attempt |
| IPv4 | 103.151.172[.]95 | 2026-10-25 | 2026-10-25 | Exploitation attempt |
| IPv4 | 178.249.214[.]6 | 2026-10-24 | 2026-10-24 | Exploitation attempt (VPN) |
| IPv4 | 31.56.197[.]72 | 2026-10-21 | 2026-10-21 | C2 (payload server) |
| IPv4 | 135.136.19[.]197 | 2026-10-26 | 2026-10-26 | Scanner + exploitation attempt (VPN) |
| IPv4 | 15.204.59[.]70 | 2026-10-24 | 2026-10-24 | Exploitation attempt |
| IPv4 | 162.35.99[.]94 | 2024-10-24 | 2024-10-24 | Exploitation attempt |