Alle Sicherheitshinweise

fbeta ePA3-Service-OpenSource

AES-GCM-Nonce-Wiederverwendung durch eingefrorenen VAU-Request-Counter

fbetas ePA3-Service initialisiert request_counter, inkrementiert ihn aber nie; jede ausgehende innere VAU-Nachricht trägt im Header request_counter=0. Der gematik-lib-vau-Server nutzt diesen Wert für den Counter-Teil seines eigenen AES-GCM-IV, reduziert die IV-Eindeutigkeit auf 32 Zufallsbits und setzt den Kanal nach ~77.000 Antworten dem Joux Forbidden Attack aus.

SchweregradHochCVSS 7.4CVSS-3.1-VektorAV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:NCWECWE-323 (Reusing a Nonce, Key Pair in Encryption)Produktfbeta ePA3-Service-OpenSourceBetroffene VersionenAlle Versionen vor 1.3.0 (vom initialen Commit `a61f91d` bis einschließlich 1.0.1)Behoben in1.3.0 (enthält Pull Request #10)GHSAGHSA-vmfm-3f7g-r9qg

Beschreibung

Der VAU-Client initialisiert zwei Counter bei VAUProtokoll.py:64-65: encryption_counter, der für den eigenen IV des Clients genutzt und in Zeile 399 inkrementiert wird, und request_counter, der im ausgehenden Nachrichten-Header genutzt und nirgends inkrementiert wird. Die gematik-Spezifikation A_24628-01 verlangt, dass der Client diesen Counter für jeden Request inkrementiert. Andreas Hallofs Upstream vau-protokoll (von dem fbetas Kryptografieschicht abgeleitet ist) enthält das Inkrement; der entsprechende fbeta-Codepfad nicht.

VAUProtokoll.py:64-65

self.encryption_counter = 0
self.request_counter = 0

View source →

VAUProtokoll.py:407 (Counter im ausgehenden Header)

header.extend(self.request_counter.to_bytes(8, "big"))

View source →

Der gematik-lib-vau-Server speichert den vom Client gelieferten Counter ohne Monotonie-Prüfung und verwendet ihn zur Konstruktion des Counter-Teils seines eigenen AES-GCM-IV (entgegen A_24631, das einen unabhängigen serverseitigen Counter verlangt). Mit dem auf 0 fixierten Client-Wert wird der Antwort-IV des Servers zu random(4) || 0x0000000000000000: 32 Bit Entropie, mit einer Geburtstags-Kollisionswahrscheinlichkeit von 50 % bei ~77.000 Nachrichten. Die korrespondierende lib-vau-Seite ist als gematik: AES-GCM-Nonce-Wiederverwendung in der VAU-Server-Verschlüsselung veröffentlicht.

Geburtstags-Kollisionswahrscheinlichkeit bei konstantem 64-Bit-Counter:

Kollisionswahrscheinlichkeit bei konstantem Counter

Nachrichten P(IV-Kollision)
100 < 0,01 %
1.000 0,01 %
10.000 1,16 %
50.000 25,23 %
77.163 50,00 %
100.000 68,55 %

AES-GCM bietet bei Nonce-Wiederverwendung keine Vertraulichkeits- oder Integritätsgarantien mehr. Der Joux Forbidden Attack (2006) erlaubt einem Angreifer, der zwei unter demselben Schlüssel und IV verschlüsselte Ciphertexte beobachtet, aus den beiden Authentifizierungs-Tags den GHASH-Authentifizierungsschlüssel H zu rekonstruieren und durch XOR der beiden Ciphertexte Klartext-Bytes zurückzugewinnen. Die inneren HTTP-Antworten auf dem VAU-Kanal haben eine hochgradig vorhersehbare Struktur (HTTP-Header, JSON-Felder, ortsfeste KVNR-Ziffern), sodass eine teilweise Klartext-Wiederherstellung ohne weitere Angreiferfähigkeit machbar ist.

Während eines Testlaufs beobachtete ein transparenter Proxy nur verschlüsselten Verkehr (kein MITM, keine Entschlüsselung) und wartete auf eine Geburtstags-Kollision auf dem 32-Bit-Zufallspräfix des IV. Nach 57.248 verschlüsselten Antworten teilten zwei Nachrichten denselben IV; alle 9 KVNR-Ziffern unterschieden sich zwischen den beiden Versicherten, und die Anzahl möglicher Ziffernpaare reduzierte den gemeinsamen Suchraum um den Faktor 60:

Passive Nonce-Kollision durch transparenten Proxy

11m43s | 55451 unique IVs | prob: 30.1%
COLLISION after 57248 encrypted responses.
Response A (#53331): IV = e0cc7a0e 00000000
Response B (#57247): IV = e0cc7a0e 00000000
Patient ID digits (bytes 188-196):
Pos 0: XOR=0x06 8 candidate pairs
Pos 1: XOR=0x07 8 candidate pairs
Pos 2: XOR=0x0b 4 candidate pairs
Pos 3: XOR=0x04 8 candidate pairs
Pos 4: XOR=0x07 8 candidate pairs
Pos 5: XOR=0x06 8 candidate pairs
Pos 6: XOR=0x0d 4 candidate pairs
Pos 7: XOR=0x02 8 candidate pairs
Pos 8: XOR=0x0d 4 candidate pairs
9/9 digits differ between the two patients.
Search space: 1,000,000,000 -> 16,777,216
Reduced by factor 60x from a single collision.

Eine zweite Kollision engt den gemeinsamen Kandidatenraum typischerweise auf eine eindeutige Wiederherstellung ein.

Auswirkung

  • Die innere VAU-Schicht schützt Medikationsdaten, Diagnoseberichte, Verordnungshistorien, KVNRs, Dokumenten-Reads und -Writes einer Betroffenen sowie die Autorisierungstransaktionen, die den Zugriff auf die Patientenakte steuern.
  • Eine passiv mithörende Angreiferin, die nur verschlüsselte VAU-Antworten auf dem Netzwerkpfad beobachtet, kann auf eine Geburtstags-IV-Kollision warten (~77.000 Antworten für 50 % Wahrscheinlichkeit, während eines Testlaufs bei ~57.000 beobachtet) und KVNR-Ziffern sowie weiteren vorhersehbaren Klartext aus dem XOR der beiden kollidierenden Ciphertexte rekonstruieren. Die Vorbedingung ist passive Netzbeobachtung; keine aktive Intervention ist nötig.
  • Eine Angreiferin, die zwei Ciphertexte unter demselben IV gewinnt, rekonstruiert mit dem Joux Forbidden Attack den GHASH-Authentifizierungsschlüssel H. Mit H fälscht die Angreiferin das GCM-Authentifizierungs-Tag für Ciphertexte unter jedem IV, für den eine Kollision beobachtet wurde, sodass Server-zu-Client-VAU-Nachrichten manipulierbar werden: durch das Einschleusen falscher Patientendaten oder gefälschter Autorisierungsantworten.
  • Wenn auch fbeta: TLS-Zertifikatsprüfung universell deaktiviert unmitigiert ist, entfällt durch die TLS-Terminierung die Vorbedingung der passiven Beobachtung und das systemweite AC sinkt auf L.

Abhilfe

Aktualisieren Sie fbeta ePA3-Service-OpenSource auf 1.3.0 oder höher. Der Fix inkrementiert request_counter bei jeder ausgehenden Nachricht und validiert die Monotonie des Antwort-Counters, um Replays zu verhindern. Dieselbe Wurzelursache existiert upstream im gematik-lib-vau-Server (der den Client-Counter ohne Monotonie-Prüfung speichert und als IV-Counter-Teil nutzt); siehe den gematik: AES-GCM-Nonce-Wiederverwendung in der VAU-Server-Verschlüsselung. Ein downstream-seitiger Fix, der stets einen frischen Counter sendet, entfernt den passiven Auslöser der serverseitigen Bedingung, schließt aber nicht die serverseitige Lücke gegen einen aktiven MITM, der auf der Relay-Ebene einen fixen Counter setzt.

Checkliste für Betreiber

  • Auf fbeta ePA3-Service-OpenSource 1.3.0 oder höher aktualisieren.

    Alle Versionen vor 1.3.0 sind betroffen. Der Fix liegt in Pull Request #10.

  • Das Inkrement im eigenen Build verifizieren.

    Ergänzen Sie in Ihrem Deployment der Bibliothek einen kurzen Integrationstest, der zwei aufeinanderfolgende ausgehende VAU-Nachrichten erfasst und prüft, dass sich das 8-Byte-request_counter-Feld im Header zwischen ihnen ändert. Die ursprüngliche Lücke manifestierte sich als einzelne fehlende Zeile im Verschlüsselungspfad; ein Integrations-Assert ist die billigste Versicherung gegen das Wiederauftauchen in einem Fork.

  • Monotonie des Antwort-Counters prüfen.

    Der Fix ergänzt zusätzlich eine Monotonie-Prüfung des Antwort-Counters. Falls Sie einen eigenen Client pflegen, ersetzen Sie jede Gleichheits-Prüfung auf dem Antwort-Counter durch response_counter > last_seen_response_counter, um Replays vergangener Server-Antworten zu verhindern.

  • Sitzungslänge als Sicherheitsparameter behandeln, bis der Fix ausgerollt ist.

    Bis das Inkrement in Ihrer Flotte greift, rotieren Sie VAU-Sitzungen deutlich unterhalb der 2^16-Nachrichten-Grenze. Die IV-Kollisionswahrscheinlichkeit übersteigt bereits bei rund 10.000 Antworten mit gleichem Counter die 1-Prozent-Schwelle; das ist Ihre operative Marge.

Bewertung im Detail

AV:NErreichbar von jeder Partei, die VAU-Antwortverkehr auf dem Netzwerkpfad zwischen DiGA-Backend und ePA-Aktensystem beobachten kann.AC:HErfordert das Sammeln in der Größenordnung von 2^16 bis 2^17 Server-Antworten unter dem fixen Client-Counter (~57k bis 77k empirisch) und die Joux'sche GHASH-Schlüsselrekonstruktion bei einer Kollision.PR:NKeine Credentials erforderlich; das passive Mitlesen verschlüsselten Verkehrs genügt, um die Vorbedingung auszulösen.UI:NKeine Interaktion eines zweiten Beteiligten erforderlich.S:UDie Auswirkung ist auf die kryptografischen Garantien des VAU-Kanals beschränkt.C:HKlartext-Wiederherstellung aus dem XOR kollidierender Ciphertexte; KVNR-Ziffern und weitere vorhersehbare Felder fallen aus einer einzigen Kollision.I:HDie GHASH-Schlüsselrekonstruktion ermöglicht die Fälschung authentisierter Server-zu-Client-VAU-Nachrichten, einschließlich des Einschleusens falscher Patientendaten oder gefälschter Autorisierungsantworten.A:NKeine Auswirkung auf die Verfügbarkeit.

Referenzen

So können wir helfen

Wer wir sind

Die Sicherheitsforscher hinter diesem Sicherheitshinweis.

Dr. Simon Weber Profile

Dr. rer. nat. Simon Weber

Senior Pentester & MedSec-Forscher

Ich evaluiere Ihr SaMD mit derselben branchenprägenden Sicherheitsexpertise, die ich dem BAK MV für die Überarbeitung des B3S-Standards beigetragen habe.

  • Promotion über Krankenhaus-Cybersicherheit
  • Kritische Schwachstellen in Krankenhaussystemen gefunden
  • Alumni der THB MedSec-Forschungsgruppe
  • gematik Security Hero
Volker Schönefeld Profile

Dipl.-Inf. Volker Schönefeld

Senior Application Security Expert

Als ehemaliger CTO und Entwickler, der zum Pentester wurde, arbeite ich mit Ihrem Team zusammen, um Schwachstellen aufzudecken und Lösungen zu finden, die zu Ihrer Architektur passen.

  • 20+ Jahre als CTO, 50+ Mio. App-Downloads
  • Architektur und Absicherung großer IoT-Flotten
  • Certified Web Exploitation Specialist
  • gematik Security Hero

Penetrationstest gesucht?

Machine Spirits ist spezialisiert auf Sicherheitsbewertungen für Medizinprodukte und Gesundheits-IT. Von MDR-Penetrationstests bis C5-Cloud-Compliance helfen wir MedTech-Unternehmen, regulatorische Anforderungen zu erfüllen.