PHP2Shellの悪用をSplunkで見つける
Security 小川 泰明はじめに
2026年10月21日、PHP FoundationはPHPコアの脆弱性2件を修正するセキュリティリリースを公開しました。
対象はCVE-2026-109618とCVE-2026-109619で通称「PHP2Shell」、CVSS v4.0のスコアはどちらも9.2です。認証不要のリモートコード実行(RCE)の脆弱性であり、攻撃は細工されたHTTPリクエストで成立、攻撃が成立した場合、OOM(CVE-2026-109618)及びuse-after-free(CVE-2026-109619)となり、最終的にはRCEが成立することが報告されています。
影響は公式発表の PHP 8.2.35 /8.3.36 /8.4.27/8.5.12以前のバージョンの他、PHP 5.4以降のすべてのビルドに及ぶことが指摘されています。
Cisco Talosは10月21日に報告を公開しています。日本語訳も公開していますので、あわせてご参照ください。
Talosは影響範囲を次のように評価しています。
影響が及ぶ可能性のある範囲は非常に広く、PHPを利用するエコシステム全体に及ぶ。
Talosの初期推定では、パッチを受け取れないPHPシステムが約50%あります。
※PHP 8.1以前はサポートが終了しておりパッチは提供されません。PHP 8.2のセキュリティサポートも2026年12月31日に終了します。
Talosは公開から数時間以内に悪用の試行を観測しています。現時点では大半がスキャンですが、今後は攻撃の量が増え手口も組織的になるとTalosは予測しています。英語版の記事にIoCとしてIPアドレス6件が掲載されているのでご活用ください。
Splunk Security Solution Architectチームでは、自組織への攻撃を調べるSPLを作成し、このブログで公開しました。対象はTalosが公開したSnortシグネチャです。自組織の状況把握のために是非ご活用ください。
修正版を当てられないときの緩和策
Talosは修正済みリリースへのアップグレードを強く推奨しています。包括的な保護となる暫定策はありません。ただしphp foundationのadvisoryでは、次の設定で特定の攻撃経路への露出を減らせる可能性があります。
- CVE-2026-109618:memory_limit=-1の設定、post_max_sizeの縮小、コンテナやcgroupによるメモリ制限
- CVE-2026-109619:session.upload_progress.enabled=0の設定とワーカーの再起動
設定の適用方法と注意点はTalosの報告に詳しく書かれています。適用前に原文をご確認ください。
Splunkによる調査
前提
Talosはこれらの脆弱性を検知するSnortのSIDとして67359、67360、67375を開発、公開しました(Community rulesetでも公開)。Cisco Secure FirewallにはSnortが含まれるため、最新のシグネチャセットを使う事で、これらのSIDの検知をSplunkで調査できます。Cisco Secure FirewallのログをSplunkに取り込むには以下のAppをご利用ください。取り込んだログのsourcetypeはcisco:sfw:estreamerです。
なお、以下のSPLはCIMではなくCisco Security Cloud Appが付与するフィールド名を前提にしています。
また、これらのSIDは無料のCommunity Rulesetでも公開されています。Snort本体をはじめ、Snortを利用する他の製品でも同じSIDで調査できる可能性があります。ただし製品によってはIPSのポリシーやルールの更新タイミングによりこれらのSIDがすぐに有効にならない場合があります。ログのsourcetypeやフィールド名も製品ごとに異なるため、以下のSPLは環境に合わせて書き換えてください。
SPL:Snort SIDの検知を集計する
[YOUR_INDEX]は自組織のindexに置き換えてください。
index=[YOUR_INDEX] sourcetype="cisco:sfw:estreamer" EventType=IntrusionEvent
signature_id IN (67359, 67360, 67375)
| fillnull value="unknown"
src dest dest_port transport signature_id signature
class_desc MitreAttackGroups rule
InlineResult InlineResultReason app
| stats count as event_count
min(_time) as firstTime
max(_time) as lastTime
by src dest dest_port transport signature_id signature
class_desc MitreAttackGroups rule
InlineResult InlineResultReason app
| eval firstTime=strftime(firstTime,"%F %T"), lastTime=strftime(lastTime,"%F %T")
| sort - event_count
このSPLは送信元、宛先、SIDなどの組み合わせごとに、検知の件数と最初と最後の時刻を集計します。結果で特に確認したいのはInlineResultとInlineResultReasonです。この2つのフィールドでCisco Secure Firewallが通信を遮断したのか、検知だけで通過させたのかを区別できます。
たとえば侵入ポリシーが検知モードのとき、InlineResultはalertなどになり通信は遮断されていません。検知だけで通過した通信の宛先(dest)は、攻撃が届いているPHPサーバーの候補です。これらのサーバーから優先して、PHPのバージョンとパッチの適用状況をご確認ください。なお、検知は攻撃の成功を意味しません。スキャンだけの可能性もあることにご注意ください。
また、Snortが検査できるのはCisco Secure Firewallを経由する通信だけです。TLSの復号を設定していない場合、HTTPSの中身は検査できませんので、検知がなくても攻撃を受けていないとは言い切れません。
SPL:httpdのログから攻撃を検知する
CVE-2026-109618及びCVE-2026-109619を突く為のPoCは多数公開されており、その攻撃手法は複数種、確認されています。今回、検知用のSPLを検討するにあたり参考としたのが、韓国のセキュリティ企業、78ResearchLab社のPoCです。公開されているPoCを検証した結果、httpdのログ(apacheのaccess.log及びerror.log)から攻撃の痕跡が確認できました。
httpd (apache)のログの観点では、apacheのプロセスがコアダンプを出力してプロセスが終了するメッセージ(AH00051)を出力する事、直前にPOSTリクエストによるphpへのリクエストが多数試行された事から、これらの情報を集計します。先にも書きましたが、この脆弱性を突くと称するPoCは複数公開されており、その手法は異なります。しかしながら、phpへのリクエストとhttpdのクラッシュが近い時間で記録される可能性は高いと考え、SPLを作成しました。
環境に合わせてカスタマイズする必要はありますが、Threat Huntingの参考としてください。
index=[YOUR_INDEX] ((sourcetype=apache:access:combined http_method=POST) OR (sourcetype=apache:error ("AH00051" OR "exit signal" OR "Allowed memory size")))
| eval src=coalesce(src, client, clientip), uri=coalesce(uri_path, url)
| eval is_php_post=if(match(sourcetype,"access") AND (match(uri, "(?i)\.(php\d?|phtml)$") OR uri="/"), 1, 0)
| eval is_crash=if(sourcetype="apache:error" AND match(_raw, "AH00051|exit signal"), 1, 0)
| eval is_oom=if(sourcetype="apache:error" AND match(_raw, "Allowed memory size of \d+ bytes exhausted"), 1, 0)
| rex field=_raw "exit signal (?<signal>[A-Za-z ]+?)\s*\(\d+\)"
| eval post_src=if(is_php_post=1, src, null()), post_time=if(is_php_post=1, _time, null())
| sort 0 host _time
| streamstats current=f last(post_src) as last_post_src last(post_time) as last_post_time by host
| eval src=if(is_crash=1 OR is_oom=1, if(_time-last_post_time<=5, last_post_src, null()), src)
| where isnotnull(src) AND (is_php_post=1 OR is_crash=1 OR is_oom=1)
| stats sum(is_php_post) as php_post sum(is_crash) as worker_crash sum(is_oom) as php_oom values(signal) as signals
values(eval(if(is_php_post=1, uri, null()))) as php_target min(_time) as firstTime max(_time) as lastTime by host src
| where php_post>=10 AND (worker_crash>=1 OR php_oom>=1)
| eval severity=case(match(mvjoin(signals,","),"Segmentation fault|Bus error|Illegal") AND worker_crash>=2, "critical",
worker_crash>=3 OR php_oom>=1, "high", true(), "medium")
| convert ctime(firstTime) ctime(lastTime)
78ResearchLabのPoC実行結果ログ
78ResearchLabのPoCログ集計SPLの実行結果
検証に使用した、Apacheのログの分析には以下のAdd-onを使用しています。
Splunk Add-on for Apache Web Server
SPL:TalosのIoCと照合する(例)
IoCを照合する場合の例です。Talos英語版に掲載された6件のIPアドレスを、ファイアウォールとWebサーバーのログに照合します。
- 原文のIPアドレスは5.191.140[.]240のように表記されているため、[.]を.に戻して入力しています
- [YOUR_FW_INDEX]と[YOUR_WEB_INDEX]は自組織のindexに置き換えてください
- ログによって送信元IPアドレスがsrcではなく、clientip等の場合は読み替えてください
また、場合によっては前段にCDNやALBがある場合、本当の送信元IPアドレスはX-Forwarded-Forヘッダーにしかない場合もあるためご注意ください。
(index=[YOUR_FW_INDEX] OR index=[YOUR_WEB_INDEX])
src IN ("5.191.140.240", "158.69.113.75", "94.154.43.149",
"143.246.223.124", "45.198.224.169", "85.11.167.243")
| stats count
dc(dest) as uniq_dest
values(dest_port) as dest_ports
values(action) as actions
sum(bytes_out) as bytes_out
min(_time) as firstTime max(_time) as lastTime
by src sourcetype
| eval total_MB=round(bytes_out/1024/1024, 2),
firstTime=strftime(firstTime, "%F %T"),
lastTime=strftime(lastTime, "%F %T")
| table src sourcetype count uniq_dest dest_ports actions total_MB firstTime lastTime
| sort - count
ESCUの検知
Splunk Enterprise Security (Splunk ES)向けの検知コンテンツとしてEnterprise Security Content Update (ESCU)があり、PHP2Shellのアナリティクスストーリー(検知ユースケース集)が10月22日に公開されました。このストーリーには7つの検知が含まれます。
たとえば次のような検知があります。
- アップロードのファイル名にPHPのシリアライズ構造を含む、PHP_SESSION_UPLOAD_PROGRESS付きのリクエスト
- マルチパートのリクエストとPHPのメモリ枯渇エラーの相関
- Webサーバーからのシェルの起動
Splunk ESをご利用でWebサーバーやエンドポイントのログを取り込んでいる環境では是非こちらもご利用ください。
まとめ
公表される脆弱性が増え続けるなかで、すべての脆弱性に対して等しく対応することは現実的ではないと指摘されています。脆弱性対応については米国CISAが「BOD 26-04: Prioritizing Security Updates Based on Risk」を公開しており、文書内でリスクベースでの脆弱性対応の優先度付けの重要性を謳っています。
Talosでは、インターネットに公開されたシステムと、実際に悪用されている脆弱性を優先するよう勧めています。その他にも、自組織内の重要なシステムを特定しておくことも重要です。Talosは開示に関わった組織から判断して、この脆弱性の発見にAIとその関連技術が重要な役割を果たしたとみています。AIが脆弱性の発見を速めているなら、守る側も検知から対応までの時間を縮める必要があります。
Splunk ESはAgentic SOCの機能群を提供しており、トリアージから対応などSOC業務をAIで自動化できます。ESをお使いでない場合も、Splunk EnterpriseとSplunk CloudではAI Toolkitを使用しAI Agentを独自実装できます。また、Splunk MCP Serverを使えば自組織で利用しているAIとSplunkを接続できます。
-
AI Toolkit
-
Splunk MCP Server
AIを活用した防御態勢づくりを我々Splunkもお手伝いできればと思います。
補足:Splunk製品への影響
Splunkは10月22日にアドバイザリSVD-2026-1013を公開しました。
各製品の状況は調査に応じて更新されるため、最新の状況はアドバイザリをご確認ください。
参考資料
- Two critical RCEs in PHP core (Cisco Talos 2026/10/21)
- PHP コアの深刻な RCE 脆弱性について (Cisco Japan Blog 2026/10/22)
- PHP2Shell: Full-Chain RCE Exploitation of CVE-2026-109618 and CVE-2026-109619 (78ResearchLab 2026/10/22)
- Analytics Story: PHP2Shell (Splunk Security Content)
- SVD-2026-1013 Vulnerabilities in PHP (CVE-2026-109618, CVE-2026-109619) on Splunk Products - October 2026 (Splunk 2026/10/22)
関連記事

<第3回>Splunkでセキュリティダッシュボードを作成しよう!データの取り込み(その2)

自律的な防御への進化:エージェンティックSOCの新しい機能
