【PHP脆弱性php2shell】WordPressも対象、パッチは21:59に公開済み。「23:15から乗っ取り」「15分でAIが攻撃コード?」は本当か、自分のVPSのログで検証(CVE-2026-109618/109619)
PHPの重大な脆弱性で、タイムラインが大騒ぎです。
震源のひとつが、「23時にパッチが公開されたら、それをAIで解析して攻撃コードを作り、23時15分以降に乗っ取られるサイトが出てくる」という話。これを真に受けた人が「23時15分に何が起きるんだ」と身構えている。
まあ、あるある煽りです。ただ、「じゃあ大したことないのか」というと、それも違う。私も最初、「どうせファイルアップロードまわりのバグだろうから、アップロードの口を表に出しているサイトしか狙われないでしょ」と読みました。公式の発表を読んだら、その読みは外れていました。
煽りのどこがズレているのか、逆に舐めてはいけないのはどこか。順番にいきます。
【追記】10月21日23時15分ごろ:パッチが出たのはPHP 8.2以降だけ。7系・8.0・8.1はどうする?
正式な修正版が出たのは、PHP 8.2〜8.5だけです。8.5.12、8.4.27、8.3.36、8.2.35。PHPの公式勧告には、はっきりこう書いてあります。「PHP 8.1以前は、もうPHPプロジェクトから更新を受け取れない」(PHP公式の勧告)。
じゃあ7.4、8.0、8.1は見捨てられたのかというと、一応、救命ボートはあります。
- ソースの最小限のバックポート:深刻さを考えて、PHPのセキュリティチームが7.4、8.0、8.1向けに、修正部分だけのソースを出しました。ただし、自分でソースからビルドする人向けです。新しいバージョン番号のリリースではありません
- ディストリビューション、LTSベンダー:サポートが残っているOSのPHPなら、そこからバックポートの更新が降ってくる場合がある。ベンダーに確認
- Remiのリポジトリ:RHEL系でよく使われている、有志のリポジトリ。公式勧告には「今日は更新が出ない」と書かれていましたが、8系の修正版(8.2.35〜8.5.12)は22時49分ごろに配信されました。一方、7.4の最新(7.4.33-29)は10月1日付で、今回の修正は入っていません
バックポートの置き場所は、PHP本家のGitHubのブランチです(7.4用、8.0用、8.1用)。7系で用意されたのは7.4だけ。7.3以前には、公式からは何も出ていません。
結局、7系や8.1以前で動いているなら、本筋は8.2以降に上げること。ちなみに8.2も、2026年12月31日でセキュリティ修正が終わります。上げるなら8.3以降にしておかないと、2か月後にまた同じことをやる羽目になります。
7系から8系に上げて、互換性は大丈夫か。大丈夫じゃないです。ここは煽りじゃなく、本当にこける。
- 8.0で、緩かった書き方がエラーになった:今まで警告で済んでいた型の間違いが、エラーで止まるようになった。数値と文字列の比較の結果が変わった(
0 == "abc"が true から false に)。古い関数も消えている(create_function()、each()など) - 8.1〜8.4で、非推奨の警告が増える:標準関数にnullを渡す、クラスにない変数を勝手に足す、といった昔ながらの書き方に警告が出る。すぐには止まらないが、ログが警告で埋まる
- WordPressは、本体が古いと8系で動かない:本体を新しくしてから、PHPを上げる。いちばんこけるのは、古いプラグインとテーマ
やり方の定石はこう。
- 本番のコピー(ステージング)を作って、そっちで先に上げる
- PHP_CodeSnifferのPHPCompatibilityなどで、コードを機械的にチェックする
- 非推奨の警告も含めてエラーログを出して、動かしてみる
- RHEL系なら、Remiでは複数のPHPを並べて入れられる。サイトごとにPHP-FPMの向き先を切り替えれば、1サイトずつ移せる
移行が終わるまでの間は、公式の暫定策(session.upload_progress.enabled=0 など)で穴を少しでも減らす。ただし公式も言っているとおり、暫定策は「安全にはならない」。急いで上げるしかない。
PHPの脆弱性「php2shell」とは:CVE-2026-109618/109619、CVSS 9.2
まず事実だけ。
- 何が:PHP本体の脆弱性2件。CVE-2026-109618とCVE-2026-109619。深刻度はどちらもCVSS v4.0で9.2。通称「php2shell」
- 何が起きる:認証なしで、外からサーバー上のコードを実行される(リモートコード実行)
- 直ったバージョン:PHP 8.5.12、8.4.27、8.3.36、8.2.35
- 8.1以前:PHPプロジェクトからの更新はもうない。ディストリビューションやLTSベンダーのバックポートを頼るか、上げるしかない
経緯はこう。PHPのセキュリティチームが、日本時間10月21日の早朝に「21日23時(14:00 UTC)に重大な修正を出す」と予告しました。ところが、本来の公表日より前に情報が漏れた。予告には最初から「詳細が公になったり、実際の悪用が見えたりしたら前倒しする」と書いてありました(PHP公式)。
国内でも、BASE、コドモン、Cygamesのゲームなど、サービスを止める判断をした会社が相次いでいます。まとめはpiyologが詳しい。
「パッチ公開から15分で乗っ取り」は本当か?
そもそも23時に出てない
まず、前提が崩れています。パッチは23時を待たずに出ました。
php.netの公開用リポジトリに、4バージョンのリリース告知とセキュリティ勧告が載ったのが21時59分。GitHubの技術詳細(セキュリティ勧告)が出たのが22時34分。予定より約1時間の前倒しです。
「23時15分」は、来ない時刻を基準にした予言でした。はい解散。
「15分」の出どころ
この数字、たぶん元ネタはセキュリティ企業Sansecの記事です。「リリースから15分以内に大量の攻撃が始まると予想している」と書いています(Sansec)。
専門家の「それくらいの覚悟でいろ」という警告が、伝言ゲームで「23時15分に乗っ取られる」という予言に化けた。あるあるです。
ちなみに、パッチが出た21時59分の15分後、22時15分を過ぎてから攻撃が始まったという報告は、22時50分の時点で見当たりません。もっとも、攻撃の観測の報告が出てくるのは、たいてい数時間から数日後です。「報告がない」は「攻撃がない」じゃない。
公開されたパッチから攻撃コードは作れるのか?
じゃあ、「パッチをAIで解析して攻撃コードを作る」という筋書き自体はどうか。
一般論としては、作れる。というか昔からある
パッチは「ここが壊れていました」という地図です。直す前と直した後の差分を見れば、どこに穴があったかが分かる。そこから攻撃を組み立てるのは、昔からある手口です。
Windowsの月例パッチが出た翌日に攻撃が増える「Exploit Wednesday」なんて言葉があるくらい。パッチが出た瞬間に、穴の場所は世界中に公開される。だから、パッチが出たら更新を急げ、と昔から言われているわけです。
AIで差分の読み解きが速くなる、というのも、一般論としてはあり得る話です。人間が何日もかけていた作業が縮むなら、パッチ公開から攻撃までの時間も縮む。ここまでは煽りサイトの言うとおり。
ただし今回は、パッチが最初のヒントじゃない
今回に限っては、この筋書きはピントがズレています。理由は3つ。
1. パッチより先に情報が漏れていた。パッチを解析してヨーイドン、じゃない。漏れた時点で、もう走り出している人がいた。
2. 公式の勧告そのものが、かなり詳しい。PHPの勧告は、どの段階で何が起きるのか、どのPHPの動かし方で通るのかまで書いています。管理者が自分のサーバーを判断できるように書いた結果ですが、攻撃する側にとっても、差分を読むまでもなく方向が分かる。AIでパッチを解析するまでもないんです。
3. 仕組みが分かることと、どこでも通る攻撃コードになることは別。今回はメモリを壊す系の脆弱性です。公式も、攻撃が通るかどうかは「PHPのビルド、拡張機能、前段のWebサーバーの挙動、メモリの配置」に左右されると書いている。環境ごとに調整が要るタイプで、ボタン1つで世界中のPHPを一斉に乗っ取れる、という話じゃない。
なので、「パッチから攻撃コードが作られる可能性」はある。というより、それが前提です。ただ、「15分後に一斉に乗っ取られる」と時刻まで断定する根拠は、どこにもない。
そもそもAIは攻撃コードを書くのか:フロンティアモデルの安全対策
「AIで攻撃コード」と簡単に言いますが、ChatGPTやClaude、Geminiみたいな最前線のモデル(フロンティアモデル)に「この脆弱性の攻撃コードを書いて」と頼んでも、普通は断られます。
各社とも、何重にも手を打っています。
- 学習の段階:人間の評価を使った強化学習などで、攻撃コードやマルウェアの作成は断るように調整している。脆弱性の説明、防御の方法、パッチの当て方には答える。でも、そのまま使える攻撃の道具は渡さない、という線引き
- 使っている最中:入出力を別の仕組みで見張って、危ないやり取りを検知する
- 使った後:利用規約で禁止して、悪用が見つかればアカウントを止める。悪用の実例を報告書として公表している会社もある
ただし、ガードレールは完璧じゃない。いちばん生々しいのが、Anthropicが2025年11月に公表した件です。中国の国家支援とみられるグループが、Claude Codeを使って約30の組織への侵入を試み、作業の8〜9割をAIが自律的にこなしていた(Anthropicの報告書)。
手口は、正規のセキュリティ診断だと名乗って、作業を細かく刻むこと。1つ1つの指示は無害に見えるから、断られない。Anthropicは検知してアカウントを止めましたが、すり抜けられたのは事実です。
つまり、フロンティアモデルの安全対策は「絶対に書かない」じゃない。「書かせにくくして、見張って、見つけたら止める」です。運営の目が届くところで動いている限りは、ですが。
悪人は「攻撃専用LLM」を作る:オープンウェイトの悪用
じゃあ、運営の目が届かないところでは?
2023年6月、ハッカー向けのフォーラムに「WormGPT」が登場しました。中身は、誰でも手に入るオープンソースのモデル(GPT-J)。それを悪用向けに仕立てて、月60〜100ユーロで売っていた。続いて「FraudGPT」なども出回りました。2025年には、GrokやMixtralを脱獄用の指示で包んだWormGPTの新しい亜種まで報告されています(Cato Networks)。
本当に怖いのは、オープンウェイトのモデルです。モデルの重みが公開されていれば、自分のPCやサーバーで動かせる。
- 安全のための調整は、追加学習で外せてしまう
- 手元で動かすから、入出力の監視もない
- 止められるアカウントも、そもそもない
オープンウェイトのモデルは研究にも商売にも欠かせないし、私もLlamaなどを使っています。ただ、作った会社がどれだけ真面目に安全対策をしても、重みを配った時点で、手綱は手放している。悪人が自前の攻撃専用LLMを持つのは、もう普通の話です。
だから、「15分でAIが攻撃コードを作る」を怖がっても仕方ない。AIは、攻撃のハードルを下げて、速くする。それは今に始まった話じゃないし、これからも下がり続ける。守る側にできるのは、パッチを当てるまでの時間を縮めることだけです。
もう走ってる
そもそも、今回はパッチより先に情報が漏れているんです。攻撃ツールのスクリーンショットも出回っていた。Sansecによれば、日本時間21日の夕方には、CloudflareがPHPサイトへの初期の攻撃を報告しています。GMO Flatt Securityも、14時の時点で「悪用できると主張するコードが出回り始めた」と追記しています(GMO Flatt Security)。
パッチが出てから、よーいドンでAIが走り出す話じゃない。もう走ってる。一方で、IPAやオーストラリアのACSCは、21日の時点で悪用は確認していないとしていて、観測は割れています。
どっちにしても、「何時何分から危ない」と時刻を区切ることに意味はありません。危ないのは、更新していないサーバー全部。今この瞬間も。
「アップロード機能がないから対象外」はなぜ間違いか:WordPressも狙われる
で、ここからが本題。私が最初に読み違えたところです。
アップロード画面と、PHPがアップロードを処理することは別
ファイルのアップロードは、HTTPでは「multipart/form-data」という形式で送られます。今回の脆弱性は、PHPがこの形式を解析するところや、アップロードの進み具合を記録する機能(session upload progress)が絡んでいる。ここまでは読みどおりでした。
問題はその先。
- 攻撃者は、画面のフォームなんか使わない。HTTPリクエストを直接投げる
- PHPは、アプリのコードが動く前に、届いたリクエストの本文を自動で解析する
- だから、そのサイトにアップロード画面があるかどうかは、関係ない
PHPの公式勧告も、狙われるのは「Webリクエストを受けているすべてのPHP」だとして、PHP-FPM、Apacheのmod_php、php-cgi、FrankenPHP、LiteSpeedを並べています。そして、mod_phpでは「認証なしのリクエストで、アプリのコードが動く前に攻撃が成立する」ことが実証済みだと書いている。
アプリが動く前、です。WordPressのアップロード機能がログインしないと使えないとか、そういう話にすらならない。PHPのファイルにリクエストが届く時点でアウト。WordPressなんて、ログイン画面もトップページもPHPです。
「メモリリーク」でもない
もうひとつ。私は「仕掛けたファイルをアップしてメモリリークを狙う」と読んでいましたが、これも違いました。
- CVE-2026-109618:メモリが足りなくなったときに処理が途中で打ち切られ、中途半端な状態のデータを、後片付けの処理が正しいものとして扱ってしまう
- CVE-2026-109619:あるリクエストのために使っていたメモリが解放された後も、その場所を指す情報が残り、同じプロセスが次に受けたリクエストで使われてしまう
漏れるんじゃなくて、壊れたものや捨てたものを使ってしまう。だから乗っ取りまで行く。
本当の分かれ目は「mod_phpか、PHP-FPMか」
じゃあ全部のPHPサイトが同じだけ危ないのかというと、そこは差があります。分かれ目は、アップロードの口の有無じゃない。PHPの動かし方です。
- Apacheのmod_php:公式が「リスクが最も高い」と名指し。実際に遠隔からコードを実行できることが確認されている
- PHP-FPM(nginxなど):リクエストの開始でこけると、その子プロセスごと捨てる作り。そのため、mod_phpと同じ攻撃がそのまま通るわけではない。1件目については、FPMでの完全な攻撃はまだ実証されていない。ただし2件目は、アプリ側の処理の条件がそろえば、FPMでも通る経路が確認されている
つまり、「FPMだから安全」も言えない。危なさの順番が違うだけで、更新しなくていい理由にはなりません。
公式は、更新できないときの暫定策(設定の変更など)も並べていますが、どれも「特定の経路を減らすだけで、安全にはならない」と書いています。PHPのリリースノートの言い方を借りると、「完全な緩和策はない。更新が唯一の安全な選択」。
じゃあ、何をすればいいのか
- 自分のサーバーのPHPのバージョンを見る。8.5.12、8.4.27、8.3.36、8.2.35未満なら、更新する
- PHPの動かし方を見る。phpinfo()の「Server API」が「Apache 2.0 Handler」ならmod_phpで、いちばん急ぐ組。「FPM/FastCGI」でも、更新はする
- レンタルサーバーなら、事業者の告知を見る。自分ではPHP本体を入れ替えられないことが多い。止める、待つ、の判断も事業者がしている
- 8.1以前で動いているなら、この機会に上げる。もう本家からは直してもらえません
WordPressサイトはどうする?
WordPressのサイトを持っている人が勘違いしやすいのが、ここ。
- WordPressの更新では直らない。今回の穴は、WordPressでもプラグインでもなく、その下で動いているPHP本体にある。管理画面で「最新です」と出ていても関係ない
- 直すのはPHPのほう。自分のサーバーならPHPを修正版に上げる。レンタルサーバーなら、事業者がPHPを入れ替えたかを告知で確認する。管理画面でPHPのバージョンを選べるサービスなら、修正版を選ぶ
- PHPを大きく上げるなら、WordPressが先。古いWordPressや古いプラグインは、新しいPHPでこける。本体、プラグイン、テーマを最新にしてからPHPを上げる
私も、自分のVPSを更新します。
自分のVPSのログを見てみた:21時59分〜22時55分に何か変わったか
せっかくなので、自分のVPS(Apache+PHP-FPM)の今日のアクセスログを集計してみました。見たかったのは、パッチが出た21時59分から22時55分までに、何か変化があったかどうか。
まず、時計が15分ずれていた
ログを開いたら、いきなりつまずきました。VPSの時計が、実際より約14分40秒遅れていた。NTPのサービスは動いていて、さくらのNTPサーバーとも通信できているのに、ずれたまま。NTP同期なしかーい。
笑い話ですが、これ、ログを読む側からすると致命的です。時計がずれていると、「パッチ公開の何分後に何が来たか」が読めない。なので、ずれを足して実時刻に直してから集計しました。インシデントのときに時系列が読めないサーバーは、それだけで調査が詰みます。皆さんも、ついでに時計を見てください。
21時59分〜22時55分:変化なし
実時刻の21時59分〜22時55分を、前の3日間の同じ時間帯と比べました。
- PHPっぽいURL(.php、wp-、xmlrpcなど)を狙う探り:今日は13件。前3日の同じ時間帯は93件、22件、303件。むしろ少ない
- PHPのファイルへのPOST:41件。うち13件は自分のWordPressの定期処理(wp-cron)、28件は昔からある別のWebツールの穴を探すスキャナで、全部404。どちらも、この時間帯の前から来ているやつです
- PHP-FPMの異常終了、メモリ不足のエラー:ゼロ。前の日もゼロ
パッチ公開の前後で、目に見える変化はありませんでした。23時15分の祭りどころか、22時15分の祭りもなし。
1か月分を日別に並べても、今日は普通の日
念のため、アクセスログ、エラーログ、SSHのログを、9月20日から日別・時間別に並べてみました。
- PHPっぽいURLへの探り:毎日3,000〜17,000件来ている。今日は約5,900件。いちばん多かったのは10月19日の深夜0時台で、1時間に1万3,000件。情報が漏れる前の、ただの総なめスキャンです
- サーバーエラー(500番台):今日は6件。この1か月は0〜73件の間
- PHP-FPMの異常終了:1か月ずっとゼロ
- SSHのパスワード総当たり:毎日6,000〜35,000回。今日は約1万6,000回。いつもどおりうるさい
インターネットに出しているサーバーには、毎日このくらいのゴミが飛んでくる。今日だけ特別、という数字はどこにもありませんでした。
それより前に来ていたのは、いつものやつ
今日いちばん目立ったのは、パッチ公開の前、20時20分ごろからの山です。1つのIPアドレスから、WordPressのログイン画面(wp-login.php)に117回のPOST。パスワード総当たりですね。
うちのWordPressは別の場所に置いてあるので、そのURLは本物のログイン画面へのリダイレクトを返すだけ。ボットはリダイレクトを追わず、同じURLを叩き続けて帰っていきました。PHPの脆弱性とは関係ない、毎日来ている、ただの総当たりです。
ただし、これでうちが安全だという話じゃありません。Apacheの標準のログには、リクエストの本文も、multipartかどうかも残らない。見えているのは、URLと件数と、エラーが出たかどうかだけです。そもそも今回いちばん危ないのはmod_phpで、うちはFPM。1台のVPSのログで、世の中の攻撃の有無は語れません。
言えるのは、うちのVPSには、21時59分を境に何かが押し寄せてきた形跡はない、ということだけ。だから慌てない。でも更新はする。
サービスを止めた会社が「大げさ」と言われていますが、止めた判断は全然大げさじゃないと思います。情報が漏れて、パッチより先に攻撃の話が出回っていた。直るまで止める、は普通の判断です。
まとめ:時刻の予言に踊らず、黙って更新しろ
- 「23時15分から乗っ取り」は煽り。パッチは21時59分に出ていたし、攻撃の話はパッチより先に出回っていた。時刻で区切る意味がない
- 「アップロード機能を公開していないから関係ない」は間違い。PHPはアプリが動く前にリクエストを解析する
- 危なさの差は、PHPの動かし方(mod_phpか、FPMか)で出る。でも、どっちでも更新する
- 私のVPSのログでは、21時59分〜22時55分に目立った変化はなかった。来ていたのは、いつものパスワード総当たりと古いスキャナだけ
煽りに乗って騒ぐのも、「うちは関係ない」と高をくくるのも、どっちもクリティカルシンキングが足りない。一次情報(今回ならphp.netの勧告)を読んで、自分のサーバーに当てはめる。それだけの話です。
システムは壊れる前提で作る、というのは、個人情報漏えいの記事でも書いた話。脆弱性が出るのは避けられない。出たときに、どれだけ早く、正しく直せるかです。
せっかくなので、これから日々の攻撃の変化を追ってみようかと思っています。ハニーポットを立てて誘い込んでみたり、家のネットワークも、ミラーリングポートのあるスイッチで出入りのパケットを眺めてみたり。
ただ、たぶん大したものは釣れない。まともな攻撃者は、踏み台探しのついでには寄ってくるけど、お宝がどこにあるかはちゃんと知っている。弱小なうちのVPSや家庭内ネットワークには、わざわざお邪魔してくれないみたいです。ありがたいような、寂しいようなw
というわけで、ハニーポットで何が釣れるか、家のIoT機器が外に何を送っているかは、やってみてから別の記事で書きます。暗号化の時代でも、誰がどこと話しているかは丸見え、という話になるはず。乞うご期待。
※参照:PHP公式(Security advisory、各バージョンのリリース告知)/GitHub Security Advisory(CVE-2026-109618)/GitHub Security Advisory(CVE-2026-109619)/Sansec/GMO Flatt Security/piyolog