Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
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
supernote-obsidian-plugin-PoC — PoC — path traversal via sincronização maliciosa de dispositivo no plugin Supernote Obsidian (GHSA-3gx3-r874-5pp4, CVE-2026-86999, CVSS 5.6). | Kitploit
Ferramentas/GitHubGitHub/squeeze440/supernote-obsidian-plugin-poc
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebVirtualização para SegurançaTestes de PenetraçãoPapers e Pesquisa
GitHubsqueeze440/supernote-obsidian-plugin-poc

supernote-obsidian-plugin-PoC

PoC — path traversal via sincronização maliciosa de dispositivo no plugin Supernote Obsidian (GHSA-3gx3-r874-5pp4, CVE-2026-86999, CVSS 5.6).

Ver Repositório
16há 19 diasAinda 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

Resumo

Status da CVE: solicitada, aguardando atribuição. Esta descoberta é publicada como GHSA-3gx3-r874-5pp4. Após a atribuição da CVE, este repositório é renomeado CVE-YYYY-NNNNN-supernote-obsidian-plugin-PoC e este banner é substituído pelo link da CVE.

PesquisadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-3gx3-r874-5pp4
CVSS 3.15.6 (Médio)
FraquezaCWE-22, CWE-73

Resumo

Path Traversal na funcionalidade de sincronização automática do dispositivo do plugin Supernote (Unofficial) para Obsidian (philips/supernote-obsidian-plugin) v2.9.1 permite que um dispositivo "Supernote" malicioso ou comprometido (ou um atacante no caminho/na LAN que se passe pelo IP do dispositivo emparelhado) faça o cliente Obsidian da vítima gravar um novo arquivo arbitrário em qualquer local onde o processo desktop possa gravar — incluindo fora da pasta de sincronização configurada e fora do próprio vault — através de um campo uri manipulado na resposta de listagem de diretórios do dispositivo.

Produto

philips/supernote-obsidian-plugin ("Supernote (Unofficial)"), um plugin da comunidade Obsidian.md que sincroniza as notas de um dispositivo físico Supernote e-ink para um vault através do servidor HTTP local "Browse and Access" do dispositivo (http://<device-ip>:8089, sem autenticação, por design da funcionalidade do dispositivo).

Versão Testada

  • Plugin: v2.9.1, commit 48db5bf4dcfb100632c84699c830c1309da1abb9
  • Submódulo supernote-typescript: commit 195415b3a1f74147... (não implicado em si — o bug está inteiramente no código de planejamento de sincronização do próprio plugin)
  • Aplicação hospedeira: Obsidian desktop 1.13.4 (binário real, testado dinamicamente)

CVSS v3.1 Estimado

5.6 Médio — CVSS:3.1/AV:A/AC:H/PR:N/UI:R/S:C/C:N/I:H/A:N

  • AV:A — o servidor HTTP do dispositivo é em texto simples, não autenticado e configurado por um endereço IPv4 simples (IP_VALIDATION_PATTERN, src/settings.ts:6); alcançá-lo como "o dispositivo" requer posição de rede adjacente à LAN (AP rogue, ARP spoofing ou reivindicar o IP), não acesso remoto arbitrário.
  • AC:H — a exploração depende de o atacante já ocupar essa posição de rede quando o plugin da vítima se comunica com directConnectIP:8089; não é um gatilho remoto de disparo único.
  • UI:R — requer que a vítima execute "Sync supernote notes now" (ou tenha o toggle de sincronização automática já ativado) enquanto aponta para o endpoint controlado pelo atacante.
  • S:C — o componente vulnerável é um plugin do Obsidian com escopo de vault; a gravação ocorre inteiramente fora do vault, no sistema de arquivos do host subjacente, que é um escopo de segurança diferente.
  • C:N — este é um primitivo somente de escrita; nada é lido de volta pelo atacante.
  • I:H — bytes controlados pelo atacante chegam a um caminho escolhido pelo atacante com nome de arquivo escolhido pelo atacante. Ressalva limitada: writeBinaryAt() (src/syncEngine.ts:40-47) só toma o ramo de criação para caminhos ainda não rastreados no próprio manifesto de sincronização do plugin, e o Vault.createBinary() do Obsidian se recusa a sobrescrever silenciosamente um arquivo que já existe fisicamente no caminho resolvido (confirmado empiricamente — ver PoC) — portanto isto é "plantar um novo arquivo em qualquer lugar", não "sobrescrever qualquer arquivo existente".
  • A:N — nenhum impacto de disponibilidade demonstrado.

Detalhes

runDeviceSync() (src/syncEngine.ts:100-196) lista os arquivos do dispositivo emparelhado via scanDeviceSupernoteTree() (src/FileListModal.ts:53-68), que percorre recursivamente a listagem de diretórios HTTP do próprio dispositivo e mantém qualquer entrada cujo name corresponda a /\.(note|spd)$/i (src/FileListModal.ts:46,63). O campo uri de cada entrada — uma string separada e controlada independentemente no mesmo objeto JSON retornado pelo dispositivo — nunca é validado em relação ao name ou a qualquer outra coisa.

Esse uri bruto é então alimentado diretamente em deviceUriToVaultPath() (src/deviceSync.ts:153-161):

const INVALID_FILENAME_CHARS = /[\\:*?"<>|]/g;   // deviceSync.ts:144

export function deviceUriToVaultPath(syncFolder: string, deviceUri: string): string {
    const segments = deviceUri
        .split('/')
        .filter((s) => s.length > 0)
        .map((s) => s.replace(INVALID_FILENAME_CHARS, '_'));

    const cleanRoot = syncFolder.replace(/^\/+|\/+$/g, '');
    return cleanRoot ? `${cleanRoot}/${segments.join('/')}` : segments.join('/');
}

INVALID_FILENAME_CHARS remove \ : * ? " < > | mas nunca remove ou rejeita segmentos de caminho ... Um uri de dispositivo /../../PWNED.txt sobrevive intacto e é concatenado à pasta de sincronização configurada (padrão "Supernote sync") para produzir vaultPath = "Supernote sync/../../PWNED.txt".

syncEngine.ts:128 calcula esse vaultPath a partir do uri bruto da listagem, então ensureFolder()/writeBinaryAt() (syncEngine.ts:146-148, 21-47) o passam diretamente para app.vault.getAbstractFileByPath() / createBinary() / modifyBinary() sem qualquer verificação de travessia. A própria resolução de caminho do Obsidian então normaliza os segmentos .. em relação ao diretório real do vault no disco, fazendo a gravação cair acima da pasta de sincronização — e, com segmentos ../ suficientes, acima da raiz do vault inteiramente, no sistema de arquivos do host, no escopo de permissão do próprio usuário do SO.

Verificação de irmãos: todos os outros pontos de gravação no vault neste código (src/main.ts — captura de espelhamento de tela, importação de PDF/markdown, "attach to note", DownloadListModal em src/FileListModal.ts:245-246) constroem seu caminho de destino via o próprio app.fileManager.getAvailablePathForAttachment(file.name) do Obsidian, que só consome o campo name do dispositivo e não é explorável dessa forma. deviceUriToVaultPath() na funcionalidade mais recente de sincronização automática é o único ponto que, em vez disso, monta manualmente um caminho a partir do campo uri do dispositivo, e é o que pulou a sanitização de .. — um caso claro de "verificado em todos os irmãos, exceto neste."

A própria UI de configurações do plugin afirma: "The sync command never writes anywhere outside this folder" (src/settings.ts, descrição da pasta de sincronização) — este PoC falsifica diretamente essa garantia.

Prova de Conceito

Confirmado dinamicamente de ponta a ponta contra um binário real e não modificado do Obsidian 1.13.4 desktop (Xvfb + fluxbox + xdotool + scrot), executando o main.js compilado real do plugin — sem simulação do código do plugin.

Baixar ferramenta