
CVE-2026-109618/109619 — 5つのRCEチェーン + 検出ルール(Suricata、Sigma、ModSecurity)。PHP session.upload_progress の認証前エクスプロイト研究。
CVE-2026-109618 & CVE-2026-109619 — PHP Pre-Auth RCE Exploit & Detection Toolkit
Exploits · Detection · Lab · Writeup
PHPのsession.upload_progressとZendエンジンのOOMベイルアウトを悪用する5つの独立したRCEチェーン。14年にわたる脆弱なコード — PHP 5.4.0(2012年)から8.5.11まで。Pre-auth。一部のチェーンではアプリケーション側の脆弱性を必要としない。
全ウェブサイトの78% に影響 — WordPress(43%)、Joomla、Drupal、Laravel、Magento、およびすべてのデフォルトPHPインストールを含む。
著者: Qi Deng | Writeup: Substack | 日付: 2026-10-21
| CVE | GHSA | CVSS | 説明 |
|---|---|---|---|
| CVE-2026-109618 | GHSA-w8hw-w9fx-j79w | 9.2 | OOM → longjmp()によりZendエンジンの状態が無効化 → RCE |
| CVE-2026-109619 | GHSA-6wmf-4rv5-p3rp | 9.2 | FPMワーカーのリクエスト間でグローバル状態が陳腐化 → UAF → RCE |
パッチ: Commit 3584a98 — Zendエンジン全体で300ファイルが変更。
| チェーン | ベクター | Pre-auth | 条件 | SAPI |
|---|---|---|---|---|
| A | セッションインジェクション + LFI | はい | アプリに任意のLFIシンクがある | すべて |
| B | var_destroy UAF → ハンドラ上書き | いいえ | アプリがunserialize()を呼び出す | すべて |
| C | ハンドラ不一致 → __destruct | はい | serialize_handlerが異なる2つのディレクトリ | FPM |
| D | OOM破壊 → 陳腐化したEG() | はい | なし — 任意のエンドポイント | mod_php |
| E | FPMセッションOOM → 陳腐化したBG() | はい | プロデューサー: 任意のsession_start()エンドポイント; コンシューマー: 任意のエンドポイント | FPM |
チェーンDが最も深刻: 任意のApache mod_phpインストールに対するゼロ依存のPre-auth RCE。
チェーンEはFPM上でほぼ同様に広範: プロデューサーはsession_start()を呼び出す任意のエンドポイントを必要とし(ほぼ普遍的 — WordPress、Laravel、Joomla、Drupalはいずれも該当)、コンシューマーは任意のPHPエンドポイントでよい — rfc1867のupload_progressハンドラはアプリケーションコードより前にSAPI起動中に実行される。検証済み: nosession.php(コード内にsession_start()なし)が陳腐化したBG(unserialize)状態を消費すると502クラッシュを引き起こす。
3つのRCEエクスプロイト(チェーンA、B、C)がexploit/に含まれている:
| ファイル | チェーン | 動作内容 |
|---|---|---|
chain_a_session_lfi.py | A | アップロードファイル名経由でPHPコードを注入 → LFIがセッションファイルをインクルード → RCE |
chain_b_uaf_rce.php | B | var_destroy UAF → EG()経由でzif_systemを発見 → /proc/self/mem経由でvar_dumpハンドラを上書き → RCE |
chain_c_mismatch_rce.py | C | FPMワーカーのPS(serializer)を汚染 → ファイル名経由でシリアライズオブジェクトを注入 → デコード失敗時に__destructが発火 → RCE |
チェーンDとEのエクスプロイトは有料購読者が利用できます。
# Chain A: Session injection + LFI → RCE
python3 exploit/chain_a_session_lfi.py --host TARGET --port 80 --command 'id'
# Chain B: var_destroy UAF → RCE (run on target or via uploaded webshell)
php exploit/chain_b_uaf_rce.php
# Chain C: Handler mismatch → __destruct → RCE
python3 exploit/chain_c_mismatch_rce.py --host TARGET --port 80 --command 'id'
detection/ にある事前構築済みの IDS / WAF / SIEM ルール:
| ファイル | 形式 | シグネチャ |
|---|---|---|
php2shell.rules | Suricata / Snort | 13 ルール — リクエスト、レスポンス、偵察 |
php2shell.yaml | Sigma | 5 ルール — Web ログ、プロセス生成、ファイルイベント |
modsecurity.conf | ModSecurity v2/v3 | 7 ルール — Apache/Nginx 向けドロップイン |
php2shell.lua | OpenResty Lua | 軽量リバースプロキシモジュール |
最速の緩和策: multipart POST ボディ内の PHP_SESSION_UPLOAD_PROGRESS をブロックする。正当な用途はほぼゼロであり、両方の CVE における主要な攻撃ベクトルをカバーする。
git clone https://github.com/ikow/php2shell-poc.git && cd php2shell-poc
# Start the lab (PHP-FPM + nginx + Apache mod_php)
cd lab && docker compose up -d
# Verify each chain
python3 ../poc/verify_session_injection.py --target http://127.0.0.1:18080
python3 ../poc/verify_handler_mismatch.py --target http://127.0.0.1:18080
python3 ../poc/verify_oom_trigger.py --host 127.0.0.1 --port 18081
python3 ../poc/verify_fpm_stale_state.py --target http://127.0.0.1:18080
# Run an exploit
python3 ../exploit/chain_a_session_lfi.py --host 127.0.0.1 --port 18080 --command 'id'
php2shell-poc/
├── exploit/
│ ├── chain_a_session_lfi.py # RCE: session injection + LFI
│ ├── chain_b_uaf_rce.php # RCE: var_destroy UAF → handler overwrite
│ └── chain_c_mismatch_rce.py # RCE: handler mismatch → __destruct
├── detection/
│ ├── php2shell.rules # Suricata / Snort IDS rules
│ ├── php2shell.yaml # Sigma SIEM detection rules
│ ├── modsecurity.conf # ModSecurity WAF rules
│ └── php2shell.lua # OpenResty / Nginx Lua WAF module
├── poc/
│ ├── verify_session_injection.py # Verify Chain A
│ ├── verify_uaf_asan.php # Verify Chain B (ASAN)
│ ├── verify_handler_mismatch.py # Verify Chain C
│ ├── verify_oom_trigger.py # Verify Chain D
│ └── verify_fpm_stale_state.py # Verify Chain E
├── lab/
│ ├── docker-compose.yml # PHP-FPM + nginx + Apache mod_php
│ ├── setup.sh # One-click lab setup
│ └── php.ini / php-apache.ini # Vulnerable PHP configs
└── docs/
├── ANALYSIS.md # Full technical analysis
└── substack_article.md # Writeup source
; Immediate — reduces attack surface
session.upload_progress.enabled = Off
session.use_only_cookies = On
唯一の完全な修正はPHPを 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12+ にパッチすることです。OOMによる破損(チェーンD)はZendエンジンのコアにあり、INI設定では修正できません。
Wizは標準的なコンテナイメージ上で事前認証RCEを実証しました:
| プラットフォーム | 脆弱 | 備考 |
|---|---|---|
| WordPress | はい | コアはPHPセッションを使用しませんが、WooCommerceや多くのプラグインが使用しています |
| Joomla | はい | デフォルトでネイティブPHPセッションを使用します |
| Drupal | はい | デフォルトでネイティブPHPセッションを使用します |
| Magento | はい | メンテナンスモードでも脆弱です |
| Laravel | はい | PendingBroadcast は既知の __destruct ガジェットです |
このリポジトリは許可されたセキュリティテストおよび教育目的のみを対象としています。チェーンDおよびE(ゼロ依存RCE)のエクスプロイトコードは、解説記事の有料購読者が利用できます。
MIT