Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2025-68621 — Lehrreicher PoC und Analyse von CVE-2025-68621, einem Timing-Angriff auf den Sync-Login von Trilium Notes. Demonstriert die HMAC-Hash-Wiederherstellung über einen Netzwerk-Timing-Seitenkanal, mit Root-Cause, Fix und Minderungsdetails. | Kitploit
Tools/GitHubGitHub/sivaadityacoder/cve-2025-68621
SchwachstellenanalyseExploitationWebsicherheitKryptographiePapers & ForschungLernen & Bildung
GitHubsivaadityacoder/cve-2025-68621

CVE-2025-68621

Lehrreicher PoC und Analyse von CVE-2025-68621, einem Timing-Angriff auf den Sync-Login von Trilium Notes. Demonstriert die HMAC-Hash-Wiederherstellung über einen Netzwerk-Timing-Seitenkanal, mit Root-Cause, Fix und Minderungsdetails.

Repository anzeigen
1vor 4 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2025-68621 — Timing-Angriff auf /api/login/sync in Trilium Notes

Schweregrad: HIGH (CVSS 7.4) Betroffene Software: TriliumNext/Trilium < 0.101.0 Schwachstellentyp: CWE-208 – Beobachtbare Timing-Diskrepanz (Observable Timing Discrepancy) Behoben in: Trilium 0.101.0 (PR #8129) Veröffentlicht: 2026-02-06 | Reserviert: 2025-12-19


Inhaltsverzeichnis

  1. Mein Ansatz
  2. Grundursache
  3. Auswirkungen
  4. Behebung
  5. Wichtige Erkenntnisse
  6. Chronologie
  7. Referenzen

Mein Ansatz

Was ist Trilium Notes?

Trilium Notes ist eine quelloffene, plattformübergreifende, hierarchische Notizanwendung, die für den Aufbau großer persönlicher Wissensdatenbanken entwickelt wurde. Sie unterstützt:

  • Einen selbst gehosteten Server, mit dem mehrere Clients synchronisieren können
  • Umfangreiche Notiztypen (Text, Code, Canvas, Diagramme)
  • Eine leistungsstarke Skripting-API

Die Sync-Funktion ermöglicht es einem Trilium-Client, sich gegenüber einem Trilium-Server zu authentifizieren, damit Notizen geräteübergreifend synchron bleiben. Dieser Sync-Endpunkt ist der Einstiegspunkt für CVE-2025-68621.

Was ist ein Timing-Angriff?

Ein Timing-Angriff ist ein Seitenkanalangriff, bei dem ein Angreifer geheime Informationen erlangt, indem er misst, wie lange ein System für die Verarbeitung unterschiedlicher Eingaben benötigt.

Das klassische Beispiel ist der String-Vergleich:

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

Die meisten Programmiersprachen vergleichen Strings Zeichen für Zeichen und brechen ab, sobald eine Abweichung gefunden wird (Early Exit). Das bedeutet:

  • Ein Versuch, der beim ersten Byte übereinstimmt, dauert einen winzigen Moment länger als einer, der sofort abweicht.
  • Indem er Tausende von Versuchen sendet und die Antwortzeiten mittelt, kann ein Angreifer statistisch bestimmen, welches Byte korrekt ist — Position für Position — bis das vollständige Geheimnis wiederhergestellt ist.

Die Lösung besteht darin, eine Vergleichsfunktion mit konstanter Laufzeit (Constant-Time-Vergleich) zu verwenden, die immer jedes Byte prüft, unabhängig davon, wo eine Abweichung auftritt.

Wie die Schwachstelle entdeckt wurde

Die Schwachstelle wurde durch manuelle Code-Überprüfung der Authentifizierungslogik von Trilium entdeckt. Der Forscher untersuchte den Sync-Login-Ablauf in apps/server/src/routes/api/login.ts und bemerkte in der Funktion loginSync() (etwa in Zeile 111) das folgende Muster:

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..." }];
}

Ein Warnsignal ist die Verwendung des in JavaScript eingebauten Operators !== zum Vergleich von HMAC-Hashes. Der Operator !== ist nicht zeitkonstant — er bricht ab, sobald er ein abweichendes Zeichen findet. Da der Vergleich mit einfachen Strings durchgeführt wird (ohne eine kryptografisch sichere Vergleichsfunktion), leakt die Antwortzeit Informationen darüber, wie viele führende Bytes des Angreifer-Versuchs korrekt sind.

Der Forscher stellte dann die Frage:

„Kann dieser kleine Timing-Unterschied über ein Netzwerk stark genug verstärkt werden, um den vollständigen, 44 Zeichen langen Base64-codierten HMAC-Hash zu rekonstruieren?“

Die Antwort war, wie sich herausstellte, ja — mit genügend wiederholten Messungen und etwas statistischer Analyse hebt sich das Signal vom Rauschen ab.

Der Angriffsalgorithmus

Wenn ein Trilium-Client synchronisieren möchte, ruft er POST /api/login/sync mit einem JSON-Body wie diesem auf:

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

Die byteweise Wiederherstellung funktioniert wie folgt:

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

Nach 44 Iterationen (eine pro Base64-Zeichen) ist der vollständige, 44 Zeichen lange HMAC-Hash wiederhergestellt.

Praktische Anforderungen:

  • >100 000 HTTP-Anfragen insgesamt (50 Stichproben × 65 Zeichensatzzeichen × 44 Positionen ≈ 143 000)
  • >1 000 verschiedene Quell-IP-Adressen aufgrund des Rate-Limiting von Trilium (erfordert rotierende Proxys oder ein Botnetz)
  • Geringes Netzwerk-Jitter zwischen Angreifer und Server (LAN oder eine stabile Cloud-Verbindung funktioniert am besten)
  • Ein Hochpräzisions-Timer (time.perf_counter() in Python bietet eine Auflösung im Nanosekundenbereich)

Proof of Concept

Siehe poc.py für ein vollständig annotiertes Python-PoC.

Kurzübersicht, was das PoC tut:

  1. Durchläuft alle 44 Base64-Zeichenpositionen des HMAC-Hashs.
  2. Testet für jede Position jedes Zeichen im Base64-Zeichensatz (A–Z, a–z, 0–9, +, /, =).
  3. Sendet 50 HTTP-POST-Anfragen an /api/login/sync für jeden Kandidaten und misst die mittlere Antwortzeit (Median).
  4. Wählt den Kandidaten mit der höchsten mittleren Antwortzeit als korrektes Zeichen.
  5. Authentifiziert sich nach der Wiederherstellung aller 44 Zeichen mit dem rekonstruierten Hash.

Haftungsausschluss: Dieses PoC dient ausschließlich Bildungszwecken und verantwortungsvoller Sicherheitsforschung. Verwenden Sie es nicht gegen Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben.


Grundursache

Die JavaScript-Operatoren !== (und ===) führen einen lexikografischen Vergleich mit frühem Abbruch durch. Die verwundbare Zeile in apps/server/src/routes/api/login.ts:

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

Das Verhalten des frühen Abbruchs erzeugt einen messbaren Timing-Unterschied pro übereinstimmendem Byte:

Versuch vs. ErwartetVerglichene BytesZeit
Falsches Byte 01~T
Korrektes Byte 0, falsches Byte 12~T + δ
Korrekte Bytes 0–1, falsches Byte 23~T + 2δ
………
Alle 44 Bytes korrekt44~T + 43δ

Jedes zusätzlich übereinstimmende Byte kostet eine winzige zusätzliche Menge an CPU-Zeit δ. Über Tausende von Stichproben hinweg ist die durchschnittliche Antwortzeit für einen Versuch mit „korrektem Byte N“ messbar länger als für einen Versuch mit „inkorrektem Byte N“, wodurch genügend Informationen preisgegeben werden, um den vollständigen HMAC-Hash Zeichen für Zeichen wiederherzustellen.

Aufschlüsselung des CVSS-Scores

MetrikWertBegründung
Basis-Score7.4 HIGH
AngriffsvektorNetzwerk (N)Über das Internet ausnutzbar
AngriffskomplexitätHoch (H)Erfordert viele Anfragen + stabiles Timing
Erforderliche PrivilegienKeine (N)Kein Konto erforderlich
BenutzerinteraktionKeine (N)Das Opfer muss nichts tun
AuswirkungsbereichUnverändert (U)Nur der Trilium-Server ist betroffen
VertraulichkeitHoch (H)Die gesamte Notizdatenbank ist lesbar
IntegritätHoch (H)Der Angreifer kann Notizen schreiben/ändern
VerfügbarkeitKeine (N)Kein Denial-of-Service-Anteil

Vector-String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N


Auswirkungen

Eine erfolgreiche Ausnutzung verschafft dem Angreifer:

  • Vollständigen Lesezugriff auf alle Notizen, einschließlich der verschlüsselten Notiz-Metadaten
  • Vollständigen Schreibzugriff — der Angreifer kann Notizen erstellen, ändern oder löschen
  • Dauerhaften Zugriff — der wiederhergestellte Hash kann (innerhalb des Zeitstempel-Fensters) wiederverwendet werden

Dies ist besonders schwerwiegend für Benutzer, die sensible persönliche Daten (Passwörter, private Dokumente, Tagebucheinträge) in ihrer Trilium-Wissensdatenbank speichern.


Behebung

Die Behebung ersetzt den nicht zeitkonstanten Vergleich mit !== durch die in Node.js eingebaute Funktion crypto.timingSafeEqual():

Vorher (verwundbar):

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

Nachher (sicher):

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() vergleicht immer jedes Byte, sodass die Ausführungszeit nicht davon abhängt, wie viele Bytes übereinstimmen. Das Timing-Signal verschwindet.

Siehe vulnerable.ts und fix.ts für Code-Beispiele im direkten Vergleich.

So aktualisieren Sie

Wenn Sie einen selbst gehosteten Trilium-Server betreiben, aktualisieren Sie sofort auf Version 0.101.0 oder höher.

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

Wichtige Erkenntnisse

  1. Verwenden Sie niemals === / !==, um Geheimnisse zu vergleichen. Die Gleichheitsoperatoren von JavaScript sind nicht zeitkonstant. Jeder Vergleich von HMACs, Tokens oder Passwörtern mit === / !== ist ein potenzielles Timing-Orakel.

  2. Verwenden Sie in Node.js immer crypto.timingSafeEqual() (oder ein Äquivalent in Ihrer Sprache/Laufzeitumgebung), wenn Sie kryptografische Werte vergleichen. Dies ist die standardmäßige, eigens für diese Aufgabe entwickelte API.

  3. Timing-Angriffe sind über das Netzwerk real. Auch wenn Nanosekunden-Unterschiede über das Internet unmöglich zu erkennen scheinen, können statistische Verfahren und genügend Stichproben ein klares Signal aus verrauschten Messungen extrahieren — insbesondere in Umgebungen mit geringem Jitter.

  4. Rate-Limiting allein ist keine ausreichende Abschwächung. Selbst mit Rate-Limiting pro IP kann ein Angreifer mit Zugriff auf rotierende Proxys oder ein Botnetz weiterhin genügend Stichproben sammeln, um den Timing-Unterschied auszunutzen.

  5. Die HMAC-Verifizierung verdient dieselbe Sorgfalt wie der Passwortvergleich. HMAC-Hashes sind Geheimnisse. Behandeln Sie jeden Vergleich eines geheimen Werts so, als ob Timing-Seitenkanäle ausgenutzt werden könnten.

  6. Die Code-Überprüfung kryptografischer Muster ist unerlässlich. Diese Schwachstelle wurde durch manuelle Prüfung gefunden — eine einzelne Codezeile, die harmlos aussah, aber schwerwiegende Sicherheitsimplikationen hatte. Dedizierte Krypto-/Sicherheitsaudits helfen, solche Probleme frühzeitig zu erkennen.


Chronologie

DatumEreignis
2025-12-19CVE-2025-68621 von GitHub Security reserviert
2025-12-21Fix-PR #8129 eröffnet
2025-12-25PR gemergt; Trilium 0.101.0 veröffentlicht
2026-02-06CVE öffentlich publiziert
2026-02-09CISA-ADP-Anreicherung hinzugefügt

Referenzen

RessourceLink
GitHub-SicherheitsempfehlungGHSA-hxf6-58cx-qq3x
Fix-Pull-RequestTriliumNext/Trilium#8129
CVE-Eintrag (CVEProject)CVE-2025-68621.json
CWE-208Observable Timing Discrepancy
Trilium-Notes-RepositoryTriliumNext/Trilium

Dieses Repository wird zu Bildungs- und Forschungszwecken unter den Grundsätzen verantwortungsvoller Offenlegung gepflegt.

Tool herunterladen