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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-25243 — CVE-2026-25243 — Redis RESTORE zipmap 二重解放 → リモートコード実行(ASLR 有効). | Kitploit
ツール/GitHubGitHub/dinosn/cve-2026-25243
メモリフォレンジック脆弱性分析エクスプロイトリバースエンジニアリングペネトレーションテストリモートアクセスツールペイロード開発バイナリエクスプロイト
GitHubdinosn/cve-2026-25243

CVE-2026-25243

CVE-2026-25243 — Redis RESTORE zipmap 二重解放 → リモートコード実行(ASLR 有効).

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

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2026-25243 — Redis RESTORE zipmap double-free → リモートコード実行

TL;DR. RESTORE に渡された不正な DUMP ペイロードは、Redis の レガシーハッシュ zipmap ローダーでヒープ double-free を引き起こします。 デフォルトの jemalloc では double-free は 無音(サーバーは稼働し続ける)であり、 制御可能な 型混乱(type-confusion) プリミティブになります。このリポジトリはそれを ASLR 有効でのリモートコード実行 に連鎖させます — Redis ワーカーが system("<攻撃者文字列>") を呼び、 サービスを提供し続けます。DoS ではありません。

root@kitploit:~
# デフォルト Redis(DEBUG 無効)、ASLR 有効 — 最も自己完結したエクスプロイト(libc オフセット不要):
$ python3 exploits/poc_rce_aslr_pie_rop.py --cmd "id > /tmp/pwned_pie 2>&1"
[*] self-cal: blob_base=0x7f352d800009 blob_robj=0x7f353286b8d8 pie_base=0x557ea9149000  (NO libc)
[*] fake dictType F=0x7f352e013c36  g1=0x557ea93cca87 execve=0x557ea91cee80
$ cat /tmp/pwned_pie
uid=0(root) gid=0(root) groups=0(root),...    # <- execve("/bin/sh","-c",<cmd>) as the redis process

ASLR を破るリークは DEBUG を一切使いません — redis.call の Lua C-closure アドレスを読み取ります (EVAL 'return tostring(redis.call)')。これは以前の Redis エクスプロイトと同じ、自己完結型で DEBUG 不要の テクニックです。blob_base/blob_robj および PIE ベース は、その後オーバーリードから実行時に導出されます (固定オフセットなし)。PIE-ROP の仕上げは JOP スタックピボットを通じて execve@plt を呼ぶため、 libc アドレスを一切使いません — ビルド固有の定数は redis-server バイナリから読み取る PIE 相対 ガジェットオフセットだけであり、以前の HLL エクスプロイトのビルド別ガジェットテーブルとまったく同じです。 デフォルトの DEBUG 無効サーバー上で uid=0(root)、ASLR 有効、8/8 を確認済みです。

2 つのフィニッシュが用意されています。poc_rce_aslr_pie_rop.py(上記)は最も自己完結型 — libc 不要、完全自己校正 — ただし execve はワーカーを置き換えます(本番シェルにはリバースシェル --cmd を使用)。poc_rce_aslr_selfcal.py はワーカーを生かしたままにします(system() が fork する)が、 その代わり libc バージョン別オフセットが 2 つ必要です。サーバーを存続させる必要があるかどうかで選択してください。


バグ

RESTORE key 0 <DUMP-payload> はシリアライズされたオブジェクトを逆シリアライズします。レガシーな RDB_TYPE_HASH_ZIPMAP(0x09)タイプでは、バリデーターとコンバーターが長さフィールドのバイト数の解釈を めぐって食い違います:

  • zipmapValidateIntegrity() は 実際の エンコード済みサイズ(過長な 0xFE プレフィックスでは 5)で歩みます。
  • zipmapNext() は zipmap → listpack 変換中、デコードされた長さ < 254 に対して 1 バイトを使用します。

過長な 5 バイト形式 で書かれた短い長さは検証を通過しますが、zipmapNext() を 4 バイト誤って ストライドさせます。同じ誤ストライドから 2 つの結果が生じます: ヒープ オーバーリード(zipmap.c)と、 Redis のみで発生する、rdb.c のハッシュ zipmap ローダーでのヒープ double-free です:

root@kitploit:~
sds field = sdstrynewlen(fstr, flen);
if (!field || dictAdd(dupSearchDict, field, NULL) != DICT_OK || !lpSafeToAdd(lp, flen + vlen)) {
    dictRelease(dupSearchDict);   // (1) dictAdd が `field` の所有権を取得 -> ここで解放
    sdsfree(field);               // (2) 再度解放  -> double-free

Valkey はこれをガードしています(if (!field_added) sdsfree(field);)。上流の Redis はガードしていないため、 double-free は Redis のみで発生します。修正は過長エンコードされた短い長さを拒否し、ロード時のチェック順序を 並べ替えます。

エクスプロイトチェーン(Redis 8.6.2、x86-64、jemalloc、PIE/NX/partial-RELRO)

root@kitploit:~
silent double-free  ->  type-confusion overlap  ->  arbitrary pointer-forge
   ->  hashtable ハッシュの dict->type を偽の dictType に偽造
   ->  HGET hd "<field>"   ==   dictFind -> type->hashFunction(field)
      libc パス  (selfcal): hashFunction = &system            -> system("<cmd>")   (ワーカー存続)
      PIE パス   (pie_rop): hashFunction = JOP-pivot g1、field = ROP チェーン
                            -> leave;ret が rsp を field 上にピボット
                            -> execve("/bin/sh","-c","<cmd>")  via execve@plt        (libc 不要、DEBUG 不要)

偽の dictType は 16 MB の文字列(SETRANGE)内の、アドレスの下位バイトが攻撃者文字列の sds ヘッダーと 一致するオフセットに植え付けられます。ASLR は完全に実行時に破られます:

  • system — 単一のヒープポインターリーク。推奨パスは DEBUG 不要 です: redis.call の Lua C-closure のアドレス(EVAL 'return tostring(redis.call)')— 以前の Redis エクスプロイトと同じ 自己完結型リークです。jemalloc アリーナは libc から一定のオフセットにあるため、 system = leaked_robj + Δlibc + system_off となります。(DEBUG OBJECT は、スクリプト実行が無効なのに DEBUG が有効という稀な構成でラボ用に使えるだけです。)
  • 16 MB blob のアドレス(独立にランダム化された mmap)— バグ自身の任意読み取りで取得: SET の dict を偽造してそのメンバーを 107 KB の SDS_TYPE_32 sds にし、SMEMBERS で隣接ヒープを オーバーリードして、既知のオフセットで blob の robj.ptr を読み取ります。

完全なプリミティブ単位の分析と、苦労して得た jemalloc / Redis-8.x の詳細(class-64 境界、dict エントリの タグ付け、ハッシュフィールド mstr、キースペースの事前 grow)については WRITEUP.md を参照してください。

ラボ

root@kitploit:~
docker build -t cve-2026-25243 .
# 標準(jemalloc)デモ — DoS か否か? 型混乱を示します(ツール不要):
docker run --rm -p 6379:6379 cve-2026-25243

# フルチェーン — DEFAULT 構成(DEBUG 無効)、推奨エクスプロイト:
sysctl -w kernel.randomize_va_space=2            # ASLR ON
redis-server &                                   # DEBUG はデフォルトでオフ
python3 exploits/poc_rce_aslr_selfcal.py --host 127.0.0.1 --port 6379 --cmd "id > /tmp/pwned 2>&1"

ASLR を破るリーク(DEBUG 不要)

ブートストラップのヒープポインターリークは以前の Redis エクスプロイトと同じアプローチです: EVAL 'return tostring(redis.call)' で redis.call の Lua C-closure アドレスをリークします。 Lua スクリプトはデフォルトでオン。DEBUG はデフォルトで オフ(enable-debug-command no)— したがって Lua リークが現実的な主要経路であり、DEBUG OBJECT(poc_rce_aslr.py)はラボでの便宜手段にすぎません。 poc_rce_aslr_selfcal.py はその後、オーバーリードから blob_base と blob_robj を実行時に導出 するため (16 MB blob の robj シグネチャをスキャン)、DLUA/DFOBJ は およそ 合っていれば十分です。

system フィニッシュでは、スモールヒープのオーバーリードに libc ポインターが含まれない ため、libc を 自己導出できません — poc_rce_aslr_selfcal.py は libc バージョン別オフセット 2 つ(DLIBC、SYSTEM_OFF)を 保持します。poc_rce_aslr_pie_rop.py フィニッシュはその依存関係を完全に除去します: 同じオーバーリードには PIE ポインターが確かに含まれ(共有の dictType が繰り返し出現する)、PIE ベースは 最頻-PIE 値 − DICTTYPE_OFF として自己校正され、チェーンは JOP スタックピボット (mov rbp,rdi; call *0x8(rax) → leave;ret が rsp を攻撃者制御の HGET フィールド上にピボットし、それが execve("/bin/sh","-c",<cmd>) ROP チェーンそのもの)を通じて execve@plt で終わります。ビルド固有の定数は redis-server から読み取る PIE 相対ガジェットオフセットだけです — ターゲットごとに / で 抽出してください。これは以前の HLL エクスプロイトが ELF Build-ID ごとにガジェットテーブルをキーとするのと まったく同じです。libc アドレスは一切使用しません。

スクリーンショット

screenshots/05-pie-rop-libc-free.png(NO libc 自己校正 + uid=0、最も自己完結した実行)、 01-rce-aslr-on.png(uid=0 の決定的ショット)、02-reliability.png(5/5)、03-exploit-chain.png(コード)、 04-debug-free-selfcal.png(デフォルト Redis 上での DEBUG 不要・自己校正 system 実行)。

影響と影響を受けるバージョン

  • リモート、特別な権限不要。 RESTORE は通常のコマンドです — 認証なし/露出した Redis (requirepass なし)では、接続済みの任意のクライアントが実行できます。認証ありのインスタンスでは、 ACL の -restore 拒否がない任意のユーザーが実行できます。他の Redis RCE で使われるデータ構造コマンドと 同じアクセスプロファイルです。
  • 確認済み: 無音のヒープ double-free、型混乱、任意のプロセスメモリ読み取り(キー/シークレット/ポインターを 外部に持ち出す情報漏えい)、およびリモートコード実行(このリポジトリ)。
  • 影響: Redis < {6.2.22, 7.2.14, 7.4.9, 8.2.6, 8.4.3, 8.6.3} — すなわち 6.2.x から現在の 8.x まで。 Valkey は DoS/オーバーリードのみ(field_added ガードが double-free を阻止)。

緩和策

修正済みリリースにアップグレードしてください。できない場合: RESTORE を制限し(ACL … -restore)、 Redis を認証なしで露出させず、DEBUG を無効にしてください。


認可されたセキュリティ研究であり、防御側の認知向上のために公開されています。所有していない、または明示的な テスト許可がないシステムに対して実行しないでください。

ツールをダウンロード
ファイルデモ内容
★ exploits/poc_rce_aslr_pie_rop.py最も自己完結型 — デフォルト Redis(DEBUG オフ)で RCE、libc オフセット不要。blob_base/blob_robj/pie_base を自己校正。JOP ピボット経由で execve@plt(ワーカーは置き換え)。8/8。
★ exploits/poc_rce_aslr_selfcal.pyワーカー存続型 — 同じチェーンだが hashFunction=&system(fork する)。libc バージョン別オフセット 2 つ(DLIBC/SYSTEM_OFF)が必要。Lua クロージャリーク、blob_base/blob_robj 自己校正。
exploits/poc_rce_aslr_nodebug.pyDEBUG 不要(Lua リーク)だが、固定オフセット使用(DEBUG 有効で校正済み)
exploits/poc_rce_aslr.pyラボ便利用バリアント: DEBUG OBJECT ブートストラップリーク(DEBUG 有効が必要)
exploits/poc_rce_aslr_off.pyASLR 無効で RCE(校正済みアドレス)
exploits/poc_typeconfusion.pydouble-free → 2 つのキーが 1 つのヒープバッファを共有(ツール不要)
exploits/poc_doublefree.pydouble-free(ASan: sdsfree で heap-use-after-free)
exploits/poc_dos_overread.pyオーバーリードクラッシュ(ASan)
ROPgadget
objdump