Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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
CVE-2025-68621 — PoC educativo y análisis de CVE-2025-68621, un ataque de sincronización en el inicio de sesión de sincronización de Trilium Notes. Demuestra la recuperación de hash HMAC mediante un canal lateral de sincronización de red, con causa raíz, corrección y detalles de mitigación. | Kitploit
Herramientas/GitHubGitHub/sivaadityacoder/cve-2025-68621
Análisis de VulnerabilidadesExplotaciónSeguridad WebCriptografíaPapers e InvestigaciónAprendizaje y Educación
GitHubsivaadityacoder/cve-2025-68621

CVE-2025-68621

PoC educativo y análisis de CVE-2025-68621, un ataque de sincronización en el inicio de sesión de sincronización de Trilium Notes. Demuestra la recuperación de hash HMAC mediante un canal lateral de sincronización de red, con causa raíz, corrección y detalles de mitigación.

Ver Repositorio
1hace 4 mesesAú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

CVE-2025-68621 — Ataque de temporización en Trilium Notes sobre /api/login/sync

Gravedad: ALTA (CVSS 7.4) Software afectado: TriliumNext/Trilium < 0.101.0 Tipo de vulnerabilidad: CWE-208 – Discrepancia de temporización observable Corregido en: Trilium 0.101.0 (PR #8129) Publicado: 2026-02-06 | Reservado: 2025-12-19


Tabla de contenidos

  1. Mi enfoque
  2. Causa raíz
  3. Impacto
  4. Solución
  5. Conclusiones clave
  6. Cronología
  7. Referencias

Mi enfoque

¿Qué es Trilium Notes?

Trilium Notes es una aplicación de toma de notas jerárquica, de código abierto y multiplataforma, diseñada para construir grandes bases de conocimiento personales. Admite:

  • Un servidor autoalojado con el que varios clientes pueden sincronizarse
  • Tipos de notas enriquecidos (texto, código, lienzo, diagramas)
  • Una potente API de scripting

La función de sincronización permite que un cliente Trilium se autentique en un servidor Trilium para que las notas permanezcan sincronizadas entre dispositivos. Este endpoint de sincronización es el punto de entrada de CVE-2025-68621.

¿Qué es un ataque de temporización?

Un ataque de temporización es un ataque de canal lateral en el que un atacante obtiene información secreta midiendo cuánto tiempo tarda un sistema en procesar diferentes entradas.

El ejemplo clásico es la comparación de cadenas:

root@kitploit:~
"correct_password" !== "aorrect_password"   → fails at position 0 → fast
"correct_password" !== "cXrrect_password"   → fails at position 1 → slightly slower
"correct_password" !== "correct_password"   → matches fully     → slowest

La mayoría de los lenguajes de programación comparan cadenas carácter por carácter y se detienen en cuanto encuentran una discrepancia (salida anticipada). Esto significa:

  • Una suposición que coincide con el primer byte tarda un poco más que una que no coincide de inmediato.
  • Al enviar miles de suposiciones y promediar los tiempos de respuesta, un atacante puede determinar estadísticamente qué byte es el correcto — posición por posición — hasta recuperar el secreto completo.

La solución es utilizar una función de comparación en tiempo constante que siempre inspeccione todos los bytes, independientemente de dónde se produzca una discrepancia.

Cómo se descubrió la vulnerabilidad

La vulnerabilidad se descubrió mediante revisión manual de código de la lógica de autenticación de Trilium. El investigador examinó el flujo de inicio de sesión de sincronización en apps/server/src/routes/api/login.ts y observó el siguiente patrón en la función loginSync() (alrededor de la línea 111):

root@kitploit:~
const documentSecret = options.getOption("documentSecret");
const expectedHash   = utils.hmac(documentSecret, timestampStr);
const givenHash      = req.body.hash;

if (expectedHash !== givenHash) {          // ← VULNERABLE LINE
    return [400, { message: "Sync login credentials are incorrect..." }];
}

La señal de alerta es el uso del operador !== incorporado de JavaScript para comparar hashes HMAC. El operador !== no es de tiempo constante: sale en cuanto encuentra un carácter diferente. Dado que la comparación se realiza sobre cadenas de texto simples (sin utilizar una función de comparación criptográficamente segura), el tiempo de respuesta filtra información sobre cuántos bytes iniciales de la suposición del atacante son correctos.

El investigador se preguntó entonces:

"¿Puede esta pequeña diferencia de temporización amplificarse lo suficiente, a través de una red, como para recuperar el hash HMAC completo de 44 caracteres codificado en Base64?"

La respuesta resultó ser sí — con suficientes mediciones repetidas y algo de análisis estadístico, la señal supera al ruido.

El algoritmo del ataque

Cuando un cliente Trilium quiere sincronizar, llama a POST /api/login/sync con un cuerpo JSON como:

root@kitploit:~
{
  "timestamp":   "2025-12-19T10:00:00.000Z",
  "syncVersion": 34,
  "hash":        "<HMAC-SHA256 of documentSecret + timestamp, Base64-encoded>"
}

La recuperación byte a byte funciona de la siguiente manera:

root@kitploit:~
For position = 0 to 43:
    For each candidate character c in charset (A-Z, a-z, 0-9, +, /, =):
        Send SAMPLES requests with hash = known_prefix + c + padding
        Record average response time
    Best character = candidate with highest average time
    Append best character to known_prefix

Tras 44 iteraciones (una por carácter Base64), se recupera el hash HMAC completo de 44 caracteres.

Requisitos prácticos:

  • >100 000 solicitudes HTTP en total (50 muestras × 65 caracteres del juego × 44 posiciones ≈ 143 000)
  • >1 000 direcciones IP de origen diferentes debido a la limitación de frecuencia de Trilium (requiere proxies rotativos o una botnet)
  • Baja fluctuación de red entre atacante y servidor (LAN o conexión en la nube estable funciona mejor)
  • Un temporizador de alta precisión (time.perf_counter() en Python ofrece resolución de nanosegundos)

Prueba de concepto

Consulte poc.py para ver un PoC de Python totalmente comentado.

Resumen rápido de lo que hace el PoC:

  1. Itera a través de las 44 posiciones de caracteres Base64 del hash HMAC.
  2. Para cada posición, prueba todos los caracteres del juego Base64 (A–Z, a–z, 0–9, +, /, =).
  3. Envía 50 solicitudes HTTP POST a /api/login/sync para cada candidato y mide el tiempo de respuesta medio.
  4. Selecciona el candidato con el mayor tiempo de respuesta medio como el carácter correcto.
  5. Tras recuperar los 44 caracteres, se autentica con el hash recuperado.

Aviso legal: Este PoC se proporciona únicamente con fines educativos y de investigación de seguridad responsable. No lo utilice contra sistemas que no le pertenezcan o para los que no tenga permiso explícito por escrito.


Causa raíz

Los operadores !== (y ===) de JavaScript realizan una comparación lexicográfica con salida anticipada. La línea vulnerable en apps/server/src/routes/api/login.ts:

root@kitploit:~
if (expectedHash !== givenHash) {
    return [400, { message: "Sync login credentials are incorrect..." }];
}

El comportamiento de salida anticipada crea una diferencia de temporización medible por cada byte coincidente:

Suposición vs. esperadoBytes comparadosTiempo
Byte 0 incorrecto1~T
Byte 0 correcto, byte 1 incorrecto2~T + δ
Bytes 0–1 correctos, byte 2 incorrecto3~T + 2δ
………
Los 44 bytes correctos44~T + 43δ

Cada byte adicional coincidente cuesta una pequeña cantidad extra de tiempo de CPU δ. A lo largo de miles de muestras, el tiempo de respuesta medio para una suposición con el "byte N correcto" es mediblemente mayor que para una con el "byte N incorrecto", filtrando suficiente información para recuperar el hash HMAC completo carácter por carácter.

Desglose de la puntuación CVSS

MétricaValorRazón
Puntuación base7.4 ALTA
Vector de ataqueRed (N)Explotable a través de internet
Complejidad de ataqueAlta (H)Requiere muchas solicitudes + temporización estable
Privilegios requeridosNinguno (N)No se necesita cuenta
Interacción del usuarioNinguna (N)La víctima no necesita hacer nada
AlcanceSin cambios (U)Solo se ve afectado el servidor Trilium
ConfidencialidadAlta (H)Toda la base de notas es legible
IntegridadAlta (H)El atacante puede escribir/modificar notas
DisponibilidadNinguna (N)Sin componente de denegación de servicio

Cadena de vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N


Impacto

Una explotación exitosa otorga al atacante:

  • Acceso de lectura completo a todas las notas, incluidos los metadatos de notas cifradas
  • Acceso de escritura completo — el atacante puede crear, modificar o eliminar notas
  • Acceso persistente — el hash recuperado puede reutilizarse (dentro de la ventana de marca de tiempo)

Esto es especialmente grave para los usuarios que almacenan datos personales sensibles (contraseñas, documentos privados, entradas de diario) en su base de conocimiento de Trilium.


Solución

La solución sustituye la comparación !== que no es de tiempo constante por la función integrada crypto.timingSafeEqual() de Node.js:

Antes (vulnerable):

root@kitploit:~
if (expectedHash !== givenHash) {
    return [400, { message: "Sync login credentials are incorrect..." }];
}

Después (seguro):

root@kitploit:~
import * as crypto from "crypto";

const expectedBuffer = Buffer.from(expectedHash);
const givenBuffer    = Buffer.from(givenHash ?? "");

if (expectedBuffer.length !== givenBuffer.length ||
    !crypto.timingSafeEqual(expectedBuffer, givenBuffer)) {
    return [400, { message: "Sync login credentials are incorrect..." }];
}

crypto.timingSafeEqual() siempre compara todos los bytes, por lo que el tiempo de ejecución no depende de cuántos bytes coincidan. La señal de temporización desaparece.

Consulte vulnerable.ts y fix.ts para ver ejemplos de código lado a lado.

Cómo actualizar

Si está ejecutando un servidor Trilium autoalojado, actualice a la versión 0.101.0 o posterior inmediatamente.

root@kitploit:~
# Docker example
docker pull zadam/trilium:0.101.0

Conclusiones clave

  1. Nunca utilice === / !== para comparar secretos. Los operadores de igualdad de JavaScript no son de tiempo constante. Cualquier comparación de HMAC, tokens o contraseñas que utilice === / !== es un posible oráculo de temporización.

  2. Utilice siempre crypto.timingSafeEqual() en Node.js (o un equivalente en su lenguaje/entorno de ejecución) al comparar valores criptográficos. Es la API estándar y específica para esta tarea.

  3. Los ataques de temporización son reales a través de la red. Aunque las diferencias de nanosegundos parezcan imposibles de detectar en internet, las técnicas estadísticas y suficientes muestras pueden extraer una señal clara de mediciones ruidosas — especialmente en entornos de baja fluctuación.

  4. La limitación de frecuencia por sí sola no es una mitigación suficiente. Incluso con limitación por IP, un atacante con acceso a proxies rotativos o una botnet puede seguir acumulando suficientes muestras para explotar la diferencia de temporización.

  5. La verificación HMAC merece el mismo cuidado que la comparación de contraseñas. Los hashes HMAC son secretos. Trate cualquier comparación de un valor secreto como si los canales laterales de temporización pudieran ser explotados.

  6. La revisión de código en busca de patrones criptográficos es esencial. Esta vulnerabilidad se encontró mediante revisión manual: una sola línea de código que parecía inofensiva pero tenía serias implicaciones de seguridad. Las auditorías dedicadas de criptografía/seguridad ayudan a detectar estos problemas a tiempo.


Cronología

FechaEvento
2025-12-19CVE-2025-68621 reservado por GitHub Security
2025-12-21Abierto el PR de corrección #8129
2025-12-25PR fusionado; lanzada Trilium 0.101.0
2026-02-06CVE publicado públicamente
2026-02-09Enriquecimiento ADP de CISA añadido

Referencias

RecursoEnlace
Aviso de seguridad de GitHubGHSA-hxf6-58cx-qq3x
Pull request de correcciónTriliumNext/Trilium#8129
Registro CVE (CVEProject)CVE-2025-68621.json
CWE-208Discrepancia de temporización observable
Repositorio de Trilium NotesTriliumNext/Trilium

Este repositorio se mantiene con fines educativos y de investigación bajo principios de divulgación responsable.

Descargar herramienta