
CVE-2026-23918 Apache http2 RCE の検出ルール - クレジット: stringa.ai, isec.pl
公開日: 2026-05-04
CVSSv3: 8.8 (高)
タイプ: リモートコード実行 / サービス拒否(Double-Free メモリ破損)
コンポーネント: Apache HTTP Server mod_http2(h2_mplx.c ストリームクリーンアップパス)
影響を受けるバージョン: HTTP/2 が有効かつマルチスレッド MPM を使用する Apache HTTP Server 2.4.66
参考情報:
CVE-2026-23918 は、Apache HTTP Server 2.4.66 の HTTP/2 プロトコル実装における二重解放メモリ破損の脆弱性であり、h2_mplx.c 内の mod_http2 モジュールのストリームクリーンアップパスのみに影響します。この脆弱性により、認証されていないリモートの攻撃者が、単一の TCP 接続と 2 つの HTTP/2 フレームを使用して Apache ワーカープロセスをクラッシュ(サービス拒否)させる可能性があります。Debian 派生システムおよび公式 Apache Docker イメージで見られる条件下では、二重解放を完全なリモートコード実行に変えることができます。
DoS の悪用は実際の環境で確認されています。HTTP/2 エンドポイントを標的とした大規模なインターネットスキャンが観測されています。RCE エクスプロイトは管理環境で実現可能であることが証明されていますが、現時点で RCE が広く一般に悪用されているという証拠はありません。
MPM prefork は影響を受けません。この脆弱性にはマルチスレッド MPM 構成(worker、event など)が必要です。CVE-2026-23918 は Apache HTTP Server バージョン 2.4.66 のみに影響します。
Attacker opens HTTP/2 connection to Apache 2.4.66 (mod_http2 loaded, multi-threaded MPM) └─ Sends HTTP/2 HEADERS frame on stream N (opens the stream) └─ Immediately sends RST_STREAM on stream N (non-zero error code) └─ Sent BEFORE the multiplexer has registered the stream
Two nghttp2 callbacks fire in sequence: ├─ on_frame_recv_cb (RST received) → calls h2_mplx_c1_client_rst → m_stream_cleanup └─ on_stream_close_cb (stream closed) → calls h2_mplx_c1_client_rst → m_stream_cleanup
Result: same h2_stream pointer pushed onto spurge[] cleanup array TWICE
c1_purge_streams() iterates spurge[] and calls h2_stream_destroy() on each entry: ├─ First call: valid — frees the stream └─ Second call: DOUBLE-FREE — operates on already-freed memory → heap corruption
DoS path (trivial, in the wild): └─ Heap corruption → SIGABRT in worker process → worker dies → service disruption
RCE path (requires mmap allocator — default on Debian/Ubuntu and official Docker): └─ Attacker places fake h2_stream struct at freed virtual address via mmap reuse └─ Points pool cleanup function pointer to system() └─ Uses Apache scoreboard shared memory (fixed address, ASLR-resistant) as payload container └─ c1_purge_streams() executes system() with attacker-controlled argument → RCE
> **主な非対称性:** DoS パスはヒープ操作スキルを必要とせず、積極的に悪用されています。RCE パスは技術的に要求が高く、実験環境では実証済みですが、スコアボードの ASLR 耐性のある固定アドレスを考慮すると、近い将来ほぼ確実に武器化されるでしょう。
---
## 検出アーキテクチャ
> このセクションでは、この検出ツールが典型的なローカル権限昇格パッケージと大きく異なる理由を説明します。
Copy Fail (CVE-2026-31431) は **ホスト側、アクセス後** の脆弱性でした。攻撃者はシステムに既に存在している必要がありました。検出は主に syscall 層 (auditd, Wazuh) と、ディスク上の PoC スクリプトに対する YARA スキャンにありました。
CVE-2026-23918 は **ネットワーク側、アクセス前** の脆弱性です。エクスプロイトは、アプリケーションコードが実行される前に、HTTP/2 プロトコルフレームとしてネットワーク上から到着します。これにより、検出スタックが大きく変化します:
| 層 | Copy Fail (LPE) | CVE-2026-23918 (RCE) |
|---|---|---|
| **主な検出** | Auditd syscall ルール | Suricata ネットワークルール |
| **WAF (ModSecurity)** | 限定的 — エクスプロイトを認識不可 | 関連あり — 異常 + 事後検出 |
| **Auditd** | コア検出 | 結果検出 (クラッシュ、事後検出) |
| **YARA** | PoC スクリプトをスキャン | Web シェルをスキャン (事後検出の痕跡) |
| **ネットワーク IDS** | 非該当 | 最優先の検出層 |
| **TLS 検査** | N/A | Suricata の完全なカバレッジに必要 |
経験則: ネットワークレベルの RCE の場合は、外側から内側へ (ネットワーク → WAF → ホスト) 作業します。ローカル権限昇格の場合は、ホストから外側に向かって作業します。
---
## 検出の制限
> **ルールを展開する前にこれを読んでください。**
**1. TLS により HTTP/2 の可視性が終了します。**
ほとんどの本番環境の Apache デプロイメントは HTTPS を提供しています。Suricata は、TLS 復号化が設定されていない限り、暗号化された HTTP/2 フレームの内容を検査できません。Suricata のデプロイメントが TLS セッションキーまたは復号化ミラーにアクセスできない場合、以下のネットワークレベルのルールは以下のみをキャッチします:
- クリアテキスト HTTP/2 (h2c) — 本番環境では一般的ではありませんが、内部環境には存在します
- TCP 接続動作のネットワークシグネチャ (接続数、TCP 層での RST パターン)
HTTPS デプロイメントの場合は、`tls-decrypt` 設定とセッションキーログを使用して Suricata の TLS 復号化を有効にするか、代わりに WAF (ModSecurity/Coraza) およびホストベース (auditd/Wazuh) 層に依存してください。
**2. ModSecurity はエクスプロイトトリガーをブロックできません。**
ダブルフリーは、完全な HTTP リクエストが組み立てられて ModSecurity に渡される前に、HTTP/2 フレームパーサー内部で発生します。WAF はフレーム解析完了後のみリクエストを認識します — その時点で損害が既に発生している可能性があります。このパッケージの ModSecurity は、異常検出、レート制限、および事後検出に使用され、トリガーのブロッカーとしては使用されません。
**3. MPM prefork は影響を受けません。**
Apache デプロイメントが `mpm_prefork_module` (シングルスレッド) を使用している場合、この脆弱性は該当しません。このバグはマルチスレッド MPM (`mpm_event_module` または `mpm_worker_module`) でのみ現れます。prefork サーバーで誤検出を発生させるルールを展開する前に、`apachectl -V | grep MPM` で確認してください。
**4. RCE には mmap アロケータが必要です。**
RCE パス (DoS パスではない) には APR の mmap アロケータが必要です。これは Debian 派生ディストリビューションおよび公式の Apache Docker イメージのデフォルトです。jemalloc またはシステム malloc を使用する RHEL/CentOS ベースのデプロイメントでは RCE リスクが軽減されますが、DoS に対しては依然として完全に脆弱です。
**5. 安定した事後検出の IoC はまだありません。**
現時点では、事後検出アクティビティに対するベンダー公開の IoC は存在しません。事後検出動作を対象とした YARA ルールおよび auditd ルールは、一般的な Web シェルおよび権限昇格パターンに基づいています — これらは一般的な結果をキャッチしますが、洗練されたカスタムペイロードはキャッチしません。
---
## 即時緩和策
優先順位の高い順に適用してください。各対策は前のものよりも破壊的ですが、より完全になります。```bash
# Option 1 (Preferred): Upgrade to 2.4.67
# See Patching & Remediation section below
# Option 2: Disable HTTP/2 in Apache config (no reboot required, restart required)
# In httpd.conf or relevant VirtualHost / site config:
# Remove or comment out: Protocols h2 h2c http/1.1
# Replace with: Protocols http/1.1
# Then:
apachectl configtest && sudo systemctl restart apache2
# Option 3: Switch to MPM prefork (eliminates vulnerability entirely — more disruptive)
sudo a2dismod mpm_event mpm_worker
sudo a2enmod mpm_prefork
apachectl configtest && sudo systemctl restart apache2
# Option 4: Reverse proxy HTTP/2 termination
# If nginx, HAProxy, or a CDN is in front of Apache and terminates HTTP/2,
# Apache only receives HTTP/1.1 — confirm your proxy config explicitly:
# nginx: proxy_http_version 1.1; (already the default for upstream connections)
# HAProxy: use-server-close + http/1.1 on backend bind
# Verify with: curl -v --http2 https://your-origin-directly
緩和策の確認: HTTP/2を無効にした後、以下で確認してください:
curl -s -o /dev/null -w "%{http_version}" --http2 http://localhost/ # "1.1" を返すべきであり、"2" ではありません apachectl -M | grep http2 # 出力はありません
cve-2026-23918.rules として保存し、suricata.yaml から参照します。