JWT Vulnerabilities (Json Web Tokens)
Last updated
Last updated
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Wenn du an einer Hacking-Karriere interessiert bist und das Unhackbare hacken möchtest - wir stellen ein! (fließend Polnisch in Wort und Schrift erforderlich).
Ein Teil dieses Beitrags basiert auf dem großartigen Beitrag: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology Autor des großartigen Tools zum Pentesting von JWTs https://github.com/ticarpi/jwt_tool
Führe jwt_tool im Modus All Tests!
aus und warte auf grüne Zeilen.
Wenn Sie Glück haben, findet das Tool einen Fall, in dem die Webanwendung das JWT falsch überprüft:
Dann können Sie die Anfrage in Ihrem Proxy suchen oder das verwendete JWT für diese Anfrage mit jwt_ tool dumpen:
You can also use the Burp Extension SignSaboteur um JWT-Angriffe von Burp auszuführen.
Sie können einfach die Daten manipulieren und die Signatur unverändert lassen und überprüfen, ob der Server die Signatur überprüft. Versuchen Sie beispielsweise, Ihren Benutzernamen in "admin" zu ändern.
Um zu überprüfen, ob die Signatur eines JWT verifiziert wird:
Eine Fehlermeldung deutet auf eine laufende Überprüfung hin; sensible Details in ausführlichen Fehlern sollten überprüft werden.
Eine Änderung der zurückgegebenen Seite deutet ebenfalls auf eine Überprüfung hin.
Keine Änderung deutet auf keine Überprüfung hin; dies ist der Zeitpunkt, um mit der Manipulation der Payload-Ansprüche zu experimentieren.
Es ist wichtig zu bestimmen, ob das Token serverseitig oder clientseitig generiert wurde, indem die Anfragehistorie des Proxys untersucht wird.
Tokens, die zuerst von der Client-Seite gesehen werden, deuten darauf hin, dass der Schlüssel möglicherweise im clientseitigen Code exponiert ist, was eine weitere Untersuchung erforderlich macht.
Tokens, die serverseitig stammen, deuten auf einen sicheren Prozess hin.
Überprüfen Sie, ob das Token länger als 24 Stunden hält... vielleicht läuft es nie ab. Wenn es ein "exp"-Feld gibt, überprüfen Sie, ob der Server es korrekt behandelt.
Setzen Sie den verwendeten Algorithmus auf "None" und entfernen Sie den Signaturteil.
Verwenden Sie die Burp-Erweiterung "JSON Web Token", um diese Schwachstelle auszuprobieren und verschiedene Werte innerhalb des JWT zu ändern (senden Sie die Anfrage an Repeater und im Tab "JSON Web Token" können Sie die Werte des Tokens ändern. Sie können auch auswählen, den Wert des "Alg"-Feldes auf "None" zu setzen).
Der Algorithmus HS256 verwendet den geheimen Schlüssel, um jede Nachricht zu signieren und zu verifizieren. Der Algorithmus RS256 verwendet den privaten Schlüssel, um die Nachricht zu signieren, und verwendet den öffentlichen Schlüssel zur Authentifizierung.
Wenn Sie den Algorithmus von RS256 auf HS256 ändern, verwendet der Backend-Code den öffentlichen Schlüssel als geheimen Schlüssel und verwendet dann den HS256-Algorithmus, um die Signatur zu verifizieren.
Dann könnten wir unter Verwendung des öffentlichen Schlüssels und der Änderung von RS256 auf HS256 eine gültige Signatur erstellen. Sie können das Zertifikat des Webservers abrufen, indem Sie dies ausführen:
Ein Angreifer bettet einen neuen Schlüssel in den Header des Tokens ein, und der Server verwendet diesen neuen Schlüssel zur Überprüfung der Signatur (CVE-2018-0114).
Dies kann mit der "JSON Web Tokens" Burp-Erweiterung durchgeführt werden. (Senden Sie die Anfrage an den Repeater, wählen Sie im Tab JSON Web Token "CVE-2018-0114" aus und senden Sie die Anfrage).
Die Anweisungen beschreiben eine Methode zur Bewertung der Sicherheit von JWT-Token, insbesondere von solchen, die einen "jku"-Headeranspruch verwenden. Dieser Anspruch sollte auf eine JWKS (JSON Web Key Set)-Datei verweisen, die den öffentlichen Schlüssel enthält, der für die Überprüfung des Tokens erforderlich ist.
Bewertung von Tokens mit "jku"-Header:
Überprüfen Sie die URL des "jku"-Anspruchs, um sicherzustellen, dass sie zur entsprechenden JWKS-Datei führt.
Ändern Sie den "jku"-Wert des Tokens, um auf einen kontrollierten Webdienst zu verweisen, der die Beobachtung des Datenverkehrs ermöglicht.
Überwachung der HTTP-Interaktion:
Die Beobachtung von HTTP-Anfragen an Ihre angegebene URL zeigt die Versuche des Servers an, Schlüssel von Ihrem bereitgestellten Link abzurufen.
Bei der Verwendung von jwt_tool
für diesen Prozess ist es wichtig, die Datei jwtconf.ini
mit Ihrem persönlichen JWKS-Standort zu aktualisieren, um die Tests zu erleichtern.
Befehl für jwt_tool
:
Führen Sie den folgenden Befehl aus, um das Szenario mit jwt_tool
zu simulieren:
Ein optionaler Headeranspruch, bekannt als kid
, wird verwendet, um einen bestimmten Schlüssel zu identifizieren, was in Umgebungen, in denen mehrere Schlüssel zur Überprüfung der Token-Signatur vorhanden sind, besonders wichtig wird. Dieser Anspruch hilft bei der Auswahl des geeigneten Schlüssels zur Überprüfung der Signatur eines Tokens.
Wenn der kid
-Anspruch im Header vorhanden ist, wird empfohlen, das Webverzeichnis nach der entsprechenden Datei oder deren Variationen zu durchsuchen. Wenn beispielsweise "kid":"key/12345"
angegeben ist, sollten die Dateien /key/12345 und /key/12345.pem im Web-Stammverzeichnis gesucht werden.
Der kid
-Anspruch könnte auch ausgenutzt werden, um durch das Dateisystem zu navigieren, was möglicherweise die Auswahl einer beliebigen Datei ermöglicht. Es ist möglich, die Konnektivität zu testen oder Server-Side Request Forgery (SSRF)-Angriffe durchzuführen, indem der kid
-Wert geändert wird, um gezielt bestimmte Dateien oder Dienste anzusprechen. Das Manipulieren des JWT, um den kid
-Wert zu ändern und gleichzeitig die ursprüngliche Signatur beizubehalten, kann mit dem -T
-Flag in jwt_tool erreicht werden, wie unten gezeigt:
Durch das Anvisieren von Dateien mit vorhersehbarem Inhalt ist es möglich, ein gültiges JWT zu fälschen. Zum Beispiel kann die Datei /proc/sys/kernel/randomize_va_space
in Linux-Systemen, die bekanntlich den Wert 2 enthält, im kid
-Parameter mit 2 als symmetrischem Passwort für die JWT-Generierung verwendet werden.
Wenn der Inhalt des kid
-Anspruchs verwendet wird, um ein Passwort aus einer Datenbank abzurufen, könnte eine SQL-Injection ermöglicht werden, indem die kid
-Nutzlast modifiziert wird. Ein Beispiel für eine Nutzlast, die SQL-Injection verwendet, um den JWT-Signierungsprozess zu ändern, ist:
non-existent-index' UNION SELECT 'ATTACKER';-- -
Diese Änderung zwingt die Verwendung eines bekannten geheimen Schlüssels, ATTACKER
, für die JWT-Signierung.
Ein Szenario, in dem der kid
-Parameter einen Dateipfad angibt, der innerhalb eines Befehlsausführungskontexts verwendet wird, könnte zu Remote Code Execution (RCE)-Schwachstellen führen. Durch das Injizieren von Befehlen in den kid
-Parameter ist es möglich, private Schlüssel offenzulegen. Ein Beispiel für eine Nutzlast zur Erreichung von RCE und Schlüsseloffenlegung ist:
/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&
jku steht für JWK Set URL. Wenn das Token einen “jku” Header-Anspruch verwendet, dann prüfen Sie die bereitgestellte URL. Diese sollte auf eine URL verweisen, die die JWKS-Datei enthält, die den öffentlichen Schlüssel zur Überprüfung des Tokens enthält. Manipulieren Sie das Token, um den jku-Wert auf einen Webdienst zu verweisen, dessen Verkehr Sie überwachen können.
Zuerst müssen Sie ein neues Zertifikat mit neuen privaten und öffentlichen Schlüsseln erstellen.
Dann können Sie beispielsweise jwt.io verwenden, um das neue JWT mit den erstellten öffentlichen und privaten Schlüsseln zu erstellen und den Parameter jku auf das erstellte Zertifikat zu verweisen. Um ein gültiges jku-Zertifikat zu erstellen, können Sie das ursprüngliche herunterladen und die benötigten Parameter ändern.
Sie können die Parameter "e" und "n" aus einem öffentlichen Zertifikat mit folgendem Befehl erhalten:
X.509-URL. Eine URI, die auf eine Menge von X.509 (einem Zertifikatsformatstandard) öffentlichen Zertifikaten verweist, die im PEM-Format codiert sind. Das erste Zertifikat in der Menge muss dasjenige sein, das verwendet wurde, um dieses JWT zu signieren. Die nachfolgenden Zertifikate signieren jeweils das vorherige, wodurch die Zertifikatskette vervollständigt wird. X.509 ist in RFC 52807 definiert. Transportsicherheit ist erforderlich, um die Zertifikate zu übertragen.
Versuchen Sie, diesen Header in eine URL unter Ihrer Kontrolle zu ändern und überprüfen Sie, ob eine Anfrage empfangen wird. In diesem Fall könnten Sie das JWT manipulieren.
Um ein neues Token mit einem von Ihnen kontrollierten Zertifikat zu fälschen, müssen Sie das Zertifikat erstellen und die öffentlichen und privaten Schlüssel extrahieren:
Dann können Sie beispielsweise jwt.io verwenden, um das neue JWT mit den erstellten öffentlichen und privaten Schlüsseln zu erstellen und den Parameter x5u auf das erstellte Zertifikat .crt zu verweisen.
Sie können auch beide dieser Schwachstellen für SSRFs ausnutzen.
Dieser Parameter kann das Zertifikat in base64 enthalten:
Wenn der Angreifer ein selbstsigniertes Zertifikat generiert und ein gefälschtes Token mit dem entsprechenden privaten Schlüssel erstellt und den Wert des "x5c"-Parameters durch das neu generierte Zertifikat ersetzt und die anderen Parameter, nämlich n, e und x5t, ändert, würde das gefälschte Token im Wesentlichen vom Server akzeptiert werden.
Wenn das JWT einen öffentlichen Schlüssel eingebettet hat, wie im folgenden Szenario:
Mit dem folgenden nodejs-Skript ist es möglich, einen öffentlichen Schlüssel aus diesen Daten zu generieren:
Es ist möglich, einen neuen privaten/öffentlichen Schlüssel zu generieren, den neuen öffentlichen Schlüssel im Token einzubetten und ihn zu verwenden, um eine neue Signatur zu generieren:
Sie können das "n" und "e" mit diesem nodejs-Skript erhalten:
Finally, using the public and private key and the new "n" and "e" values you can use jwt.io to forge a new valid JWT with any information.
Wenn einige Anwendungen ES256 verwenden und denselben Nonce zur Generierung von zwei JWTs verwenden, kann der private Schlüssel wiederhergestellt werden.
Hier ist ein Beispiel: ECDSA: Offenlegung des privaten Schlüssels, wenn derselbe Nonce verwendet wird (mit SECP256k1)
Der JTI (JWT ID) Anspruch bietet einen eindeutigen Identifikator für ein JWT-Token. Er kann verwendet werden, um zu verhindern, dass das Token wiederverwendet wird. Stellen Sie sich jedoch eine Situation vor, in der die maximale Länge der ID 4 beträgt (0001-9999). Die Anfragen 0001 und 10001 werden dieselbe ID verwenden. Wenn das Backend die ID bei jeder Anfrage inkrementiert, könnten Sie dies ausnutzen, um eine Anfrage wiederzugeben (wobei 10000 Anfragen zwischen jeder erfolgreichen Wiederholung gesendet werden müssen).
Cross-Service Relay Angriffe
Es wurde beobachtet, dass einige Webanwendungen auf einen vertrauenswürdigen JWT-Dienst für die Generierung und Verwaltung ihrer Tokens angewiesen sind. Es wurden Fälle dokumentiert, in denen ein Token, das für einen Client vom JWT-Dienst generiert wurde, von einem anderen Client desselben JWT-Dienstes akzeptiert wurde. Wenn die Ausgabe oder Erneuerung eines JWT über einen Drittanbieterdienst beobachtet wird, sollte die Möglichkeit untersucht werden, sich mit demselben Benutzernamen/E-Mail auf einem anderen Client dieses Dienstes anzumelden. Anschließend sollte versucht werden, das erhaltene Token in einer Anfrage an das Ziel wiederzugeben, um zu sehen, ob es akzeptiert wird.
Ein kritisches Problem könnte durch die Akzeptanz Ihres Tokens angezeigt werden, was möglicherweise das Spoofing eines beliebigen Benutzerkontos ermöglicht. Es sollte jedoch beachtet werden, dass möglicherweise eine Genehmigung für umfassendere Tests erforderlich ist, wenn Sie sich auf einer Drittanbieteranwendung anmelden, da dies in einen rechtlichen Graubereich fallen könnte.
Ablaufprüfung von Tokens
Das Ablaufdatum des Tokens wird mit dem "exp" Payload-Anspruch überprüft. Da JWTs oft ohne Sitzungsinformationen verwendet werden, ist eine sorgfältige Handhabung erforderlich. In vielen Fällen könnte das Erfassen und Wiedergeben eines anderen Benutzers JWT die Identitätsübernahme dieses Benutzers ermöglichen. Die JWT RFC empfiehlt, JWT-Wiederholungsangriffe zu mindern, indem der "exp"-Anspruch verwendet wird, um eine Ablaufzeit für das Token festzulegen. Darüber hinaus ist die Implementierung relevanter Prüfungen durch die Anwendung, um die Verarbeitung dieses Wertes und die Ablehnung abgelaufener Tokens sicherzustellen, entscheidend. Wenn das Token einen "exp"-Anspruch enthält und die Testzeitlimits dies zulassen, wird empfohlen, das Token zu speichern und es nach Ablauf der Zeit erneut wiederzugeben. Der Inhalt des Tokens, einschließlich der Zeitstempel-Analyse und der Ablaufprüfung (Zeitstempel in UTC), kann mit dem -R-Flag des jwt_tool gelesen werden.
Ein Sicherheitsrisiko könnte bestehen, wenn die Anwendung das Token weiterhin validiert, da dies implizieren könnte, dass das Token niemals ablaufen könnte.
If you are interested in hacking career and hack the unhackable - we are hiring! (fluent polish written and spoken required).
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)