paint-brush
Kritische Sicherheitslücke in Swedish BankID legt Benutzerdaten offenby@mastersplinter
506
506

Kritische Sicherheitslücke in Swedish BankID legt Benutzerdaten offen

mastersplinter10m2024/07/11
Read on Terminal Reader

Wenn ein Dienst BankID zur Authentifizierung seiner Benutzer verwendet, kommt es häufig vor, dass einige Sicherheitsfunktionen des Protokolls falsch implementiert werden. Dadurch sind sie der Sicherheitslücke Session Fixation CWE-384 ausgesetzt, die ein Angreifer nutzen kann, um die Sitzung eines Opfers auf diesem Dienst zu kapern. Je nachdem, wie viel Zugriff der Angreifer nach Ausnutzung dieser Sicherheitslücke hat, liegt der Schweregrad einer solchen Sicherheitslücke zwischen hoch und kritisch.
featured image - Kritische Sicherheitslücke in Swedish BankID legt Benutzerdaten offen
mastersplinter HackerNoon profile picture
0-item



Die schwedische BankID ist eine Form der digitalen Identifizierung, die von den meisten, wenn nicht allen schwedischen Einwohnern zur Authentifizierung bei verschiedenen Diensten verwendet wird, wie etwa: Internetanbietern, Online-Banking-Diensten, Wett-Websites und insbesondere Regierungswebsites.


Da ich selbst in Schweden lebe und die Hackermentalität mir ständig im Kopf herumschwirrt, kam ich zu dem Schluss, dass dies ein sehr interessantes Gebiet für die Sicherheitsforschung wäre.


In diesem Beitrag stelle ich eine neue Sicherheitslücke vor, die meiner Erfahrung nach bei den meisten schwedischen Dienstanbietern auftritt und auf eine unsichere Implementierung des Authentifizierungsprotokolls von BankID zurückzuführen ist.


Ich werde kurz darauf eingehen, wie ein solches Protokoll funktioniert, wie eine anfällige Konfiguration aussieht, wie man sie ausnutzt, wie man sie behebt und was diese Art von Angriffen schließlich für die allgemeine Implementierung von eIDs bedeutet.

Das BankID-Authentifizierungsprotokoll

BankID ist ein Dienst, der auf dem Gerät eines Benutzers installiert wird und den man erhält, indem man ihn bei einer schwedischen Bank anfordert, vorausgesetzt, man hat eine schwedische Persunnumer , eine persönliche Steuernummer. Die Anwendung wird auf dem Gerät des Benutzers installiert und mit seiner Steuernummer verknüpft, wodurch seine/ihre Identität im Wesentlichen an eine solche Anwendung gebunden wird. So funktionieren elektronische Identifikationssysteme oft: Ein staatlich autorisierter und vertrauenswürdiger Dritter gibt ein Stück Software heraus, das an eine bestimmte Person gebunden ist, und dann integrieren sich Dienste mit dem Anbieter dieses Stücks Software, um ihren Benutzern die Authentifizierung auf ihrer Plattform zu ermöglichen, ein gemeinsames Vertrauensmodell, das es Diensten ermöglicht, Personen einfach zu authentifizieren.


Bei BankID ist das nicht anders. Es bietet Dokumentation für solche Dienste, die von nun an als Relying Party (RP) bezeichnet werden, sodass sie ihren Authentifizierungsfluss problemlos in BankID integrieren können. https://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide/rp-introduktion .


Mit BankID werden zwei Hauptabläufe verwendet, um einen Benutzer zu authentifizieren:

  • Authentifizierung auf demselben Gerät

  • Authentifizieren auf einem anderen Gerät


Wir werden diese beiden bald noch einmal aufgreifen. Beide Abläufe beginnen jedoch damit, dass der RP eine Anfrage an die API von BankID sendet, um eine Authentifizierungsreihenfolge zu starten. In dieser Post-Anfrage muss der RP den Parameter endUserIp angeben, der die IP des Benutzers enthält, der versucht, sich anzumelden. Dies wird später im Bericht wichtig sein.


Der /auth API-Endpunkt antwortet ungefähr folgendermaßen:

 HTTP/1.1 200 OK Content-Type: application/json { "orderRef":"131daac9-16c6-4618-beb0-365768f37288", "autoStartToken":"7c40b5c9-fa74-49cf-b98c-bfe651f9a7c6", "qrStartToken":"67df3917-fa0d-44e5-b327-edcc928297f8", "qrStartSecret":"d28db9a7-4cde-429e-a983-359be676944c" }


  • orderRef ist eine Kennung, die der RP gegenüber dem /collect Endpunkt verwenden kann, um den Authentifizierungsstatus zu überprüfen und später die benötigten Benutzerinformationen von dieser Person abzurufen.
  • autoStartToken ist ein Token, das vom RP verwendet wird, um einen Deep Link zu erstellen, der beim Anklicken die BankID-App öffnet und den Benutzer auffordert, sich zu authentifizieren ( das ist wirklich wichtig ).

qrStartToken und qrStartSecret werden weiter unten behandelt, sind für die durchgeführte Sicherheitsforschung jedoch nicht unbedingt wichtig.


Zusätzlich zur IP des Benutzers kann ein RP weitere Parameter für die Authentifizierungsreihenfolge angeben, darunter Text, der in der BankID-Anwendung angezeigt werden soll, und Authentifizierungsanforderungen .


In diesem Beitrag konzentrieren wir uns unter anderem auf die sogenannten Zertifikatsrichtlinien , die es dem RP ermöglichen, BankID mitzuteilen, welchen der beiden Abläufe der Benutzer gewählt hat.

Authentifizierung auf demselben Gerät

Wenn ein Benutzer sich auf demselben Gerät mit BankID authentifizieren möchte, erstellt der RP mit dem autoStartToken einen Deep Link, der wie folgt aussieht: bankid:///?autostarttoken=7c40b5c9-fa74-49cf-b98c-bfe651f9a7c6&redirect=https://service.com/login . Dieser Deep Link wird dann vom Betriebssystem des Benutzers abgerufen und an die BankID-Anwendung übergeben.


Bei der Untersuchung dieses Ablaufs wurde eine Open-Redirect- Schwachstelle gefunden, da von Seiten von BankID keine Validierung des redirect erfolgt. Später werde ich darauf eingehen, warum dieser zusätzliche Fehler den Session-Hijacking-Angriff noch wirkungsvoller macht.


Authentifizierungsablauf von BankID auf demselben Gerät


Authentifizierung auf einem anderen Gerät

UI-Beispiel für BankID auf einem anderen Gerät


Wenn ein Benutzer sich für die Authentifizierung mit BankID auf einem anderen Gerät entscheidet, verwendet der RP qrStartToken und qrStartSecret , um einen dynamischen QR-Code zu generieren (indem er die Daten des nächsten Frames vom oben genannten /collect Endpunkt abruft), den der Benutzer mit seiner Mobile BankID-Anwendung scannen kann.


Authentifizierungsablauf von BankID auf einem anderen Gerät


Zertifikatsrichtlinien

Diese SOLLTEN vom RP bei der Einleitung eines Authentifizierungsauftrags angegeben werden. Sie ermöglichen es BankID, einen Authentifizierungsversuch abzulehnen, wenn der Ablauf nicht übereinstimmt, um Phishing vorzubeugen. Wenn der Benutzer beispielsweise „Authentifizierung auf demselben Gerät“ wählt, sollte der RP dies BankID mitteilen, damit die Anwendung die Authentifizierung ablehnen kann, wenn sie über eine Mobile BankID und/oder mithilfe des QR-Codes versucht wird.


Darüber hinaus kann der RP nach Abschluss der Authentifizierung die ipAddress abrufen, die zum Öffnen der BankID-Anwendung vom /collect API-Endpunkt verwendet wurde. Diese SOLLTE dann mit der IP-Adresse des Benutzers auf dem RP verglichen werden, falls er „Authentifizierung auf demselben Gerät“ gewählt hat.


Die Zertifikatsrichtlinien SOLLTEN zusammen mit der ipAddress verwendet werden, um sicherzustellen, dass der Authentifizierungsfluss nicht manipuliert werden kann.

Obwohl diese Sicherheitsmaßnahmen vorhanden sind, versäumt BankID es, deren Bedeutung hervorzuheben und setzt sie auch in der bereitgestellten Beispielimplementierung nicht korrekt um! https://github.com/BankID/SampleCode

Der Session-Fixation-Bug

Was passiert also, wenn dieses Protokoll nicht sicher implementiert wird?


Als ich den Deeplink bankid:/// zum ersten Mal sah, durchsuchte ich gerade meine Bewerbungsunterlagen für die Universität, auf die ich zugreifen kann, wenn ich mich mit BankID anmelde. Zuerst dachte ich: Was passiert, wenn ich diesen Deeplink an jemanden schicke? Also schickte ich ihn an einen Freund, der darauf klickte, und zu meiner Überraschung hatte ich, nachdem er BankID geöffnet hatte, alle seine Bewerbungen für die Universität vor mir!


Zu diesem Zeitpunkt habe ich begonnen, mich mit der API von BankID zu befassen, mein eigenes RP implementiert und all die Dinge gelernt, die ich gerade skizziert habe.


Nach einigen Wochen der Recherche entwickelte ich ein Skript, das das Deep Link Grabbing von bankid:/// für über 30 RPs automatisierte. Das Skript startete einen Webserver und erstellte einen Pfad für jeden Dienst. Wenn ein Benutzer den Link für einen bestimmten Dienst besuchte, holte das Skript einen neuen Link und leitete den Benutzer dorthin um. Dies führte dazu, dass das Gerät des Benutzers die BankID-App öffnete und bei der Authentifizierung ich anstelle des Benutzers authentifiziert wurde.


Ich konnte dies tun, weil:

  • RPs haben die Zertifikatsrichtlinien nicht an BankID gesendet, sodass ich einen Deep Link abrufen und an eine Mobile BankID-App weiterleiten konnte

  • RPs haben die IP-Adresse, die den Link anforderte, nicht mit der IP-Adresse verglichen, die die Authentifizierung abgeschlossen hatte

  • RPs stellten den Link bereit, auch wenn die Option „Auf einem anderen Gerät authentifizieren“ gewählt wurde


Was zur Session-Fixation-Sicherheitslücke führte.

Der Angriff

Angriffsdiagramm


Stellen wir uns einen anfälligen Dienst namens AmazingSevice AB vor. Dieser hat den BankID-Flow gemäß dem bereitgestellten Beispielcode implementiert und hostet diese Implementierung unter https://amazingservice.se/login/bankid .


Ein Bedrohungsakteur ist an den auf AmazingSevice AB gespeicherten Benutzerdaten interessiert und hat sein Opfer im Blick. Er müsste lediglich das Abgreifen des bankid:/// Links automatisieren, ihn auf seinem Server hosten und dann den Link an seinen bösartigen Server an seine Opfer senden. Nachdem er seine Phishing-Zustellungsart (SMS, E-Mail usw.) ausgewählt hat, wird er den Link in die Nachricht einbetten, die sich als AmazingSevice AB ausgibt und das Opfer auffordert, sich anzumelden.


Bei einer solchen Kontoübernahme ist Social Engineering kaum erforderlich, denn sobald das Opfer auf den Link klickt, wird es sofort aufgefordert, BankID zu öffnen. Es verlässt das „unbekannte Territorium“ der Website des Angreifers und gelangt zu einer viel vertrauteren Benutzeroberfläche, nämlich BankID. Darüber hinaus wird die Authentifizierungsanfrage, die das Opfer in der BankID-Anwendung sehen würde, von AmazingSevice AB angefordert, wodurch es unmöglich ist, betrügerisches Verhalten zu erkennen.


Sobald sich das Opfer authentifiziert hat, wird die Sitzung des Angreifers für das Konto des Opfers authentifiziert. Das Opfer kann weiter getäuscht werden, indem die in BankID vorhandene Open Redirect- Sicherheitslücke ausgenutzt wird. Dadurch kann der Angreifer den redirect als https://amazingservice.se/login/bankid angeben. Dies würde dazu führen, dass das Opfer auf die Website des legitimen Dienstes umgeleitet wird und einfach denkt, die Authentifizierung sei nicht erfolgreich gewesen.

Demo

Aus offensichtlichen Gründen konnte ich keines der Unternehmen verwenden, bei denen ich mich gemeldet habe. Stattdessen zeigt die Demo, dass der Demodienst von BankID hierfür anfällig ist!


In der rechten Ecke ist die Ansicht des Opfers zu sehen, das den Link erhält. Dies wird durch den Besuch der Website des Angreifers simuliert. Sobald das Opfer den Link besucht, öffnet der Server des Angreifers den Headless-Browser und extrahiert den Link bankid:/// , der dann an das Telefon des Opfers weitergeleitet wird. In der App von BankID ist „Test av BankID“ zu sehen, was der legitime Ursprung der Demo-Site von BankID ist. Darüber hinaus wird zu Beginn des Videos ein VPN eingeschaltet, um sicherzustellen, dass während der Authentifizierung keine IP-Adressprüfungen durchgeführt werden. Am Ende ist zu sehen, dass der Angreifer auf seinem Laptop als Opfer (Johan Johansson) angemeldet ist.

Der Aufprall

Der Session-Fixation-Bug führt zu einer 1-Klick-Kontoübernahme bei jeder Anwendung, die Swedish BankID als Authentifizierungsanbieter verwendet und Zertifikatsrichtlinien und ipAddress Adressprüfungen falsch (oder überhaupt nicht) implementiert hat. Dies ist sehr schwerwiegend, da die Dienste, die BankID zur Authentifizierung ihrer Benutzer verwenden, häufig Zugriff auf sehr vertrauliche Daten und Aktionen haben. Über 30 Anwendungen wurden als anfällig für diesen Angriff eingestuft. So viele wie möglich wurden kontaktiert, was zu 11 akzeptierten Bug-Bounty-Berichten auf den wichtigsten Plattformen führte.


Einer der Dienste, denen ich diese Sicherheitslücke gemeldet habe, konnte mich mit Schwedens nationalem CSIRT in Kontakt bringen, da das Problem weit verbreitet und schwerwiegend ist. Die Gespräche haben gerade erst begonnen, also folgen Sie mir auf Twitter (X) @m4st3rspl1nt3r, wenn Sie auf dem Laufenden bleiben möchten.

Sanierung

Wenn Sie nach einem Beispiel suchen, wie eine sichere BankID RP API-Implementierung aussieht, habe ich eines erstellt, das Sie entweder als Golang-Bibliothek verwenden oder anpassen und als Microservice bereitstellen können. Das finden Sie hier .

Antwort von BankID

Die meisten der betroffenen Dienste, insbesondere diejenigen mit BBPs und VDPs, reagierten recht empfänglich und schnell auf meinen Bericht. Die Antwort von BankID war jedoch etwas anders. In der einen E-Mail, die ich erhielt, nachdem ich sie mehrfach über verschiedene Kanäle kontaktiert hatte, erklärten sie, dass sie sich des Problems bewusst seien, aber der Meinung seien, dass man nicht viel dagegen tun könne, um die „einfache Integration“ für RPs aufrechtzuerhalten. Die geplante Abhilfe, die leider immer noch Änderungen auf der RP-Seite erfordert, wurde mir wie folgt mitgeteilt (ist aber aus irgendeinem Grund nirgendwo in ihrer Dokumentation zu finden):


Eine weitere Anforderung, die RP festlegen kann, ist das Risiko. Dadurch wird das akzeptable Risikoniveau für die Transaktion festgelegt. Wenn das Risiko der Transaktion höher als der erforderliche Grenzwert ist, wird die Transaktion blockiert. „NIEDRIG“ – nur Aufträge mit geringem Risiko akzeptieren. „MODERAT“ – Aufträge mit geringem und mittlerem Risiko akzeptieren. Wenn dies festgelegt ist, führen wir unter anderem die IP-Prüfung auf unserer Seite durch, wenn diese von RP bereitgestellt wird. Andere Risikoparameter, die risikoüberwacht werden, wenn sie bereitgestellt werden, sind „referingDomain“, „userAgent“ und „deviceIdentifier“.


Darüber hinaus gibt es einen Plan zur Behebung der Open Redirect-Sicherheitslücke.


Meine persönliche Meinung hierzu ist, dass Sie, wenn Sie einen so wichtigen und weit verbreiteten Authentifizierungsanbieter entwickeln und betreiben, der häufig zum Schutz sehr vertraulicher Benutzerinformationen verwendet wird, Ihre Sicherheitsmechanismen ordnungsgemäß dokumentieren sollten, damit RPs sie sicher integrieren können. Optionale Sicherheitsfunktionen sind völlig nutzlos. Wenn ein Entwickler Zeit sparen kann, indem er bestimmte Funktionen/Parameter nicht implementiert, wird das passieren, und wir können nicht die Schuld auf die RP-Seite schieben. BankID sollte sein Bestes tun, um so viele Betrugsschutz- und Sicherheitsfunktionen wie möglich auf ihre Seite zu verlagern, um die „einfache Integration“ aufrechtzuerhalten, aber auch sicherstellen, dass alle zusätzlichen Sicherheitsfunktionen, die die RP implementieren muss, ordnungsgemäß dokumentiert werden; Hinweis: „ Erforderlich“ , nicht „optional“.


Privates Unternehmen in öffentlicher Gefahr

Dieser Teil des Blogs stellt ausschließlich meine Meinung dar.


Für mich ist diese Sicherheitslücke ein Beispiel dafür, wie gefährlich es ist, einem privaten Unternehmen die vollständige Kontrolle über ein System zu überlassen, das für die Bevölkerung eines Landes von entscheidender Bedeutung ist. Der Grund, warum ich glaube, dass dies ernster ist als nur eine weitere Sicherheitslücke in einem Softwareunternehmen, ist, dass BankID von über 8,5 Millionen schwedischen Einwohnern verwendet wird. Es wird verwendet, um sich bei Ihrer Bank, Ihrem Versicherungsanbieter, Ihrem Stromanbieter und anderen sensiblen Plattformen anzumelden, die reale Konsequenzen haben.


Wenn jemand eine Kontoübernahme bei Facebook feststellt, gehen möglicherweise einige Bilder verloren. Wenn jemand eine Schwachstelle beim (oft privaten) eID-Anbieter Ihres Landes findet, können die Auswirkungen auf das Leben einer Person unvorstellbar sein.


Immer mehr europäische Länder führen eIDs ein und die EU plant, in den kommenden Jahren eine eigene EU-eID einzuführen (mehr dazu erfahren Sie hier ).


eIDs-Karte


Ich hoffe, dass die Regulierungsbehörden darauf drängen werden, dass die Entwicklung und Kontrolle der eID-Anbieter vollständig durch öffentliche Einrichtungen erfolgt, möglicherweise mit der Anforderung, dass solche Systeme Open Source sind und regelmäßig auf Sicherheitsmängel geprüft werden.


Wie können wir derart kritische Software in unserer Gesellschaft bedenkenlos akzeptieren, wenn sie von einem privaten Unternehmen entwickelt wird?

Weitere Forschung

Obwohl das Hauptthema dieses Blogbeitrags der Session-Fixation-Angriff auf BankID war, habe ich festgestellt, dass viele andere Authentifizierungs-/Identifizierungsanbieter alle mit demselben Fehler ausgestattet sind. Eine neue Schwachstellenklasse findet sich bei Anbietern, die die Verwendung eines anderen Geräts (häufig eines Mobiltelefons) erfordern, um den Authentifizierungsfluss abzuschließen.


Die Forschung ist noch nicht abgeschlossen und ich hoffe, bald weitere meiner Erkenntnisse sowie ein Tool veröffentlichen zu können, an dem ich gearbeitet habe und mit dem solche Schwachstellen automatisiert und ausgenutzt werden können. Bleiben Sie dran für mein nächstes Thema Session Fixation by Design – Albträume bei der geräteübergreifenden Authentifizierung


Bis dahin: Hacken Sie den Planeten!