
CVE-2026-42945を解析し、NGINXのrewriteヒープオーバーランについて、差分検出器、決定的なDoS PoC、および検証付きのクレジット付きRCEポートを提供します。
CVE-2026-42945(CVSS 4.0 9.2 CRITICAL)に関するセキュリティ研究: NGINXのスクリプトエンジンにおけるヒープバッファオーバーランで、置換文字列に引数を含むrewrite(例: rewrite ^(.*) /new?c=1;)がエンジンのis_argsフラグを設定したままクリアしないため、その後にset/ifで評価される任意のキャプチャ($1)が、エスケープされていない長さ用にサイズ設定されたバッファにURIエスケープ付きでコピーされます。リクエストURIに%XXエスケープまたは+を含む任意のクライアントが、認証前で到達可能です。
結果(フェーズ1): 安全な差分検出器(脆弱な1.30.0と修正済み1.30.1、クラッシュゼロ)と、決定的なワーカーDoS(SIGSEGV、コアダンプ — レスポンスは最初に完全に配信されます)。両方とも、コミット71d62c6でソースからコンパイルされたビルドに対して再現されました。
結果(フェーズ2): 報告者のRCEのクレジット付き移植 — ワーカーユーザー(nobody)としてのsystem()実行が、lab/rce/で複製された報告者の固定ビルドに対して3/3回のクリーンな実行で再現されました。悪用手法は**Leo Lin(DepthFirst)**によるものです。ここでの独自性と先行研究の違いおよびライトアップの先行研究を参照してください。
| 主張 | 証拠 |
|---|---|
| 根本原因は修正コミットから導出(ブログからではない) | finding-sheet |
修正は1行 — ngx_http_script_regex_end_code()内のe->is_args = 0; | コミット524977e(writeupに引用) |
| 安全な検出器: 脆弱vs修正済みオラクル、クラッシュゼロ | poc/diagnose.py — 切り詰めフィンガープリント(/foo%25b vs /foo%bar) |
| トリガーマトリクス: 引用符付き/プラスURI およびキャプチャ内のエスケープ可能文字 — 両方必須 | poc/diagnose.pyプローブバッテリー(/a%41bコントロールを含む) |
| 決定的なワーカーDoS(SIGSEGV、コアダンプ、レスポンスが最初に配信) | poc/crash.py — X-Worker-PIDの変更がワーカーの死亡を証明 |
| 修正済み1.30.1は同一攻撃を生き残る | poc/crash.py --host 127.0.0.1:29544 — 3/3ラウンド生存 |
| RCE(フェーズ2、報告者の手法、クレジット付き移植) | exploit/rce.py — 3/3実行、証明ファイル+uid=65534(nobody)、実行後にワーカーがexited on signal 11 |
# 差分ペア: ソースからビルドされたnginx 1.30.0(:29543)+ 1.30.1(:29544)
cd lab && docker compose up -d --build && cd ..
python3 poc/diagnose.py # 安全なオラクル — どちらのワーカーもクラッシュさせない
python3 poc/crash.py --host 127.0.0.1:29543 # 1.30.0: ワーカーがシグナル11で死亡、コアダンプ
python3 poc/crash.py --host 127.0.0.1:29544 # 1.30.1: すべてのラウンドを生存
docker logs cve-42945-vuln 2>&1 | grep 'exited on signal' | tail -3
フェーズ2 — 報告者の固定ビルドに対するRCE(nginx devリビジョン
98fc3bb7 = release-1.29.8-14、固定エントリポイントによりASLR無効):
docker compose -f lab/rce/docker-compose.yml up -d --build # :29545、ビルドに数分
python3 exploit/rce.py \
--cmd 'echo pwned-by-cve-2026-42945 > /tmp/proof' --verify --expect pwned
docker compose -f lab/rce/docker-compose.yml exec nginx cat /tmp/proof
| ドキュメント | 内容 |
|---|---|
| docs/finding-sheet.md | 1ページのデータシート: バージョン、CVSS、設定パターン、トリガー条件、検出シグネチャ |
| docs/report-ptes.md | PTES構造のレポート(7フェーズ)、実際に実施した範囲に限定 |
| docs/research-writeup.md | 調査の物語 — 修正コミットの考古学、切り詰めの驚き、移植可能な教訓、今後の作業 |
フェーズ1の研究チェーンは独自の作業です: クラッシュフリーの差分オラクルとその切り詰めフィンガープリント(配信されるボディは生の長さに切り詰められた再エスケープキャプチャ — 長さ/値の2パス不一致の可視シグネチャ)、両方の前提条件が必要であることを証明するトリガーマトリクス、長さパスがis_argsを認識できない理由のソースレベルでの説明、およびレスポンス後の決定的なワーカーキル。バグ自体、脆弱な設定パターン、修正コミットの分析は報告者と上流による先行研究です — **Leo Lin(DepthFirst)**が問題を開示し、Roman Arutyunyanが修正しました。ライトアップの先行研究セクションとDepthFirst Disclosures — Nginx-Rift、ツリーCVE-2026-42945を参照してください。
フェーズ2(RCE)は報告者の公開エクスプロイトの移植であり、独立したチェーンではありません: オーバーランを隣接するリクエストプールのcleanupポインタに着地させるクロスリクエストヒープフェングシュイ、保持されたPOSTボディを介した偽のngx_pool_cleanup_tスプレー、libc system()へのクリーンアップディスパッチリダイレクト、オーバーフロー形状(349 A + 969 + + 6ターゲットバイト)、ASLRなしのベース/オフセット定数、およびlab/rce/の固定ビルド(彼らのenv/)はすべてLeo Linの設計であり、exploit/rce.pyでクレジット付きで再現されています。フェーズ2での独自部分: 移植自体 — このリポジトリのCLI/ロギング/検証規約、ライブヒープスキャン候補発見とベース自動検出(彼らの静的定数はカーネル依存です。エクスプロイトのdocstringを参照)、stdlibリバースシェルリスナー、および検証証拠。
このリポジトリはCVE-2026-42533 — NGINX Pre-Auth Heap Overflow: Analysis & RCE(兄弟リポジトリ)と方法論を共有しています: nginxスクリプトエンジンにおける同じ2パス長さ/値バグクラスで、そちらでは完全な認証前RCEチェーンまで到達しています。そのチェーンはこのバグの可能な上限を区切りました。このリポジトリのフェーズ2はここで同じ上限に到達します — 報告者の手法のクレジット付き移植としてであり、独立したチェーンではありません。
docs/ finding sheet · PTESレポート · 研究ライトアップ
poc/ diagnose.py(安全な差分オラクル)· crash.py(決定的DoS)
exploit/ rce.py — 報告者のsystem()チェーンのクレジット付き移植
lab/ Dockerfile(ソースからのnginx、-g -O0)+ 差分composeペア
lab/nginx/ vulnerable.conf — 修正コミットからのPoC設定
lab/rce/ 報告者の固定RCE環境(彼らのenv/、私たちのポートマッピング)
524977e7c534
"Rewrite: fixed escaping and possible buffer overrun"(Roman Arutyunyan)— nginx 1.30.1でリリースCVE-2026-42945(報告者の先行研究; Leo Lin)教育用研究アーティファクト。所有しているシステム、または明示的にテストを許可されたシステムに対してのみ実行してください。この脆弱性はパッチ済みです — nginxを≥ 1.30.1にアップグレードしてください。