libarchive 的 RAR v4 过滤器路径(copy_from_lzss_window)中存在可控的堆越界读取 / 内存泄露。本仓库端到端复现了该漏洞:本地 ASan、一个从零编写的 RAR v4 编码器(可调节泄露大小),以及 iOS 18.5 上的真机演示(使用手机自带的系统 libarchive.2.dylib)。
parse_filter() 读取过滤器 blocklength(RAR-VM 字节码,最多 32 位),随后 copy_from_lzss_window() 从 LZSS 窗口 memcpy 该数量的字节,却未检查其是否适合 dictionary_size。窗口大小为 rar_fls(unp_size) << 1 —— 攻击者可同时控制两者。声明 unp_size=16 → 32 字节窗口,设置 blocklength=0x3C000 → 从相邻堆读取约 240 KB 数据到解压输出中。a612bf62(libarchive 3.8.0)添加了 if (blocklength > rar->dictionary_size) return 0;(并在 copy_from_lzss_window 中修复了回绕问题)。3.7.4 —— 版本字符串无法区分二者(参见 writeup §7–8)。完整技术报告见:writeup/cve-2025-5915.en.md(意大利语版:writeup/cve-2025-5915.it.md)。
同一个未检查的 blocklength 是一次 memcpy 的长度,它有两个端点:
在 iOS 18.5 上,写入端上限检查(26256)已向后移植,但读取端防护(5915)尚未移植——因此在 iOS 上这仅是读取问题(analysis/two_cve_unification.md)。
writeup/ full technical article (EN + IT)
poc/
build_bigleak.py shrink unp_size in a real archive + repair header CRC-16
build_encoder.py from-scratch RAR v4 encoder; dials blocklength (leak size)
plant.c macOS realloc interpose to plant a secret after the window
*.rar proof-of-concept archives (see poc/README.md)
RARLeak/ on-device iOS harness (Xcode project)
analysis/ ASan logs, iOS patch-diff (disassembly), notes, isolated guard patch
device-proof/ output of the on-device run (iPhone, iOS 18.5)
git clone https://github.com/libarchive/libarchive && cd libarchive && git checkout v3.7.4
CC=clang CFLAGS="-fsanitize=address -g -O1" LDFLAGS="-fsanitize=address" \
cmake -B build-asan -DENABLE_TEST=OFF . && cmake --build build-asan --target bsdtar
ASAN_OPTIONS=detect_leaks=0 build-asan/bin/bsdtar -xOf poc/enc_0x40000.rar >/dev/null
# -> AddressSanitizer: heap-buffer-overflow READ of size 262112
自行构造:python3 poc/build_encoder.py out.rar <unp_size> <blocklength> [e8e9]。
poc/RARLeak 是一个 iOS 应用:它对自身堆进行堆喷,dlopen 系统 libarchive,喂入精心构造的 RAR,并统计输出中有多少数据来自自身堆。设置签名团队后构建:
cd poc/RARLeak && ./build.sh <device-udid> # set DEVELOPMENT_TEAM first (see build.sh)
预期结果:声明为 16 字节的文件会产生约 196 KB 的输出,其中约 150 KB 是植入的 LK5915!! 标记被越界读出。结果写入应用的 Documents/ 目录。
Apple 的 libarchive.2.dylib(18.5 / 18.6)不包含在内(专有)。仅包含其 SHA-1 值(analysis/SHA1SUMS.ios-dylibs)以及相关的反汇编摘录。可使用 ipsw dyld extract <dyld_shared_cache> libarchive.2.dylib 自行提取。
N-day 漏洞,已在 libarchive 3.8.0 / iOS 18.6 中修复。所有测试均在作者自己的硬件上完成。漏洞由 JJLeo 报告(libarchive issue #2565),研究由 Yifan Zhang(PLL,北京大学)完成,修复由 Tobias Stoeckmann 和 Tim Kientzle 提供。CVE-2024-26256 的修复由 Tobias Stoeckmann 提供。仅限研究与防御性用途。
| 端点 | 缺失的边界检查 | CVE | 修复 |
|---|
| 源(LZSS 窗口) | blocklength ≤ dictionary_size | CVE-2025-5915(读取) | a612bf62, v3.8.0 |
目标(vm->memory,0x40000) | blocklength ≤ VM_MEMORY_SIZE | CVE-2024-26256(写入) | b7b0c7c4, v3.7.5 |