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
zotlit-PoC — PoC — a importação de anexos copia arquivos de caminhos locais não aprovados no ZotLit (GHSA-4qh7-66xv-h329, CVE-2026-87000, CVSS 5.5). | Kitploit
Ferramentas/GitHubGitHub/squeeze440/zotlit-poc
Análise de VulnerabilidadesExploraçãoExfiltração de DadosColeta de InformaçõesVirtualização para SegurançaPapers e Pesquisa
GitHubsqueeze440/zotlit-poc

zotlit-PoC

PoC — a importação de anexos copia arquivos de caminhos locais não aprovados no ZotLit (GHSA-4qh7-66xv-h329, CVE-2026-87000, CVSS 5.5).

Ver Repositório
20há 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

ZotLit: aviso de segurança

Status da CVE: solicitada, aguardando atribuição. Esta descoberta é publicada como GHSA-4qh7-66xv-h329. Após a atribuição da CVE, este repositório é renomeado CVE-YYYY-NNNNN-zotlit-PoC e este banner é substituído pelo link da CVE.

PesquisadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-4qh7-66xv-h329
CVSS 3.15.5 (Médio)
FraquezaCWE-73, CWE-200

Resumo

O Controle Externo de Nome de Arquivo ou Caminho no recurso de importação de anexos do AidenLx ZotLit (aidenlx/zotlit) 1.1.12 permite que um atacante que controla uma biblioteca Zotero compartilhada/sincronizada divulgue arquivos locais arbitrários do sistema de arquivos da vítima para o cofre Obsidian da vítima por meio de um caminho de anexo linked_file manipulado.

Produto

ZotLit — plugin do Obsidian para integração com o Zotero (aidenlx/zotlit, id do plugin zotlit, versão do manifesto 1.1.12)

Versão Testada

Commit do Git 41e60aaa6178629b34f8a42d104e757594b72435 (2026-07-31)

CVSS v3.1 Estimado

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N — 5.5 (Médio)

Métricas não óbvias: AV:L — a exploração ocorre quando o processo local do Obsidian/zotlit da vítima processa metadados de itens do Zotero fornecidos pelo atacante (entregues por meio de uma biblioteca compartilhada/sincronizada), a mesma convenção usada para bugs de "arquivo malicioso processado por aplicativo local", embora a entrega em si possa ocorrer pela rede (biblioteca de grupo compartilhada, arquivo de exportação enviado por e-mail). UI:R — a vítima deve importar/sincronizar a biblioteca maliciosa no Zotero e executar o recurso de importação de notas do ZotLit (ou de incorporação de anotações/citações) em uma nota que faça referência ao anexo manipulado; isso é uso rotineiro da funcionalidade central do plugin, habilitada por padrão (attachment.import tem valor padrão true), não uma ação incomum. I:N/A:N — esta descoberta é apenas uma primitiva de leitura/cópia; nenhum path traversal no lado do destino é alegado (consulte Detalhes para uma observação relacionada, mas não verificada).

Detalhes

O ZotLit lê metadados de anexos diretamente do banco de dados SQLite do Zotero (ou de uma biblioteca sincronizada/compartilhada), incluindo a coluna de texto livre itemAttachments.path, e confia nela completamente ao resolver de onde ler um anexo "vinculado":

  • packages/db/src/lib/zt-path.ts:62-63 — attachmentAbsPath(), caso "linked-absolute":

    case "linked-absolute":
      return parsed.path;
    

    Para linhas com linkMode: 2 (linked_file) cujo path não carrega o placeholder de diretório base attachments:, parsed.path é a string bruta do banco de dados retornada literalmente como o caminho absoluto do sistema de arquivos a ser lido — sem allowlist, sem confinamento ao diretório de dados do Zotero ou a qualquer local aprovado pelo usuário.

  • packages/db/src/lib/context/zt-template-attach.ts:101-106 — attachmentFilename(), caso "linked-absolute":

    case "linked-absolute":
      return basename(path.path);
    

    O nome de arquivo usado para construir a cópia no cofre é derivado desse mesmo caminho controlado pelo atacante por meio de basename(), portanto o nome de arquivo de destino é influenciado pelo atacante, mas livre de separadores de caminho (seguro contra traversal neste ramo).

  • apps/obsidian/src/services/note-import/note-parser.ts:403-430 — resolveEmbeddedImage() é invocado durante a conversão de uma anotação de imagem incorporada de uma nota de literatura do Zotero em Markdown do Obsidian (uma ação rotineira e padrão do recurso "Import Note" do ZotLit). Ele resolve sourcePath = attachmentAbsPath(attachment, ...) e chama deps.resolveLink({ sourcePath, vaultName: \${attachment.key}-${filename}` })` — enfileirando uma cópia de qualquer caminho absoluto escolhido pelo atacante para dentro do cofre.

  • apps/obsidian/src/services/attachment-import/service.ts:125-155 — AttachmentImportBatch.resolveLink() enfileira { source: sourcePath, dest: <vault attachment folder>/<key>-<filename> }, condicionado apenas à configuração attachment.import, cujo padrão é true (apps/obsidian/src/services/settings/schema.ts:123).

  • apps/obsidian/src/lib/copy-attachments.ts:43-60 — copyAttachment() executa a leitura+escrita real sem nenhuma validação de caminho: stat(source) e depois copyFile(source, dest).

Efeito líquido: um atacante que consiga inserir um item do Zotero linked_file (linkMode 2) na biblioteca da vítima — por exemplo, uma biblioteca de grupo compartilhada do Zotero, uma exportação .rdf/.json/Better BibTeX que a vítima importa, ou uma biblioteca sincronizada na qual o atacante tem acesso de escrita — pode definir o caminho de anexo desse item para qualquer arquivo no disco da vítima (~/.ssh/id_rsa, armazenamentos de credenciais do navegador, outros cofres, arquivos .env, etc.). No momento em que a vítima executa a importação de notas do ZotLit (ou renderiza/incorpora essa anotação) com a configuração padrão attachment.import: true, o ZotLit copia silenciosamente o conteúdo desse arquivo para o cofre Obsidian da vítima sob um nome previsível (<attachmentKey>-<basename>). Como os cofres são rotineiramente sincronizados, commitados no git ou publicados, isso move dados que o atacante jamais conseguiria alcançar de outra forma para um local que o atacante (ou qualquer outra pessoa com acesso ao destino de sincronização) pode ler.

Observação relacionada, não verificada (não faz parte do PoC desta descoberta): o ramo irmão "storage" de attachmentFilename() (zt-template-attach.ts:103-104) retorna o sufixo bruto do caminho sem a chamada basename() aplicada aos outros dois ramos. Se isso é explorável de forma independente depende de como o próprio mecanismo de sincronização de armazenamento do Zotero nomeia os arquivos baixados localmente, o que está fora deste repositório e não foi verificado — sinalizado aqui apenas como uma lacuna de hardening que vale a pena fechar por consistência.

Prova de Conceito

Verificação dinâmica: as funções vulneráveis exatas (parseAttachmentPath, attachmentAbsPath, attachmentFilename, copyAttachments/copyAttachment/writeCopy/destMatches, isErrno, reflink) foram extraídas literalmente (com arquivo:linha citados acima, lógica inalterada) do código-fonte distribuído e executadas diretamente no Node, porque uma instalação completa offline do workspace pnpm não estava disponível neste sandbox (toolchain corepack/pnpm quebrado offline). A única substituição foi trocar a chamada do logger LogTape por console.warn — apenas cosmético, efeito zero no fluxo de controle. Script: ~/engagements/zotlit/evidence/poc-verify.mjs.

Passos:

  1. Segredo simulado da vítima em ~/engagements/zotlit/evidence/victim-disk/id_rsa (conteúdo fictício, claramente marcado como simulado).
  2. Linha de anexo do Zotero controlada pelo atacante e manipulada: { key: "EVILKEY1", path: "<path to victim's id_rsa>", linkMode: 2 } — exatamente o formato que getAttachmentByKey retorna do banco de dados do Zotero.
  3. Executou a attachmentAbsPath() real — resolveu a origem como o arquivo da vítima, literalmente, sem validação.
  4. Executou a attachmentFilename() real — resolveu id_rsa como o basename de destino aparentemente seguro.
  5. Reproduziu a construção real do vaultName a partir de note-parser.ts:427 (${key}-${filename}).
  6. Executou a copyAttachments() real — resultado { copied: 1, skipped: 0, missing: 0 }.
  7. Leu de volta fake-vault/attachments/EVILKEY1-id_rsa — conteúdo byte a byte idêntico ao arquivo original da vítima.
Baixar ferramenta