NanaZip 的 UFS 处理程序中存在无界内存分配漏洞,通过攻击者可控的 fs_bsize 字段触发。
| 字段 | 值 |
|---|---|
| CVE | CVE-2026-55781 |
| 安全公告 | GHSA-m34h-jf84-m74h |
| 厂商 | M2Team / NanaZip |
| 受影响版本 | NanaZip <= 6.5 Preview (6.5.1742.0) |
| 修复版本 | 6.5.1749.0 |
| 漏洞类别 | 拒绝服务 (CWE-789: 使用过大尺寸值进行内存分配) |
| 平台 | Windows |
| 作者 | g17hubH4ck |
| 披露日期 | 2026-07-17 |
NanaZip.Codecs.Archive.Ufs.cpp 读取 UFS 超级块,并仅对 fs_bsize 进行下界校验(MINBSIZE)。在该值被用于确定分配大小之前,未强制实施上界检查。
当根 inode(#2)声明的 di_size 大到需要间接块时,解析器会使用 fs_bsize 为每个间接层级分配一个缓冲区。设置 fs_bsize = 0x40000000(1 GiB)和 di_size = 0x10000000000(1 TiB)会强制进行三次 1 GiB 的分配(Ufs.cpp:435-437)——大约 3 GiB 的连续内存——且在任何边界检查运行之前。
结果:内存耗尽和进程终止。无代码执行。
关键超级块字段(偏移量基于 FreeBSD fs.h 中的 offsetof(struct fs, ...)):
根 inode 地址:GetInodeOffset(2) = fs_iblkno * fs_fsize + 2 * 256 = 512。
python3 poc.py poc.img
该脚本写入畸形镜像并重新解析它,以确认每个字段都落在易受攻击的解析器所期望的位置。无网络访问、无子进程、无武器化载荷——仅载体文件本身是无害的。
验证
生成的镜像可以在没有 NanaZip 的情况下进行检查:
xxd -s 65536 -l 64 poc.img # 超级块头部
xxd -s 512 -l 32 poc.img # 根 inode 头部
要观察崩溃,请在 Windows 上使用易受攻击的版本打开 poc.img。6.5.1749.0 及更高版本能正确处理该输入。
注意:此 PoC 是通过对 NanaZip.Codecs 解析器的静态分析构建的。它到达了安全公告中记录的精确易受攻击行,但未针对运行中的 NanaZip 构建执行。
缓解措施
· 升级到 NanaZip >= 6.5.1749.0。 · 如果无法升级,请避免打开来自不受信任来源的 UFS 镜像。
参考资料
· NanaZip: https://github.com/M2Team/NanaZip · 安全公告: GHSA-m34h-jf84-m74h · CWE-789: https://cwe.mitre.org/data/definitions/789.html
免责声明
本材料仅供防御性研究和在受控环境中复现漏洞使用。请勿将其用于您不拥有或未经明确许可测试的系统。
| 区域 | 偏移 | 备注 |
|---|
根 inode #2 | 512 | ufs2_dinode,256 字节,di_mode = IFDIR,di_size = 1 TiB |
| UFS2 超级块 | 65536 (SBLOCK_UFS2) | struct fs,小端序,fs_bsize = 0x40000000 |
| 总大小 | 66912 字节 | SBLOCK_UFS2 + sizeof(struct fs) |
| 偏移 | 字段 | 值 |
|---|
+16 | fs_iblkno | 0 |
+44 | fs_ncg | 1 |
+48 | fs_bsize | 0x40000000 ← 恶意值 |
+52 | fs_fsize | 1 |
+56 | fs_frag | 1 |
+104 | fs_sbsize | 1376 |
+1000 | fs_sblockloc | 65536 |
+1372 | fs_magic | 0x19540119 (FS_UFS2_MAGIC) |