Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2025-68621 — Educational PoC et analyse de CVE-2025-68621, une attaque temporelle sur la connexion de synchronisation de Trilium Notes. Démontre la récupération du hachage HMAC via un canal auxiliaire temporel réseau, avec les détails de la cause racine, du correctif et de l'atténuation. | Kitploit
Outils/GitHubGitHub/sivaadityacoder/cve-2025-68621
Analyse des VulnérabilitésExploitationSécurité WebCryptographieArticles et RechercheApprentissage et Éducation
GitHubsivaadityacoder/cve-2025-68621

CVE-2025-68621

Educational PoC et analyse de CVE-2025-68621, une attaque temporelle sur la connexion de synchronisation de Trilium Notes. Démontre la récupération du hachage HMAC via un canal auxiliaire temporel réseau, avec les détails de la cause racine, du correctif et de l'atténuation.

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
Voir le dépôt
il y a 3 moisPas encore vérifié

CVE-2025-68621 — Attaque temporelle sur Trilium Notes via /api/login/sync

Sévérité : HAUTE (CVSS 7.4) Logiciel affecté : TriliumNext/Trilium < 0.101.0 Type de vulnérabilité : CWE-208 – Discrepance temporelle observable Corrigé dans : Trilium 0.101.0 (PR #8129) Publié : 2026-02-06 | Réservé : 2025-12-19


Table des matières

  1. Mon approche
  2. Cause racine
  3. Impact
  4. Correction
  5. Points clés à retenir
  6. Chronologie
  7. Références

Mon approche

Qu'est-ce que Trilium Notes ?

Trilium Notes est une application open-source, multiplateforme, de prise de notes hiérarchique conçue pour construire de grandes bases de connaissances personnelles. Elle prend en charge :

  • Un serveur auto-hébergé avec lequel plusieurs clients peuvent se synchroniser
  • Des types de notes riches (texte, code, canvas, diagrammes)
  • Une API de script puissante

La fonctionnalité de synchronisation permet à un client Trilium de s'authentifier auprès d'un serveur Trilium afin que les notes restent synchronisées entre les appareils. Ce point de terminaison de synchronisation est la porte d'entrée de CVE-2025-68621.

Qu'est-ce qu'une attaque temporelle ?

Une attaque temporelle est une attaque par canal auxiliaire où un attaquant apprend une information secrète en mesurant combien de temps un système met à traiter différentes entrées.

L'exemple classique est la comparaison de chaînes :

root@kitploit:~
"correct_password" !== "aorrect_password"   → échec à la position 0 → rapide
"correct_password" !== "cXrrect_password"   → échec à la position 1 → légèrement plus lent
"correct_password" !== "correct_password"   → correspondance complète → le plus lent

La plupart des langages de programmation comparent les chaînes caractère par caractère et s'arrêtent dès qu'une différence est trouvée (sortie anticipée). Cela signifie :

  • Une supposition qui correspond au premier octet prend un tout petit peu plus de temps qu'une qui échoue immédiatement.
  • En envoyant des milliers de suppositions et en faisant la moyenne des temps de réponse, un attaquant peut déterminer statistiquement quel octet est correct — position par position — jusqu'à ce que le secret complet soit récupéré.

La correction consiste à utiliser une fonction de comparaison en temps constant qui examine toujours chaque octet indépendamment de l'endroit où une différence se produit.

Comment la vulnérabilité a été découverte

La vulnérabilité a été découverte par révision manuelle du code de la logique d'authentification de Trilium. Le chercheur a examiné le flux de connexion de synchronisation dans apps/server/src/routes/api/login.ts et a remarqué le motif suivant dans la fonction loginSync() (autour de la ligne 111) :

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

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

Le signal d'alarme est l'utilisation de l'opérateur !== natif de JavaScript pour comparer des hachages HMAC. L'opérateur !== n'est pas en temps constant — il sort dès qu'il trouve un caractère différent. Comme la comparaison est effectuée sur des chaînes simples (sans utiliser de fonction de comparaison cryptographiquement sûre), le temps de réponse divulgue des informations sur le nombre d'octets de tête de la supposition de l'attaquant qui sont corrects.

Le chercheur s'est alors demandé :

"Cette petite différence temporelle peut-elle être suffisamment amplifiée, à travers un réseau, pour récupérer le hachage HMAC complet encodé en Base64 de 44 caractères ?"

La réponse s'est avérée être oui — avec suffisamment de mesures répétées et une analyse statistique, le signal dépasse le bruit.

L'algorithme d'attaque

Lorsqu'un client Trilium souhaite se synchroniser, il appelle POST /api/login/sync avec un corps JSON comme :

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

La récupération octet par octet fonctionne comme suit :

root@kitploit:~
Pour position = 0 jusqu'à 43 :
    Pour chaque caractère candidat c dans le jeu de caractères (A-Z, a-z, 0-9, +, /, =) :
        Envoyer ÉCHANTILLONS requêtes avec hash = préfixe_connu + c + bourrage
        Enregistrer le temps de réponse moyen
    Meilleur caractère = candidat avec le temps moyen le plus élevé
    Ajouter le meilleur caractère au préfixe_connu

Après 44 itérations (une par caractère Base64), le hachage HMAC complet de 44 caractères est récupéré.

Exigences pratiques :

  • >100 000 requêtes HTTP au total (50 échantillons × 65 caractères du jeu × 44 positions ≈ 143 000)
  • >1 000 adresses IP source différentes en raison de la limitation de débit de Trilium (nécessite des proxies rotatifs ou un botnet)
  • Faible gigue réseau entre l'attaquant et le serveur (LAN ou connexion cloud stable fonctionne le mieux)
  • Un chronomètre de haute précision (time.perf_counter() en Python donne une résolution nanoseconde)

Preuve de concept

Voir poc.py pour un PoC Python entièrement annoté.

Résumé rapide de ce que fait le PoC :

  1. Parcourt les 44 positions de caractères Base64 du hachage HMAC.
  2. Pour chaque position, essaie chaque caractère du jeu de caractères Base64 (A–Z, a–z, 0–9, +, /, =).
  3. Envoie 50 requêtes HTTP POST à /api/login/sync pour chaque candidat et mesure le temps de réponse médian.
  4. Sélectionne le candidat avec le temps de réponse médian le plus élevé comme caractère correct.
  5. Après avoir récupéré les 44 caractères, s'authentifie avec le hachage récupéré.

Avertissement : Ce PoC est fourni à des fins éducatives et de recherche en sécurité responsable uniquement. Ne l'utilisez pas contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation écrite explicite de tester.


Cause racine

Les opérateurs !== (et ===) de JavaScript effectuent une comparaison lexicographique avec sortie anticipée. La ligne vulnérable dans apps/server/src/routes/api/login.ts :

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

Le comportement de sortie anticipée crée une différence temporelle mesurable par octet correspondant :

Chaque octet supplémentaire correspondant coûte une minuscule quantité de temps CPU δ. Sur des milliers d'échantillons, le temps de réponse moyen pour une supposition "octet N correct" est mesurablement plus long que pour une supposition "octet N incorrect", divulguant suffisamment d'informations pour récupérer le hachage HMAC complet caractère par caractère.

Décomposition du score CVSS

Chaîne vectorielle : CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N


Impact

Une exploitation réussie donne à l'attaquant :

  • Accès complet en lecture à toutes les notes, y compris les métadonnées de notes chiffrées
  • Accès complet en écriture — l'attaquant peut créer, modifier ou supprimer des notes
  • Accès persistant — le hachage récupéré peut être réutilisé (dans la fenêtre de timestamp)

C'est particulièrement grave pour les utilisateurs qui stockent des données personnelles sensibles (mots de passe, documents privés, entrées de journal) dans leur base de connaissances Trilium.


Correction

La correction remplace la comparaison non en temps constant !== par la fonction intégrée crypto.timingSafeEqual() de Node.js :

Avant (vulnérable) :

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

Après (sécurisé) :

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() compare toujours chaque octet, donc le temps d'exécution ne dépend pas du nombre d'octets correspondants. Le signal temporel disparaît.

Voir vulnerable.ts et fix.ts pour des exemples de code côte à côte.

Comment mettre à jour

Si vous exécutez un serveur Trilium auto-hébergé, mettez à jour immédiatement vers la version 0.101.0 ou ultérieure.

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

Points clés à retenir

  1. N'utilisez jamais === / !== pour comparer des secrets. Les opérateurs d'égalité de JavaScript ne sont pas en temps constant. Toute comparaison de HMAC, jetons ou mots de passe utilisant === / !== est un oracle temporel potentiel.

  2. Utilisez toujours crypto.timingSafeEqual() dans Node.js (ou un équivalent dans votre langage/environnement d'exécution) lors de la comparaison de valeurs cryptographiques. C'est l'API standard et spécialement conçue pour cette tâche.

  3. Les attaques temporelles sont réelles sur le réseau. Bien que des différences nanosecondes semblent impossibles à détecter sur Internet, les techniques statistiques et un nombre suffisant d'échantillons peuvent extraire un signal clair des mesures bruitées — en particulier dans des environnements à faible gigue.

  4. La limitation de débit seule n'est pas une mitigation suffisante. Même avec une limitation de débit par IP, un attaquant ayant accès à des proxies rotatifs ou un botnet peut toujours accumuler suffisamment d'échantillons pour exploiter la différence temporelle.

  5. La vérification HMAC mérite la même attention que la comparaison de mots de passe. Les hachages HMAC sont des secrets. Traitez toute comparaison de valeur secrète comme si les canaux auxiliaires temporels pouvaient être exploités.

  6. La revue de code pour les motifs cryptographiques est essentielle. Cette vulnérabilité a été trouvée par une revue manuelle — une seule ligne de code qui semblait inoffensive mais qui avait de sérieuses implications de sécurité. Des audits dédiés crypto/sécurité aident à détecter ces problèmes tôt.


Chronologie


Références


Ce dépôt est maintenu à des fins éducatives et de recherche dans le cadre des principes de divulgation responsable.

Télécharger l’outil
Saisie vs. AttenduOctets comparésTemps
Mauvais octet 01~T
Octet 0 correct, mauvais octet 12~T + δ
Octets 0–1 corrects, mauvais octet 23~T + 2δ
………
Les 44 octets corrects44~T + 43δ
MétriqueValeurRaison
Score de base7.4 HAUTE
Vecteur d'attaqueRéseau (N)Exploitable via Internet
Complexité d'attaqueÉlevée (H)Nécessite de nombreuses requêtes + une temporisation stable
Privilèges requisAucun (N)Aucun compte nécessaire
Interaction de l'utilisateurAucune (N)La victime n'a rien à faire
PérimètreInchangé (U)Seul le serveur Trilium est affecté
ConfidentialitéÉlevée (H)L'intégralité de la base de notes est lisible
IntégritéÉlevée (H)L'attaquant peut écrire/modifier des notes
DisponibilitéAucune (N)Aucun composant de déni de service
DateÉvénement
2025-12-19CVE-2025-68621 réservé par GitHub Security
2025-12-21PR de correction #8129 ouverte
2025-12-25PR fusionnée ; Trilium 0.101.0 publié
2026-02-06CVE publié publiquement
2026-02-09Enrichissement ADP de la CISA ajouté
RessourceLien
Avis de sécurité GitHubGHSA-hxf6-58cx-qq3x
Pull Request de correctionTriliumNext/Trilium#8129
Enregistrement CVE (CVEProject)CVE-2025-68621.json
CWE-208Discrepance temporelle observable
Dépôt Trilium NotesTriliumNext/Trilium