2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHP2Shell:更新したつもりを防ぐPHPの確認・更新・再起動手順

2
Posted at

PHP2Shell:更新したつもりを防ぐPHPの確認・更新・再起動手順

PHPの重大な脆弱性「PHP2Shell」が公表されました。認証なしでサーバー上のコードを実行される可能性があり、悪用も確認されています。

PHPで動く業務システムやWordPressを管理しているなら、まず調べたいのはWebリクエストを処理しているPHPが修正済みかです。

ここで厄介なのは、PHPの更新コマンドが成功しても、古いワーカーが動き続ける場合があることです。

パッケージを更新しただけで安心せず、Web側でどのPHPが動いているか、古いワーカーが残っていないかまで確かめたいところです。 その確認を軸に、更新、再起動、侵害の初動調査まで順番に整理します。

まず30秒で対象を判断する

最初に確認するのは3点です。

  1. Web側で動いているPHPの系列とバージョン
  2. パッケージ提供元によるCVEの修正状況
  3. 更新後に古いPHPワーカーが残っていないか

2026年10月21日に公表された修正版は次のとおりです。

PHP系列 修正版 確認すること・次の対応
8.5 8.5.12 未修正なら更新・再起動
8.4 8.4.27 未修正なら更新・再起動
8.3 8.3.36 未修正なら更新・再起動
8.2 8.2.35 更新後、サポート終了にも備える
8.1以前 通常の修正版なし 提供元の対応確認と移行計画

OSの提供元が修正をバックポートしている場合は、バージョン番号だけで判断できません。

Web側のPHPが不明なら次の節へ。未修正なら更新の節へ。更新できない場合は暫定策の節へ進んでください。

PHP2Shellとは

2026年10月21日、The PHP Groupは次の2件を公表しました。

CVE 問題
CVE-2026-109618 OOM時のリクエストデータ処理
CVE-2026-109619 解放済みメモリに関係する状態の残存

いずれも認証なしのリモートコード実行につながる可能性があり、CVSS v4.0の深刻度は9.2です。

CVE-2026-109618は、特にApacheのmod_php構成で危険度が高くなります。

公式の詳細は、それぞれCVE-2026-109618のアドバイザリとCVE-2026-109619のアドバイザリで確認できます。

JPCERT/CCの注意喚起では、悪用を試みる通信の観測報告が相次いでいると説明されています。

米CISAも10月26日、2件を悪用が確認された脆弱性のカタログに追加しました。最新の登録状況はCISAのKEVカタログで確認してください。

Web側で動くPHPを特定する

php -vだけで判断するのは危険です。

例えば、CLIがPHP 8.4でも、Web側のPHP-FPMは8.2という構成が考えられます。

確認の順番は、Webサーバーの接続先 → 稼働プロセス → パッケージの修正状況です。

1. 実行方式を確認する

実行方式 調べる対象
PHP-FPM Webサーバーの接続先とFPMマスター
mod_php ApacheのPHPモジュールと子プロセス
コンテナ 稼働コンテナ内のPHP

Debian系のApacheなら、読み込まれているモジュールを確認できます。

apache2ctl -M | grep -E 'php|proxy_fcgi'

ただし、モジュールの存在だけでは対象サイトの実行方式は確定しません。

ApacheのVirtualHost設定やNginxのfastcgi_passを確認し、リクエストがどこへ渡されるかを調べます。

2. FPMマスターを確認する

PHP-FPMの場合、まずプロセスを確認します。

ps -eo pid,ppid,args | grep '[p]hp-fpm'

systemd環境ではサービスも調べます。

systemctl list-units --type=service --state=running | grep -E 'php.*fpm'

サービス名がphp8.2-fpmなら、起動設定を確認します。

systemctl show php8.2-fpm -p MainPID -p ExecStart

FPMマスターのPIDが分かったら、実行ファイルを確認します。

sudo readlink /proc/1234/exe

1234は実際のPIDに置き換えてください。

readlinkは実行ファイルへのリンク先を表示します。更新前の実行ファイルが削除されている場合、末尾に(deleted)が付くことがあります。

ただし、同じパスでバイナリが置き換わった場合もあるため、パスだけでは修正済みか断定できません。

この段階で分かるのは、どのプロセスがどの実行ファイルを使用しているかです。脆弱性が解消された証明ではありません。

3. 提供元の修正状況を照合する

Debian系では次のコマンドを使います。

dpkg-query -W 'php*'

RPM系なら次の方法があります。

rpm -qa | grep -E '^php'

インストール済みパッケージを確認したら、OSやPHP提供元のセキュリティ情報で対象CVEへの対応状況を照合します。

ここまでで、Web側のPHPと修正すべきパッケージを特定できます。

更新しただけでは終わらない。PHPワーカーを入れ替える

PHP2Shell:更新したつもりを防ぐPHPの確認・更新・再起動手順

新しいPHPをインストールしても、古いワーカーが残る可能性があります。

そのため、更新後はパッケージ、プロセス、Web側の実効バージョンを別々に確認します。

1. 関連パッケージを更新する

Debian系なら、まずインストール済みPHPパッケージを確認します。

dpkg-query -W 'php*'

PHP-FPMやCLIだけでなく、php8.2-common、拡張モジュール、Apache用モジュールなども確認対象です。

更新前には変更対象と依存関係を確認し、必要なバックアップを取得します。

Debian系の更新例です。

sudo apt update
sudo apt upgrade

apt upgradeはPHP以外の更新も対象にするため、提示される変更内容を確認してください。

リポジトリに修正版がなければ、コマンドが成功しても問題は解消しません。

2. PHPワーカーを再起動する

サービス名がphp8.2-fpmの場合です。

sudo systemctl restart php8.2-fpm
sudo systemctl status php8.2-fpm

プロセスの起動時刻を確認します。

ps -eo pid,lstart,args | grep '[p]hp-fpm'

さらに、更新後のFPMマスターについて/proc/<PID>/exeを再確認します。

ここで見るのは、古いプロセスが終了したか、修正済みパッケージの実行ファイルで起動し直されたかです。

実行方式によって確認対象は異なります。

実行方式 更新後の確認
PHP-FPM マスターとワーカーの入れ替え
mod_php Apache再起動と古い子プロセスの終了
コンテナ 修正版イメージへの置き換え
複数サーバー 全インスタンスへの反映

Debian系でApacheを再起動する例です。

sudo systemctl restart apache2

サービス名は環境によって異なります。

コンテナではホスト側のPHPを更新しても意味がありません。修正版イメージを作成し、旧イメージ由来のコンテナが残っていないことを確認します。

3. Webリクエストで確認する

最後に、実際のWebリクエストを処理するPHPのバージョンと主要な業務機能を確認します。

診断用の情報をWeb経由で表示する場合は、アクセスを制限し、確認後に削除してください。

更新前後の確認をまとめると、次のようになります。

更新前 更新後
Webサーバーの接続先 接続先が想定どおりか
FPMマスターのPID 新しいプロセスに入れ替わったか
PHPパッケージ 対象CVEの修正が適用されたか
Web側のPHP 修正済みPHPが応答しているか
主要な業務機能 更新後も正常に動くか

更新コマンドの成功は、更新作業の一部にすぎません。

更新できない場合は、暫定策の適用可否を判断する

古い業務システムでは、フレームワークや拡張機能の互換性によって、すぐにPHPを更新できない場合があります。

ただし、公式アドバイザリは完全な対策はPHPのアップデートだけとしています。

暫定策を検討する順番は次のとおりです。

  1. 正式更新が可能か確認する
  2. 外部メモリ制限とアップロード機能への影響を確認する
  3. 負荷試験、監視、切り戻し手順を用意する
  4. 暫定策を適用して全ワーカーを再起動する
  5. 正式更新の期限を決める

CVE-2026-109618

CVE-2026-109618の公式アドバイザリでは、OOM処理に関する部分的な緩和策が示されています。

項目 暫定対応
memory_limit -1
post_max_size アップロード不要なら8M、必要なら32M
upload_max_filesize post_max_sizeより小さくする
メモリ制御 コンテナやcgroupで制限

memory_limit=-1はPHP自身のメモリ上限を解除します。

外部メモリ制限が適切でも、OOM Killerによるプロセス終了やサービス停止の可能性は残ります。

外部制限、負荷試験、監視、切り戻し手順、正式更新期限を確認できない場合は、安易に適用しないでください。

以下は設定項目を示す例であり、そのまま本番投入するためのものではありません。

memory_limit = -1
post_max_size = 32M
upload_max_filesize = 16M

公式アドバイザリでは、RLIMIT_ASとRLIMIT_DATAを使用しないよう指定されています。

この緩和策はCVE-2026-109619を解消しません。

CVE-2026-109619

CVE-2026-109619の公式アドバイザリでは、セッションのアップロード進捗機能を無効にする暫定策が示されています。

session.upload_progress.enabled = 0

php.iniやFPMプールなど、サーバー管理者が制御する設定で適用します。

ini_set()や.user.iniでは不十分です。リクエスト処理中に設定を変更しても、アップロード処理がすでに進んでいる場合があるためです。

設定後は全ワーカーを再起動し、実効値とアップロード機能への影響を確認します。

PHP 8.5では、追加の暫定策として次の設定も示されています。

fatal_error_backtraces = 0

暫定策を適用したら、メモリ使用量、エラー、ワーカーの状態を監視し、正式更新までの期限を記録します。

侵害調査は、リクエストとワーカーの時系列を突き合わせる

PHPを更新しても、過去の侵害がなかったことにはなりません。

JPCERT/CCの注意喚起では、調査の手掛かりとして次の点が示されています。

  • 不自然に長い、または異常な形式のPHPSESSID Cookie
  • 不審なmultipart/form-dataリクエスト前後のメモリエラーやHTTP 500
  • PHPワーカーの異常終了や頻繁な再起動

ただし、レスポンスのSet-Cookieヘッダーは、通常のアクセスログには保存されていない場合があります。

まずログの保存先、ローテーション、保持期間を確認し、調査可能な期間を決めます。

そのうえで「いつ、どのリクエストで、どのワーカーに異常が起きたか」を時系列で突き合わせます。

以下は一般的なApacheアクセスログでHTTP 500を探す参考例です。

sudo grep ' 500 ' /var/log/apache2/access.log

ログ形式によってステータスコードの位置が異なるため、抽出結果の確認が必要です。

PHPのメモリエラーを探す参考例です。

sudo grep -Ei 'Allowed memory size|Out of memory' /var/log/php*-fpm.log

ログがファイルではなく、systemdのジャーナルやコンテナログに記録される場合もあります。

systemd環境なら、対象期間を指定して確認できます。

sudo journalctl -u php8.2-fpm --since "2026-10-21"

日付は例です。実際にはログの保持状況と調査方針に合わせて設定してください。

HTTP 500やメモリエラーは通常の障害でも発生します。単独では侵害の証拠になりません。

これらは初動調査です。侵害の疑いが強い場合は証拠を保全し、影響範囲の確認と適切なインシデント対応につなげます。

古いPHPは、今夜の封じ込めと移行を分ける

PHP 8.1以前には、今回の通常の修正版が提供されません。

公式アドバイザリにはPHP 7.4、8.0、8.1向けの限定的なバックポートがありますが、継続的な保守が保証されるわけではありません。

PHP 8.2も2026年12月31日にサポートが終了します。

PHPのサポート対象バージョンを確認し、必要な保守期間を確保できる系列を移行先に選びます。

古い業務システムでは、対応を3段階に分けるのが現実的です。

時期 対応
今夜 影響確認と可能な封じ込め
短期 修正版の適用と動作検証
中期 サポート対象PHPへの移行

古いコードの作り直しに関わってきた経験から、移行では最初に依存関係を整理することが重要だと考えています。

確認する順番は、PHP本体、フレームワーク、拡張モジュール、業務上停止できない機能です。

それぞれについて、更新先への対応状況と、更新を妨げている箇所を整理します。

全面的な書き直しを前提にせず、必要な改修を切り分けます。

補足:10月23日に公表された別のCVE

2026年10月23日には、CVE-2026-115560も公表されました。

これは、session.serialize_handlerがphp_binaryまたはphp_serializeで、session_start()前にini_set()でphpへ変更し、アップロード進捗機能が有効な場合に関係する問題です。

最初の2件とは影響条件が異なります。詳細はPHP公式の10月23日の発表を確認してください。

最後に残すのは、作業履歴ではなく確認結果

脆弱性対応では、何を実行したかだけでなく、どの状態を確認できたかを残します。

例えば、次の記録様式です。

記録項目 残す内容
対象サーバー ホスト、コンテナ、対象アプリケーション
CVEへの修正状況 PHP系列、パッケージ提供元、修正確認結果
稼働プロセス PID、実行ファイル、再起動確認結果
Web側の確認 実効バージョンと主要機能の動作結果
侵害の初動調査 対象期間、確認したログ、調査結果
未対応リスク 暫定策、制約、残るリスク
次回確認日 正式更新・移行・再調査の予定

この記録があれば、更新作業を引き継ぐ人も、何が確認済みで何が残っているかを判断できます。

更新コマンドが成功したことではなく、修正済みコードが実際に稼働していることを確認し、その証拠を残す。

そこまでを今回の対応の完了条件にします。

参考

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?