Skip to content
KitploitKITPLOIT
ツールブログ
Log in
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-42945 — CVE-2026-42945に関する完全な調査リポジトリ。ヒープバッファオーバーフロー解析、RCEエクスプロイト(ヒープスプレー+Feng Shui)、検出スクリプト、NGINX rewriteモジュールの脆弱性に対するパッチ適用ガイダンスを含みます。 | Kitploit
ツール/GitHubGitHub/quantumworld-dpdns-io/cve-2026-42945
脆弱性分析エクスプロイトウェブセキュリティファジングペネトレーションテスト学習と教育インシデントレスポンスバイナリエクスプロイトラボと実践
GitHubquantumworld-dpdns-io/cve-2026-42945

CVE-2026-42945

CVE-2026-42945に関する完全な調査リポジトリ。ヒープバッファオーバーフロー解析、RCEエクスプロイト(ヒープスプレー+Feng Shui)、検出スクリプト、NGINX rewriteモジュールの脆弱性に対するパッチ適用ガイダンスを含みます。

リポジトリを見る
134ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
Screenshot 2026-05-28 at 4 09 53 PM

CVE-2026-42945 — NGINX Rift

NGINX ngx_http_rewrite_module におけるヒープバッファオーバーフロー

項目値
CVSS v4.09.2(緊急)
CVSS v3.18.1(高) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE122 — ヒープベースのバッファオーバーフロー
導入時期2008年6月 — v0.6.27
発見2026年4月 — DepthFirst Research
修正2026年5月13日 — v1.30.1、v1.31.0
CVE公開2026年5月21日
潜伏期間約18年(未検出)
修正コミット524977e7c534e87e5b55739fa74601c9f1102686

目次

  1. 脆弱性の概要
  2. 根本原因の分析
  3. 悪用のメカニズム
  4. 修正内容の分析
  5. 影響を受けるバージョン
  6. 検出
  7. 緩和策
  8. プロジェクト構成
  9. クイックスタート
  10. 脆弱なバージョンのビルドと実行
  11. オーバーフローのトリガー
  12. RCEエクスプロイト
  13. リバースシェルの検証
  14. パッチ適用
  15. テスト
  16. ファジング
  17. CIパイプライン
  18. ドキュメント索引
  19. プロジェクト統計
  20. 参考文献

1. 脆弱性の概要

認証されていないリモート攻撃者は、特定の rewrite + set/if/rewrite 構成パターンを持つサーバーに対して細工したHTTPリクエストを送信することで、NGINXのワーカープロセスに決定論的なヒープバッファオーバーフローを引き起こすことができます。このオーバーフローはヒープメタデータ(ngx_pool_cleanup_t ポインタ)を破壊し、ヒープスプレーとFeng Shuiの技術により**リモートコード実行(RCE)**を可能にします。

トリガーパターン```nginx

server { listen 19321;

location ~ ^/api/(.*)$ {
    rewrite ^/api/(.*)$ /internal?migrated=true;
    set $original_endpoint $1;
}

}

**主な要件:**
- 置換文字列に `?`(クエリ文字列区切り文字)を含む `rewrite` ディレクティブ
- その後に続く `set`、`if`、または `rewrite` ディレクティブが **名前なしPCREキャプチャ**(`$1`、`$2` など)を参照している
- rewrite の置換文字列内の `?` が `ngx_http_script_start_args_code` をトリガーし、`e->is_args = 1` を設定する

### 攻撃者が達成できること

| 能力 | 説明 |
|-----------|-------------|
| **サービス拒否 (Denial of Service)** | ワーカープロセスを決定的にクラッシュさせ、再スポーンループを引き起こす(ASLR の有無に関係なく機能) |
| **リモートコード実行 (Remote Code Execution)** | ASLR が無効(または部分的な上書きでバイパス)の場合、nginx ユーザーとして完全な RCE を達成 |
| **データ漏えい (Data Exfiltration)** | メモリ読み取りプリミティブを通じて、ワーカーヒープから機密データを抽出 |
| **永続化 (Persistence)** | ワーカープロセスメモリ内でのコード実行によりバックドアを仕込む |

---

## 2. 根本原因分析

### 2パススクリプトエンジン

NGINX の `ngx_http_rewrite_module` は、`src/http/ngx_http_script.c` 内で **2パススクリプトエンジン** を使用しています:

1. **長さパス** (`ngx_http_script_run`): すべてのスクリプトコードを反復処理し、必要なバッファサイズの合計を計算します。長さを `le.ip` と `le.pos` に書き込みます。
2. **コピーパス** (`ngx_http_script_copy_len`/`_code`): 再度反復処理し、事前に割り当てられたバッファ内の `e->ip` と `e->pos` に実際のバイトを書き込みます。

各スクリプトコードには、各パスに対応する2つのハンドラがあります。例:
- `ngx_http_script_copy_len` → `ngx_http_script_copy_code`
- `ngx_http_script_start_args_len` → `ngx_http_script_start_args_code`

### `is_args` フラグ

**エンジン構造体** (`ngx_http_script_engine_t`) 上のフラグ `e->is_args` は、コピーパスが特定の文字をどのように処理するかを制御します。```c
typedef struct {
    u_char                  *ip;
    u_char                  *pos;
    ngx_http_variable_value_t *sp;
    ngx_str_t               buf;
    int                     flushed;
    unsigned                is_args:1;    // <-- THE BUG
    unsigned                ncaptures:1;
    ngx_uint_t              captures_size;
    // ...
} ngx_http_script_engine_t;

When e->is_args = 1, the copy-code for $N capture references calls ngx_escape_uri() with NGX_ESCAPE_ARGS, which expands:

  • + → %2B (1 byte → 3 bytes, +200%)
  • % → %25 (1 byte → 3 bytes, +200%)
  • & → %26 (1 byte → 3 bytes, +200%)

バグ: パス間でのフラグ漏洩

脆弱なパターンに対する実行フロー:``` rewrite ^/api/(.*)$ /internal?migrated=true;

1. **リライト評価**中に、エンジンは置換文字列内の`?`に遭遇し、`ngx_http_script_start_args_code`をトリガーして、`e->is_args = 1`を設定します。
2. リライトはリクエストURIを変更し、続いて次のディレクティブに進みます。
3. **`e->is_args`は決してクリアされません**。

次に:```
set $original_endpoint $1;
  1. 長さパスのために新しいサブエンジン(le)が作成されます: ```c ngx_memzero(&le, sizeof(ngx_http_script_engine_t));

これにより le.is_args = 0 が正しくゼロになるため、長さパスは生の、エスケープされていないキャプチャ長を返します。

  1. コピーパスはメインエンジン e を再利用します。この e はステップ1から e->is_args = 1 のままです。コピーパスはURIエスケープを適用し、エスケープ可能な各文字を、raw長に合わせてサイズ設定されたバッファ内で1バイトから3バイトに展開します — ヒープオーバーフロー。

ビジュアルウォークスルー```

Pass 1 (Length — sub-engine le): le.is_args = 0 capture $1 = "A+++++B" → length = 7

Buffer allocated: 7 bytes

Pass 2 (Copy — main engine e): e.is_args = 1 ← LEAKED from rewrite capture $1 = "A+++++B" ngx_escape_uri("A+++++B", NGX_ESCAPE_ARGS): A → A (1 byte) + → %2B (3 bytes) ← EXPANSION + → %2B (3 bytes) + → %2B (3 bytes) + → %2B (3 bytes) + → %2B (3 bytes) B → B (1 byte) total written: 17 bytes buffer size: 7 bytes OVERFLOW: 10 bytes

展開倍率は `7 + (n_escapable * 2)` です。ここで `n_escapable` はキャプチャ内の `+`、`%`、`&` の数です。

---

## 3. 悪用のメカニズム

### 概要

| ステップ | 技術 | 説明 |
|------|-----------|-------------|
| 1 | オーバーフロー | `+` パディングを含む細工した URI を送信し、ヒープバッファをオーバーフローさせる |
| 2 | ヒープスプレー | `/spray` に大きなボディを POST し、制御したデータでヒープを埋める |
| 3 | Feng Shui | オーバーフロー対象(`ngx_pool_cleanup_t`)が隣接するように割り当てを調整する |
| 4 | ハンドラの破壊 | オーバーフローで `ngx_pool_cleanup_t.handler` を `system()` のアドレスで上書きする |
| 5 | クリーンアップのトリガー | プールの破棄を待機 → `system(cmd)` が攻撃者のコマンドを実行する |
| 6 | リバースシェル | リバースシェルペイロードに連鎖させ、インタラクティブなアクセスを得る |

### リクエスト横断型 Feng Shui

**単一リクエストの Feng Shui は失敗します**。オーバーフローが `cleanup` ポインタに到達する前に、プールのメタデータ(`->d.next`、`->d.failed`)を破壊してしまうためです。リクエスト終了時にプールが破棄されると、破壊されたメタデータが原因で **`system()` が呼び出される前にクラッシュ** します。

代わりに、このエクスプロイトは **リクエスト横断型 Feng Shui** を使用します。
1. **リクエスト 1(スプレー)**: `/spray` に大きなボディを POST します。バックエンド(`server.py`)は `X-Delay` ヘッダーでレスポンスを保持し、接続を開いたままにしてヒープの割り当てを維持します。スプレーによって、偽の `ngx_pool_cleanup_t` ブロックでヒープが埋められます。
2. **リクエスト 2(オーバーフロー)**: オーバーフロー URI を送信します。オーバーフローは `cleanup` ポインタのみを破壊し(プールのメタデータは破壊せず)、スプレーした偽ブロックを指すようにします。
3. **プールの破棄**: スプレーのレスポンスが完了すると(遅延が期限切れになると)、プールのクリーンアップチェーンは偽ブロックに移動し、`system(cmd)` を呼び出します。

### アドレス要件

| シンボル | 値(Docker、ASLR 無効) | 説明 |
|--------|--------------------------|-------------|
| `HEAP_BASE` | `0x555555659000` | nginx ヒープのベース |
| `system@libc` | `0x7ffff6f6e420` | glibc 内の `system()` |
| `NGX_CYCLES_POOL` | `0x5555556a4040` | cycles プールへのポインタ |
| 偽クリーンアップアドレス | `0x5555556a4030` | スプレーのターゲットアドレス |

### ASLR バイパス

ASLR を無効にしなくても、**DoS**(クラッシュ)は決定的に動作します。ASLR が有効な状態での RCE には、2 つのアプローチがあります。

1. **部分的な上書き**: 1 バイトまたは 2 バイトの上書きを使用して、同じページ内でポインタをずらし、残りのニブルを総当たりします(16〜256 回の試行)。
2. **情報漏洩**: `/proc/self/maps` を読み取るか、`log_parser.py` のメモリ分析を使用してレイアウトを特定します。

---

## 4. 修正の分析

### 公式修正

**コミット**: `524977e7c534e87e5b55739fa74601c9f1102686`  
**ファイル**: `src/http/ngx_http_script.c`  
**行**: 約 1205(`ngx_http_script_regex_end_code` 内)```diff
 void
 ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
 {
     ngx_http_script_regex_code_t *code;

     code = (ngx_http_script_regex_code_t *) e->ip;

+    e->is_args = 0;    /* ← THE FIX */

     e->ip += sizeof(ngx_http_script_regex_code_t);
     // ...
 }

この場所が正しい理由

ngx_http_script_regex_end_code は、長さパスとコピーパスの両方で すべての正規表現評価の後 に実行されます。ここで e->is_args = 0 をリセットすることで、以下が保証されます:

  • フラグは、正規表現コードの実行が終了した 直後に クリアされます
  • 後続のスクリプトコード (set, if, rewrite) はクリーンな is_args = 0 で開始されます
  • ngx_http_script_start_args_code は、置換文字列内で ? を検出したときに is_args = 1 を設定できます — この修正はその機能を壊しません

多層防御パッチ

patches/0002-hardening-bounds-check.patch は ngx_http_script_copy_capture_code に境界チェックを追加します:```c if (e->pos + len > e->buf.data + e->buf.len) { return; /* gracefully truncate instead of overflowing */ }

### バックポートパッチ
ツールをダウンロード