Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
zotlit-PoC — PoC — la importación de adjuntos copia archivos desde rutas locales no aprobadas en ZotLit (GHSA-4qh7-66xv-h329, CVE-2026-87000, CVSS 5.5). | Kitploit
Herramientas/GitHubGitHub/squeeze440/zotlit-poc
Análisis de VulnerabilidadesExplotaciónExfiltración de DatosRecopilación de InformaciónVirtualización de SeguridadPapers e Investigación
GitHubsqueeze440/zotlit-poc

zotlit-PoC

PoC — la importación de adjuntos copia archivos desde rutas locales no aprobadas en ZotLit (GHSA-4qh7-66xv-h329, CVE-2026-87000, CVSS 5.5).

Ver Repositorio
20hace 19 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

ZotLit: aviso de seguridad

Estado del CVE: solicitado, pendiente de asignación. Este hallazgo se publica como GHSA-4qh7-66xv-h329. Al asignarse el CVE, este repositorio se renombra CVE-YYYY-NNNNN-zotlit-PoC y este banner se reemplaza con el enlace del CVE.

InvestigadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-4qh7-66xv-h329
CVSS 3.15.5 (Medio)
DebilidadCWE-73, CWE-200

Resumen

El control externo del nombre de archivo o la ruta en la función de importación de adjuntos de AidenLx ZotLit (aidenlx/zotlit) 1.1.12 permite a un atacante que controla una biblioteca de Zotero compartida/sincronizada divulgar archivos locales arbitrarios del sistema de archivos de la víctima en el vault de Obsidian de la víctima mediante una ruta de adjunto linked_file manipulada.

Producto

ZotLit — plugin de Obsidian para la integración con Zotero (aidenlx/zotlit, id del plugin zotlit, versión del manifiesto 1.1.12)

Versión probada

Commit de 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 (Medio)

Métricas no obvias: AV:L — la explotación ocurre cuando el proceso local de Obsidian/zotlit de la víctima procesa metadatos de elementos de Zotero proporcionados por el atacante (entregados mediante una biblioteca compartida/sincronizada), la misma convención usada para errores de "archivo malicioso procesado por una aplicación local", aunque la entrega en sí pueda ocurrir a través de una red (biblioteca de grupo compartida, archivo de exportación enviado por correo electrónico). UI:R — la víctima debe importar/sincronizar la biblioteca maliciosa en Zotero y ejecutar la función de importación de notas de ZotLit (o la inserción de anotaciones/citas) en una nota que haga referencia al adjunto manipulado; esto es un uso rutinario de la funcionalidad principal del plugin, habilitada por defecto (attachment.import es true por defecto), no una acción inusual. I:N/A:N — este hallazgo es únicamente una primitiva de lectura/copia; no se afirma un path traversal del lado del destino (véase Detalles para una observación relacionada pero no verificada).

Detalles

ZotLit lee los metadatos de los adjuntos directamente de la base de datos SQLite de Zotero (o de una biblioteca sincronizada/compartida), incluida la columna de texto libre itemAttachments.path, y confía completamente en ella al resolver desde dónde leer un adjunto "vinculado":

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

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

    Para las filas con linkMode: 2 (linked_file) cuyo path no lleva el marcador de directorio base attachments:, parsed.path es la cadena sin procesar de la base de datos devuelta tal cual como la ruta absoluta del sistema de archivos que se va a leer — sin lista de permitidos, sin confinamiento al directorio de datos de Zotero ni a ninguna ubicación aprobada por el usuario.

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

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

    El nombre de archivo usado para construir la copia en el vault se deriva de esa misma ruta controlada por el atacante mediante basename(), por lo que el nombre de archivo de destino está influenciado por el atacante pero carece de separadores de ruta (seguro frente a traversal en esta rama).

  • apps/obsidian/src/services/note-import/note-parser.ts:403-430 — se invoca resolveEmbeddedImage() al convertir la anotación de imagen incrustada de una nota de literatura de Zotero en Markdown de Obsidian (una acción rutinaria y predeterminada de la función "Import Note" de ZotLit). Resuelve sourcePath = attachmentAbsPath(attachment, ...) y llama a deps.resolveLink({ sourcePath, vaultName: \${attachment.key}-${filename}` })` — encolando una copia de cualquier ruta absoluta elegida por el atacante en el vault.

  • apps/obsidian/src/services/attachment-import/service.ts:125-155 — AttachmentImportBatch.resolveLink() encola { source: sourcePath, dest: <vault attachment folder>/<key>-<filename> }, condicionado únicamente por la configuración attachment.import, cuyo valor predeterminado es true (apps/obsidian/src/services/settings/schema.ts:123).

  • apps/obsidian/src/lib/copy-attachments.ts:43-60 — copyAttachment() realiza la lectura+escritura real sin ninguna validación de ruta: stat(source) y luego copyFile(source, dest).

Efecto neto: un atacante que pueda introducir un elemento de Zotero linked_file (linkMode 2) en la biblioteca de la víctima — por ejemplo, una biblioteca de grupo compartida de Zotero, una exportación .rdf/.json/Better BibTeX que la víctima importe, o una biblioteca sincronizada sobre la que el atacante tenga acceso de escritura — puede establecer la ruta del adjunto de ese elemento a cualquier archivo del disco de la víctima (~/.ssh/id_rsa, almacenes de credenciales del navegador, otros vaults, archivos .env, etc.). En el momento en que la víctima ejecuta la importación de notas de ZotLit (o renderiza/incrusta esa anotación) con la configuración predeterminada attachment.import: true, ZotLit copia silenciosamente el contenido de ese archivo en el vault de Obsidian de la víctima bajo un nombre predecible (<attachmentKey>-<basename>). Dado que los vaults se sincronizan, se confirman en git o se publican de forma rutinaria, esto traslada datos a los que el atacante nunca podría acceder de otro modo a una ubicación que el atacante (o cualquier otra persona con acceso al destino de sincronización) puede leer.

Observación relacionada y no verificada (no forma parte del PoC de este hallazgo): la rama hermana "storage" de attachmentFilename() (zt-template-attach.ts:103-104) devuelve el sufijo de ruta sin procesar sin la llamada a basename() aplicada a las otras dos ramas. Si esto es explotable de forma independiente depende de cómo el propio mecanismo de sincronización de almacenamiento de Zotero nombra los archivos descargados localmente, lo cual queda fuera de este repositorio y no se verificó — se señala aquí únicamente como una brecha de endurecimiento que vale la pena cerrar por consistencia.

Prueba de concepto

Verificación dinámica: las funciones vulnerables exactas (parseAttachmentPath, attachmentAbsPath, attachmentFilename, copyAttachments/copyAttachment/writeCopy/destMatches, isErrno, reflink) se extrajeron literalmente (con archivo:línea citados arriba, lógica sin cambios) del código fuente distribuido y se ejecutaron directamente en Node, porque no había disponible una instalación completa del workspace de pnpm sin conexión en este sandbox (la cadena de herramientas corepack/pnpm está rota sin conexión). La única sustitución fue cambiar la llamada al logger LogTape por console.warn — solo cosmético, sin efecto alguno en el flujo de control. Script: ~/engagements/zotlit/evidence/poc-verify.mjs.

Descargar herramienta