首页 网络安全 正文

NanaZip元数据读取堆缓冲区溢出CVE-2026-47224

摘要

栋科技漏洞库关注到在NanaZip LVM 元数据 CRC 检查中存在的读取堆缓冲区溢出漏洞,追踪为CVE-2026-47224,CVSS 3.X评分7.3。

NanaZip 是一款开源免费、基于 7-Zip 二次开发的衍生压缩工具,专为Windows 10/11现代系统优化,界面现代化、贴合系统原生风格。

一、基本情况

NanaZip是一款基于 7-Zip 改造的免费开源压缩软件,专门适配 Win10、Win11,右键菜单调用更方便,并且支持更多新式压缩格式。

NanaZip元数据读取堆缓冲区溢出CVE-2026-47224

NanaZip 完整沿用 7-Zip 内核,无广告捆绑,采用 MSIX 封装,安装卸载干净无残留,是 Windows 新版系统下 7-Zip 的优质替代工具。

栋科技漏洞库关注到在NanaZip LVM 元数据 CRC 检查中存在的读取堆缓冲区溢出漏洞,追踪为CVE-2026-47224,CVSS 3.X评分7.3。

二、漏洞分析

CVE-2026-47224是NanaZip LVM元数据CRC校验模块中的堆缓冲区越界读取漏洞,影响版本 3.0.1000.0 版至 6.0.1698.0 版(不含)。

该漏洞是 LVM2 物理卷元数据解析器(源自上游 7-Zip 的 LvmHandler 模块)中的漏洞,打开特制 LVM 磁盘镜像文件即可触发该漏洞。

该漏洞源于7-Zip部分源代码存在缺陷,NanaZip专门启用了对应代码模块。

(一)受测版本

V6.0.16.50

(二)漏洞详情

当元数据区域长度字段取值在1至511字节区间时,处理器会按该长度分配缓冲区,但仍强制读取508字节数据执行CRC-32校验,

造成最多越界读取507个已分配缓冲区之外的字节。

LvmHandler.cpp文件的CHandler::Open2函数从物理卷头部读取元数据磁盘位置信息,长度字段为从恶意镜像中解析得到的64位数值。

程序严格按照该数值大小分配缓冲区,并从数据流中读取等量数据写入缓冲区后,

仍采用固定长度kSectorSize - 4(即508字节)计算CRC-32校验值:

// LvmHandler.cpp — CHandler::Open2()

CByteBuffer meta;
const size_t sizeT = (size_t)size;
if (sizeT != size)
    return S_FALSE;
meta.Alloc(sizeT);                                       // allocates sizeT bytes
RINOK(InStream_SeekSet(stream, offset))
RINOK(ReadStream_FALSE(stream, meta, sizeT))              // fills sizeT bytes

// CRC check reads a FIXED 508 bytes regardless of sizeT:
if (Get32(meta) != LvmCrcCalc(meta + 4, kSectorSize - 4)) // ← reads meta[4..511]
    return S_FALSE;

源码路径:NanaZip.Core/SevenZip/CPP/7zip/Archive/LvmHandler.cpp,第754至761行

当1 ≤ sizeT < 512时,元数据缓冲区仅存有sizeT字节数据,

但调用LvmCrcCalc(meta + 4, 508)会读取meta[4]至meta[511]区间的数据,最多会超出堆内存分配边界读取511 - sizeT字节。

同理,Get32(meta)会从缓冲区起始位置读取4字节数据,若sizeT < 4,同样会发生缓冲区越界读取。

(三)越界长度范围

NanaZip元数据读取堆缓冲区溢出CVE-2026-47224

sizeT取值为1时,最大越界读取字节数可达511字节。

(四)根本成因

CRC校验逻辑硬编码采用kSectorSize - 4(508字节)作为校验长度,

该写法适配磁盘上LVM元数据头部规范,即CRC校验范围为首扇区剩余全部数据。

但代码默认缓冲区长度至少为512字节,却未对该前提做任何校验;长度字段由攻击者可控,可被任意篡改。

(四)路径约束条件

元数据磁盘位置结构需通过下述校验逻辑,方能执行存在漏洞的CRC调用:

1、offset != 0 || size != 0:磁盘位置标识不能为全零终止符;

2、(size_t)size == size:64位长度值可无损转为size_t类型(64位系统下恒成立)。

代码未设置最小长度校验规则。

(五)漏洞影响

1、LVM处理器绑定.lvm后缀文件,格式标识为0xBF,扇区偏移512字节处存在LABELONE特征签名;

2、NanaZip的MSIX清单配置了通配符文件关联(<uap10:FileType>*</uap10:FileType>),打开任意文件时都会自动执行格式识别;

3、漏洞在IInArchive::Open()接口执行阶段触发,用户仅需打开恶意文件,无需额外操作;

4、物理卷全部标签字段(魔数、CRC值、结构常量)必须合法,代码才会走到漏洞分支;

该CRC为标准CRC-32/IEEE算法,自定义初始值为0xf597a6cf,攻击者构造镜像时可轻易算出合法校验值。

(1)信息泄露

越界读取会访问元数据缓冲区相邻堆内存。

读取数据仅用于CRC比对,不会直接回传给攻击者,但归档能否正常打开可作为侧信道观测CRC校验结果,存在堆内存部分内容泄露。

(2)拒绝服务

常规场景下,越界读取大概率命中相邻堆填充内存,不会触发异常;

但若内存分配紧邻页边界,会触发访问违例(ACCESS_VIOLATION)程序崩溃。

(3)堆布局操纵下的扩展风险

若相邻堆内存存有密钥、令牌、用户隐私数据等敏感内容,

理论上可借助CRC预言机逐字节探测数据,但该攻击需要多次交互并精准控制堆内存布局。

(4)受影响版本

自3.0.1000.0版本(2024-05-27)起生效,该版本是首个内置LVM解析模块的正式发行版。

(六)与空指针引用漏洞的关联说明

本漏洞和另一起因超大内存分配未校验引发的空指针解引用漏洞,代码缺陷触发位置一致;

两个问题根源均为未对元数据磁盘位置结构的size字段做边界合法性校验。

NanaZip元数据读取堆缓冲区溢出CVE-2026-47224

(七)7-Zip 不受该漏洞影响的原因

LvmHandler.cpp 属于上游7-Zip源码(与7-Zip 26.00内置版本完全一致),

Pavlov's源码树中确实存在该漏洞代码,但7-Zip在编译发布版7z.dll时主动剔除了该解析模块:

1、在CPP/7zip/Bundles/Format7zF/Arc_gcc.mak编译脚本中,LvmHandler.o目标文件被注释禁用;

2、在MSVC编译所用Arc.mak文件里,AR_OBJS对象列表未纳入LvmHandler模块。

NanaZip则在NanaZip.Core.vcxproj工程文件中引入了LvmHandler.cpp启用该解析器,

编译时通过REGISTER_ARC_I宏自动加载激活此模块。

(八)修复方案

方案一:因该解析器尚未成熟,直接禁用此解压处理模块。

方案二:执行CRC校验前,强制校验元数据缓冲区最小长度不得小于扇区尺寸常量kSectorSize(512字节)。

if (sizeT < kSectorSize)
    return S_FALSE;

三、POC概念验证

1、漏洞触发方法:

为对应可执行程序开启完整页堆校验,随后运行漏洞验证代码(PoC)并查看程序退出码:

管理员已设置登录后刷新可查看



扫描二维码,在手机上阅读
评论
更换验证码
友情链接