Filipemendonca1978/CVE-2026-21045_and_CVE-2026-21048
GitHub: Filipemendonca1978/CVE-2026-21045_and_CVE-2026-21048
该仓库提供三星 libimagecodec.quram.so 越界写入漏洞的概念验证脚本,用于演示和复现 TIFF/DNG 图像解析中的整数溢出绕过问题。
Stars: 1 | Forks: 0
# CVE-2026-21045 & CVE-2026-21048 — Samsung libimagecodec.quram.so OOB 写入 PoC
## 概述
本仓库包含概念性的概念验证 (PoC) 文件,用于演示三星 Android 设备所使用的 **Quramsoft 图像编解码库** (`libimagecodec.quram.so`) 中的越界 (OOB) 写入漏洞。
| CVE | 格式 | 类型 | 严重程度 | CVSS 4.0 | 修复版本 |
|-----|--------|------|----------|----------|------------|
| CVE-2026-21045 | TIFF | 越界写入 (CWE-787) | 严重 | 8.4 | SMR 2026年7月 发布版 1 |
| CVE-2026-21048 | DNG | 越界写入 (CWE-787) | 高 | — | SMR 2026年7月 发布版 1 |
## 受影响设备
- 运行 Android 14、15、16 的三星 Galaxy 设备
- 具体包括:Galaxy Z Fold 7、Flip 7、S 系列、A 系列(例如 A17)
- 安全补丁级别**早于 SMR 2026年7月 发布版 1** 的设备
- 库文件:`/system/lib64/libimagecodec.quram.so`
## 漏洞机制
### 根本原因
该漏洞存在于 **IFD (Image File Directory) 标签解析** 函数 `WINKJ_ReadExifField`(在 64 位二进制文件中的偏移量为 `0x13a0a8`)中。此函数处理单个的 TIFF/EXIF IFD 条目,每个条目均为 12 字节的结构体:
```
Offset Size Field
------ ---- -----
0 2 Tag ID
2 2 Data Type (1=BYTE, 2=ASCII, 3=SHORT, 4=LONG, 5=RATIONAL, etc.)
4 4 Count (number of values)
8 4 Value / Offset to data
```
当 `count * element_size > 4` 时,4 字节的 Value 字段会被视为**文件偏移量**(指向实际数据的存储位置)。随后,代码会在地址 `0x13a258` 处执行边界检查:
```
add w8, w6, w7 ; w8 = value_offset + (count * element_size) [32-bit]
cmp w8, w5 ; compare against remaining buffer size
b.ls ok ; if w8 <= buffer_size, proceed
```
### 整数溢出绕过
该漏洞是加法运算中的一个 **32 位无符号整数溢出**。
如果攻击者精心构造 `value_offset` 和 `count * element_size`,使得它们的总和回绕(wrap around)为一个极小的值,那么即使在 `base + value_offset` 处的实际内存访问已经越界的情况下,该检查也会顺利通过。
**示例(UNDEFINED 类型,element_size = 1):**
| 字段 | 值 (十六进制) | 十进制 |
|-------|-------------|---------|
| `count` | `0xFFFF0001` | 4,294,901,761 |
| `element_size` | 1 | 1 |
| `count * element_size` | `0xFFFF0001` ≡ `-65535` (mod 2³²) | 4,294,901,761 |
| `value_offset` | `0x00017FFF` | 98,303 |
| `value_offset + count*size` | **`0x00008000`** (溢出!) | 32,768 |
| `buffer_size` | `0x00008000` | 32,768 |
| 检查结果:`0x8000 <= 0x8000` | ✅ **通过** | — |
| 实际内存访问:`base + 0x17FFF` | 超出缓冲区 0x7FFF 字节 | **❌ OOB** |
32 位加法运算 `0x17FFF + 0xFFFF0001 = 0x10008000` 会被截断为 `0x8000`,恰好等于 `buffer_size`。虽然检查通过,但实际的数据指针 (`base + 0x17FFF`) 却位于已分配缓冲区末尾之后的 0x7FFF 字节处。
### 漏洞代码路径
```
TIFFReadDirectory / WINKJ_ReadTiffInfo
└─> WINKJ_ReadTiffIFDInfo (allocates IFD buffer)
└─> for each IFD entry:
└─> WINKJ_ReadExifField (parses entry, reads value data)
└─> Switch on Data Type (jump table at 0x13a15c)
├─ Type 0 (BYTE/ASCII/UNDEFINED): handler at 0x13a15c
├─ Type 3/8 (SHORT/SSHORT): handler at 0x13a1d0
├─ Type 4/9/11 (LONG/SLONG/FLOAT): handler at 0x13a17c
└─ Type 5/10/12 (RATIONAL/SRATIONAL/DOUBLE): handler at 0x13a1ac
Each handler -> reads data at offset -> bounds check at 0x13a258
```
## PoC 文件
| 文件 | 描述 |
|------|-------------|
| `cve-2026-21045_tiff_oob_poc.py` | 生成 `poc_crash.tif` — 畸形的 TIFF 文件,通过带有恶意构造 count/offset 的 ASCII 标签触发 OOB 写入 |
| `cve-2026-21048_dng_oob_poc.py` | 生成 `poc_crash.dng` — 畸形的 DNG 文件,通过带有恶意构造 count/offset 的 UNDEFINED 标签触发 OOB 写入 |
### 用法
```
# 生成 TIFF PoC
python3 cve-2026-21045_tiff_oob_poc.py -o payload.tif
# 生成 DNG PoC
python3 cve-2026-21048_dng_oob_poc.py -o payload.dng
# 传输到设备并触发(例如,通过 Gallery/MMS)
adb push payload.tif /sdcard/Download/
adb shell am start -a android.intent.action.VIEW -d file:///sdcard/Download/payload.tif -t image/tiff
```
### 预期行为
在**未修补的设备**(安全补丁早于 2026 年 7 月)上,在 Samsung Gallery(或任何使用 Quram 解码器的应用)中打开精心构造的 TIFF/DNG 文件应该会导致**堆内存损坏**,这可能引发:
- 应用程序崩溃 (SIGSEGV/SIGABRT)
- 越界堆写入
- 在特定的堆布局下:潜在的**任意代码执行**
在**已修补的设备**(SMR 2026年7月及以上版本)上,该图像要么应作为无效文件被拒绝,要么应被安全地处理。如果在已完全修补的设备上发生崩溃,可能表明存在另一个未修补的问题。
## 二进制分析详情
### 库信息
```
File: libimagecodec.quram.so (64-bit)
SHA256: (verify against your copy)
NDK: r23c (Android 21)
Built: 2021-12-31 (placeholder date)
Soname: libimagecodec.quram.so
```
### 关键函数
| 函数 | 地址 (64 位) | 大小 | 用途 |
|----------|-----------------|------|---------|
| `WINKJ_ReadExifField` | `0x13a0a8` | 912 | 解析单个 IFD 条目(存在漏洞) |
| `WINKJ_ReadTiffIFDInfo` | `0x139d28` | 896 | 读取所有 IFD 条目 |
| `WINKJ_ReadTiffInfo` | `0x139ad4` | 596 | 高层级 TIFF 信息解析器 |
| `WINKJ_GetTiffInfo` | `0x1393fc` | 1752 | 主 TIFF 解析入口点 |
| `decodeTIFF` | `0x1a2adc` | 580 | 通过 libtiff 解码 TIFF 图像 |
| `getTIFFImageInfo` | `0x1a2d20` | 508 | 获取 TIFF 图像元数据 |
| `copySubImageBuffer` | `0x0b2824` | 324 | 拷贝子图像区域 |
| `TIFFReadDirectory` | `0x1aac78` | 5896 | libtiff 4.6.0 目录读取器 |
| `_TIFFMultiply32` | `0x1a2f1c` | 56 | 安全的 32 位乘法检查 |
| `_TIFFMultiply64` | `0x1a2f58` | 48 | 安全的 64 位乘法检查 |
### 分发表 (标签类型 → 处理器)
从 `WINKJ_ReadExifField` 中提取:
| 类型 | 名称 | 元素大小 | 处理器地址 |
|------|------|-------------|-----------------|
| 1 | BYTE | 1 | `0x13a15c` |
| 2 | ASCII | 1 | `0x13a15c` |
| 3 | SHORT | 2 | `0x13a1d0` |
| 4 | LONG | 4 | `0x13a17c` |
| 5 | RATIONAL | 8 | `0x13a1ac` |
| 6 | SBYTE | 1 | `0x13a15c` |
| 7 | UNDEFINED | 1 | `0x13a15c` |
| 8 | SSHORT | 2 | `0x13a1d0` |
| 9 | SLONG | 4 | `0x13a17c` |
| 10 | SRATIONAL | 8 | `0x13a1ac` |
| 11 | FLOAT | 4 | `0x13a17c` |
| 12 | DOUBLE | 8 | `0x13a1ac` |
所有 `element_size = 1` 的类型(BYTE、ASCII、UNDEFINED)均共享同一个处理器,并且同样容易受到整数溢出绕过的攻击。
## 相关 CVE
| CVE | 描述 | 状态 |
|-----|-------------|--------|
| CVE-2025-58477 | `libimagecodec.quram.so` 中 IFD 标签解析的 OOB 写入 (SMR 2025年12月) | ✅ 已修补 |
| CVE-2026-20973 | `libimagecodec.quram.so` 中的 OOB 读取 (SMR 2026年1月) | ✅ 已修补 |
| CVE-2026-21045 | `libimagecodec.media.quram.so` 中 TIFF 解析的 OOB 写入 (SMR 2026年7月) | ⚠️ **对我而言未修补** |
| CVE-2026-21048 | `libimagecodec.media.quram.so` 中 DNG 解析的 OOB 写入 (SMR 2026年7月) | ⚠️ **对我而言未修补** |
| CVE-2026-4775 | libtiff 4.6.0 `putcontig8bitYCbCr44tile` 中的有符号整数溢出 | ⚠️ **对我而言未修补** |
| CVE-2024-7006 | libtiff `tif_dirinfo.c` 中的 NULL 解引用 | ✅ 在 4.6.1 中已修复 |
## 免责声明
提供这些概念验证仅供**教育和安全研究目的**。它们用于演示漏洞机制,以帮助用户和开发人员了解相关风险。请勿将其用于您不拥有或未获得明确测试授权的系统。
## 参考
- https://nvd.nist.gov/vuln/detail/CVE-2026-21045
- https://nvd.nist.gov/vuln/detail/CVE-2026-21048
- https://security.samsungmobile.com/securityUpdate.smsb
- https://gitlab.com/libtiff/libtiff/-/releases/v4.6.0
标签:安全漏洞, 整数溢出, 漏洞验证程序, 目录枚举, 移动安全, 逆向工具