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
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
há 7 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):

root@kitploit:~
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.

  1. Compilou-se o plugin a partir do código-fonte (./scripts/build) e carregou-se em um vault de teste novo (Supernote (Unofficial) v2.9.1, ativado via "Trust author and enable plugins").
  2. Definiu-se a configuração do plugin Supernote IP address como 127.0.0.1, deixou-se Sync folder no padrão Supernote sync.
  3. Levantou-se um mock Node de um arquivo do servidor "Browse and Access" do dispositivo em 127.0.0.1:8089, simulando um dispositivo malicioso/comprometido. Sua listagem de diretórios retorna:
    root@kitploit:~
    {"name":"Quick notes.note","size":61,"date":"2026-07-31 00:00:00",
     "uri":"/../../PWNED_BY_DEVICE_SYNC.txt","extension":"note","isDirectory":false}
    
    (name passa pelo filtro de extensão .note; uri carrega a travessia.) Qualquer GET é respondido com 200 e os bytes do arquivo — clientes HTTP reais normalizam .. do caminho da requisição de saída antes de chegar ao fio (RFC 3986), o que é irrelevante aqui, já que o código vulnerável calcula o caminho de escrita a partir da string JSON original, não da URL de requisição normalizada.
  4. Executou-se a ação da paleta de comandos "Supernote (Unofficial): Sync supernote notes now".
  5. Resultado: um novo arquivo, PWNED_BY_DEVICE_SYNC.txt, contendo os bytes do atacante, foi criado um diretório acima da raiz do vault (irmão de testvault/, inteiramente fora do vault). O próprio data.json do plugin registrou o caminho calculado literalmente: "vaultPath": "Supernote sync/../../PWNED_BY_DEVICE_SYNC.txt".

Evidências (capturas genuínas, ~/engagements/supernote-obsidian-plugin/evidence/):

  • 01-vault-escape-file-write.png — terminal real: ls -la testvault/ PWNED_BY_DEVICE_SYNC.txt mostrando o arquivo como irmão do diretório do vault, além de seu conteúdo controlado pelo atacante via cat.
  • 02-plugin-data-json-vaultpath.png — o próprio arquivo de estado de sincronização persistido do plugin registrando "vaultPath": "Supernote sync/../../PWNED_BY_DEVICE_SYNC.txt".
  • 03-plugin-settings-security-claim.png — a UI de configurações do plugin afirmando que o comando de sincronização "never writes anywhere outside this folder."

Impacto

Um atacante que possa responder como o dispositivo Supernote configurado da vítima (adjacente à LAN: AP rogue, ARP spoofing ou reivindicar o IP do dispositivo) pode fazer o cliente Obsidian da vítima criar um novo arquivo controlado pelo atacante em qualquer caminho do sistema de arquivos onde o processo desktop possa gravar — dentro do vault (por exemplo, um arquivo totalmente novo em .obsidian/plugins/<new-id>/, preparando o terreno para abuso adicional de confiança de plugins) ou inteiramente fora dele (por exemplo, ~/.config/autostart/*.desktop, um novo drop-in de crontab, ou qualquer outro local onde um novo arquivo — não uma sobrescrita — seja suficiente para obter execução ou persistência). Não pode sobrescrever silenciosamente um arquivo que já existe no caminho resolvido (o createBinary do Obsidian lança "File already exists" nesse caso, confirmado empiricamente), o que limita o primitivo a plantio de arquivos totalmente novos em vez de sobrescrita universal.

Fraquezas

  • CWE-22: Limitação Imprópria de um Nome de Caminho a um Diretório Restrito ('Path Traversal')
  • CWE-73: Controle Externo de Nome de Arquivo ou Caminho (o uri fornecido pelo dispositivo determina diretamente o destino no disco)

Remediação

Em deviceUriToVaultPath() (src/deviceSync.ts:153-161), rejeitar ou remover segmentos de caminho .. (e vazios/apenas .) após dividir deviceUri, por exemplo:

root@kitploit:~
const segments = deviceUri
    .split('/')
    .filter((s) => s.length > 0 && s !== '.' && s !== '..')
    .map((s) => s.replace(INVALID_FILENAME_CHARS, '_'));

Além disso, scanDeviceSupernoteTree() (src/FileListModal.ts:63) deve validar que o uri de uma entrada de listagem é consistente com seu name (por exemplo, uri termina com o mesmo nome de arquivo), em vez de confiar nos dois campos independentemente — a mesma classe de defesa já implicitamente utilizada em todos os outros lugares do código, que constrói caminhos apenas a partir de name/basename via getAvailablePathForAttachment().

Crédito

Dostxodjayev Abdullox

Canal de Relato

Não há SECURITY.md presente neste repositório. O relato privado de vulnerabilidades do GitHub está confirmado como habilitado para philips/supernote-obsidian-plugin (gh api repos/philips/supernote-obsidian-plugin/private-vulnerability-reporting --jq .enabled → true; 0 avisos de segurança publicados anteriormente). Aplica-se o fluxo padrão do GHSA: https://github.com/philips/supernote-obsidian-plugin/security/advisories/new.

Baixar ferramenta