• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Дневник белой шляпы [Часть 7]: Ничего [JWT]

grozdniyandy

White-Hat
Premium
Регистрация
11.08.2023
Сообщения
522
Реакции
677
Гарант сделки
2

ey...... (Вступление)

Я и снова другая статья. Для тех, кто не понял, "ey" - это то, как начинаются все JWT токены. Я всегда стараюсь делать креативные вступления. Эта статья предназначена для всех, кто заинтересован в изучении и "совершенствовании" знаний о JWT.

Предварительные требования: Желательно, немного разбираться в Linux и web
Уровень: Легкий

  1. Паутина
    • Дневник белой шляпы [Часть 1]: не DDoS
    • Дневник белой шляпы [Часть 2]: Интервью [GraphQL]
    • Дневник белой шляпы [Часть 3]: Cтажировкa [File Inclusion (Remote / Local)]
    • Дневник белой шляпы [Часть 5]: Удачная догадка [RCE - Проверка простейших CVE, найденных в PHP-приложениях]
    • Дневник белой шляпы [Часть 6]: Сообщение [Websockets + Tool]
  2. ОС
    • Дневник белой шляпы [Часть 4]: Знания [PrivEsc - Linux Capabilities] [Повышение привилегий - Возможности Linux]

Содержание
  1. История
  2. Что такое шифрование кодирование?
  3. Что такое BASE64? Как это работает? Зачем нам это нужно?
  4. Что такое JWT? Как это работает? Зачем нам это нужно?
  5. ВЕБ-аббревиатуры JSON (JWT/JWK...)
  6. Атаки на JWT
  7. Некоторые случаи

История

Я не силен в шифровании и прочем. Все началось с одного из выступлений в blackhat (https://www.youtube.com/watch?v=9gKMoCH0tms), где Брюс Шна́йер сказал, "Я пришел в компьютерную безопасность из криптографии, а криптография - это математика. И одна из вещей, которые я сказал, когда писал 'Прикладную криптографию', заключается в том, что нам нужно защищать себя не законами, а математикой. Что в некотором роде интересно, но на самом деле невероятно наивно. Потому что то, что я узнал за последние несколько лет, изучая уязвимости, заключается в том, что криптография, математика, не могут нас спасти. Большинство хороших атак, которые мы наблюдаем, не являются проблемами, которые могла бы устранить криптография, даже если бы она была применена.". Я не собираюсь высказывать свое собственное мнение по этому поводу, в основном потому, что у меня нет знаний в математике, поэтому я решил поинтересоваться, как криптография используется в кибербезопасности. Как мы знаем oн используется для обеспечения конфиденциальности и целостности данных.

Что такое шифрование кодирование?

Кодирование - это процесс перевода символов в специализированный формат для нужд обработки информации. Это просто процесс преобразования данных в другой формат.
Почему мы хотим кодировать данные?

Мы хотим закодировать данные, чтобы сделать их пригодными для хранения, обработки или передачи в другое приложение. Самым простым примером кодирования может быть кодировка URL.

URL (Uniform Resource Locator) - это адрес, который используется для доступа к ресурсам в Интернете. URL-адрес может содержать буквенно-цифровые символы (AZ, az, 0-9), дефис (-), подчеркивание (_), точку (.), тильду (~) без необходимости кодирования данных. Также есть некоторые зарезервированные символы, которые можно использовать в URL, нет необходимости кодировать их, если они используются по назначению, в противном случае они должны быть закодированы. Этими символами являются двоеточие ( : ), косая черта (/), вопросительный знак (?), aмперсанд (&), знак равенства (=), знак плюса (+), знак доллара ($), запятая (,), точка с запятой ( ; ).

Давайте представим, что у нас есть URL-адрес https://xss.pro/?user=andy&desc=animeNerd. В этом случае "&" показывает нам, что у нас есть 2 параметра, desc и user. Desc показывает описание пользователя. Теперь давайте предположим, что наше описание - "Аниме&Nerd", но мы знаем, что "&" используется между двумя разными параметрами, а "Nerd" - это не параметр, это значение. В этом случае нам придется закодировать его по URL-адресу. Подумайте, что наш URL-адрес выглядел бы следующим образом https://xss.pro/?user=andy&desc=Anime&Nerd. В данном случае мы относимся к "Nerd" как к параметру, а не к значению. Если мы хотим, чтобы это было значение, оно должно быть urlencoded, и наш url-адрес будет выглядеть следующим образом https://xss.pro/?user=andy&desc=Anime%26Nerd.

Зачем нам нужна кодировка URL?
По той же причине, по которой нам вообще нужна кодировка, для обработки данных. URL-адрес может содержать только определенный набор символов, поэтому нам нужно закодировать некоторые символы перед их передачей.

Что такое шифрование?
Существует множество определений по этому поводу. Для меня, в наиболее точном варианте, шифрование - это процесс преобразования необработанного текста в зашифрованный текст

Зачем нам нужно шифрование?
В основном это нужно нам для защиты информации. Простым примером может служить HTTPS-соединение, которое шифрует данные, которые мы отправляем и получаем. HTTPS использует (TLS)/SSL для шифрования связи.

В чем разница между шифрованием и кодированием?
На самом деле они служат разным целям. Шифрование используется для сокрытия "секретной" информации, a кодированиe для того чтобы сделать данные пригодными для обработки и тп.

Что такое BASE64? Как это работает? Зачем нам это нужно?

BASE64 - это алгоритм, который используется для кодирования двоичного кода в удобочитаемый текст. Самый простой пример можно привести при передаче изображений. BASE64 используется для кодирования необработанных изображений. Вы можете спросить, зачем нам это нужно. Это устраняет необходимость отдельных файлов для изображений. Данные изображения могут быть включены непосредственно в HTML-код в виде строки в кодировке BASE64. Вы можете увидеть пример на изображении ниже. Я использовал тег "img" с закодированным изображением.

Изображение [1]: Закодированное изображение

Изображение [1]: Закодированное изображение
Как это работает?
Я объясняю эту часть только потому, что полезно понять, как это работает. Мы делаем это для себя, ради наших знаний. Я могу допускать ошибки, я говорю об этом в каждой своей статье, вы вольны их исправлять.
Предположим, что мы должны в BASE64 закодировать слово "XSS". Мы должны преобразовать слово "XSS" в ASCII.

ASCII (American Standard Code for Information Interchange) - это система, которая присваивает символу уникальный номер.
Изображение [2]: Таблица ASCII [[ICODE]https://wikimedia.org[/ICODE]]

Изображение [2]: Таблица ASCII [https://wikimedia.org]
Код:
X:88
S:83
S:83

Двоичная система счисления - это система счисления, которая использует только две цифры, 0 и 1. В этом случае мы будем использовать 8-битный двоичный код, который представляет собой последовательность из 8 двоичных цифр (тоесть в 0 и 1). Наша работа на этом этапе заключается в преобразовании каждого значения ASCII в его 8-битное двоичное представление. У нас есть ASCII-значения букв "X" и "S". Мы будем использовать их для преобразования слова в двоичный код.

Давайте попробуем получить двоичное значение буквы X, разделив ее ASCII-значение на 2.

Код:
(88)/2   44   0    0
(44)/2   22   0    1
(22)/2   11   0    2
(11)/2   5    1    3
(5)/2    2    1    4
(2)/2    1    0    5
(1)/2    0    1    6

Ответ здесь 1011000

Давайте попробуем получить двоичное значение буквы S, разделив ее ASCII-значение на 2.

Код:
(83)/2   41   1    0
(41)/2   20   1    1
(20)/2   10   0    2
(10)/2   5    0    3
(5)/2    2    1    4
(2)/2    1    0    5
(1)/2    0    1    6

Ответ здесь 1010011
Эти значения являются 7-битными двоичными, мы должны сделать их 8-битными (чтобы равномерно делилась на 6, типо 8*3=24, а 24 делится на 6), просто добавьте 0 в начале X: 01011000 S: 01010011 .Давайте объединим все двоичные значения вместе, чтобы сформировать единую двоичную строку 010110000101001101010011. Поскольку BASE64 кодирует данные группами по 6 бит, нам может потребоваться дополнить двоичную строку нулями справа, чтобы она равномерно делилась на 6 (мы уже сделали это). Теперь мы должны разделить двоичную строку на 6-битные группы: 010110 000101 001101 010011. Время для преобразования каждого 6-разрядного двоичного кода в десятичный и нахождения соответствующих значений в соответствии с таблицей набора символов BASE64.
Вычисление:
Код:
(010110)₂ = (0 × 2⁵) + (1 × 2⁴) + (0 × 2³) + (1 × 2²) + (1 × 2¹) + (0 × 2⁰) = (22)₁₀
(000101)₂ = (0 × 2⁵) + (0 × 2⁴) + (0 × 2³) + (1 × 2²) + (0 × 2¹) + (1 × 2⁰) = (5)₁₀
(001101)₂ = (0 × 2⁵) + (0 × 2⁴) + (1 × 2³) + (1 × 2²) + (0 × 2¹) + (1 × 2⁰) = (13)₁₀
(010011)₂ = (0 × 2⁵) + (1 × 2⁴) + (0 × 2³) + (0 × 2²) + (1 × 2¹) + (1 × 2⁰) = (19)₁₀

Изображение [3]: Таблица BASE64 [[ICODE]https://www.woolha.com[/ICODE]]

Изображение [3]: Таблица BASE64 [https://www.woolha.com]
В результате получается:
Код:
22:W
5:F
13:N
19:T
WFNT - это BASE64 слова "XSS"

Очевидно, что это всего лишь простое объяснение. Этого должно быть достаточно только для того, чтобы у вас появилось понимание, или, как говoрил один из моих русскоязычных наставников, "vision".

Что такое JWT? Как это работает? Зачем нам это нужно?

Для этого мы должны сначала понять, что такое объект JSON. Для тех, кто работает с веб-сайтами, вы, вероятно, видели данные, отправляемые с типом содержимого application/json, где данные имеют вид {"key":"value"}. Объект JSON - это набор пар "key-value".

JWT (JSON Web Token) - это стандарт, который определяет способ передачи информации в виде объекта JSON. Он широко используется в системах аутентификации. Возможно, вы увидели заголовок "Authorization" (в основном Authorization: Bearer <token>), содержащий закодированный токен JWT в качестве значения.

Как это работает?

Чем меньше вы думаете об этом, тем легче это работает =)
Токены JWT состоят из 3 частей: заголовка, полезной нагрузки (payload) и подписи (signature).

Заголовок показывает нам используемый алгоритм подписи и токен (которым является JWT). Существует множество алгоритмов подписи, и для их понимания необходимы знания в области криптографии. В нашем случае мы решим лабораторные работы и разберемся в основах.
Пример:
Код:
{
  "alg": "HS256",
  "typ": "JWT"
}

Полезная нагрузка - это данные. Эти данные называются "заявлениями". Обычно в нем содержится информация о пользователе, дата истечения срока действия "exp", дата создания "iat" и т.д. Я расскажу подробнее об этом заголовке по мере того, как мы будем решать лабораторные задачи. На данный момент все, что вам нужно знать, это то, что он содержит информацию о пользователе и что "exp" показывает дату истечения срока действия JWT. После этой даты JWT недействителен и не должен функционировать.
Пример:
Код:
{
  "name": "Grozdniy Andy",
  "exp": "1693948820",
  "iat": 1693887608
}

Подпись - это зашифрованный заголовок+полезная нагрузка+секрет. Шифрование происходит с помощью алгоритма, используемого в заголовке.

Честно говоря, алгоритмов существует очень много. Чтобы глубоко понять весь этот процесс, вы должны очень хорошо разбираться в криптографии, что я не умею, криптография - сложная штука. Несмотря на то, что это не сильно повлияет на поиск уязвимостей, тем не менее понимание криптографии поможет в поиске новых возможных векторов атак. Так зачем же я написал всю эту чушь? Это мой способ пожелать вам "удачи".

Зачем нам это нужно?
Вы можете найти много информации по этому поводу. По моему собственному опыту, JWT используются в основном для аутентификации, и они хранят информацию пользователя в себе. Почему мы должны использовать его, когда у нас есть cookie? По самой простой причине JWT снижают нагрузку на сервер, поскольку данные хранятся в самом JWT, а не на сервере. Несмотря на то, что это правда, лично я считаю, что JWT был создан для того, чтобы мы могли находить уязвимости)

Помните, что если бы разработчики выполняли свою работу так, как от них требуется, не было бы такого понятия, как "пентест приложений". © GrozdniyAndy (слова друга. кредит мне)

ВЕБ-аббревиатуры JSON (JWT/JWK...)

Вы можете рассердиться, что, черт возьми, он не объяснил JWT на примерах, и бежит объяснять аббревиатуры. Это потому, что лучше ознакомиться с теоретической частью, прежде чем переходить к технической.

Что такое JOSE?
Мужское имя в переводе с испанского, эквивалентное.... Просто шучу. JOSE - JSON Object Signing and Encryption - это набор стандартов, которые определяют, как безопасно передавать данные JSON и манипулировать ими с использованием различных криптографических методов. JWT использует JOSE для шифрования.

Что такое JWS?
JWS - JSON Web Signature - является частью JOSE, которая занимается обеспечением целостности и подлинности данных JSON с помощью цифровых подписей (algorithm). Он также используется в заголовке JWT как "alg", что указывает на используемый алгоритм.

Что такое JWE?
JWE (JSON Web Encryption) - это способ надежно скрыть содержимое объекта JSON, чтобы только авторизованные стороны могли его прочитать. Итак, в чем разница между JWS и JWE. JWS использует подпись (signature), в то время как JWE использует электронное шифрование (encryotion). Если JWT зашифрован с помощью JWE, мы не сможем прочитать полезную нагрузку (payload), просто расшифровав JWT с помощью BASE64. Также стоит упомянуть, что JWT сначала подписывается (JWS) для обеспечения его целостности и происхождения, а затем весь JWT (включая подпись JWS) шифруется (JWE) для обеспечения конфиденциальности.

Что такое JWA?

JWA - JSON Web Algorithms - определяет набор криптографических алгоритмов, которые могут использоваться для таких задач, как подписание (алгоритмы - JWS) и шифрование данных (JWE) в формате JSON

Что такое JWK?
JWK - JSON Web Key - содержит информацию о типе ключа, его значении и дополнительных метаданных в формате JSON. Насколько я понимаю, он используется для подписи данных и проверки цифровых подписей. Они HE предназначены для шифрования и дешифрования данных.

Что такое JKU?
JKU - JSON Key URL -используется в веб-токенах JSON для указания URL-адреса, по которому можно найти набор веб-ключей JSON (JWK). Так что просто это URL-адрес, который содержит JWK.
Я в хорошем настроении, так что давайте сперва поставим Дуа Липу, а потом Ивана (Я не знаю почему, но мне нравится эта песня *с музыкой, да?*) и продолжим наши атаки.

Атаки на JWT

Непроверенная подпись
Мы знаем, что токены JWT подписываются с помощью подписи. Чтобы отредактировать полезную нагрузку, мы должны знать "секрет". В некоторых случаях мы можем редактировать полезную нагрузку (payload), не зная секрета, и это будет работать.

ПОЖАЛУЙСТА, всегда создавайте шпаргалку при решении лабораторных работ. Поверьте мне, это очень поможет вам при поиске конкретных уязвимостей в системах.

Лаборатория №1
: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature

У нас есть данные для входа (wiener:peter), пришло время запустить Burp Suite и взломать : )- (тире это типо борода)

Мы вошли в систему и получили JWT в качестве session cookie. Первое, что пришло мне в голову, это "Почему они используют это как сессию? Хранят ли они эти данные?". Ребята, я не знаю об этом, это пришло к нам от умов, которые создали PUT и вместо этого используют POST.


Изображение [4]: Вход

Изображение [4]: Вход
Как мы уже говорили ранее, JWT состоит из 3 частей, мы можем использовать веб-сайт jwt.io чтобы проанализировать наш токен JWT. Первая часть - это заголовок, вторая часть - полезная нагрузка, а третья - подпись. Если мы попытаемся отредактировать нашу полезную нагрузку в jwt.io само по себе это не сработает, потому что у нас нет секретного ключа. В любом случае полезная нагрузка - это просто данные, закодированные в BASE64, мы можем их просто декодировать.


Изображение [5]: Проверка токена JWT

Изображение [5]: Проверка токена JWT




Изображение [6]: Декодирование полезной нагрузки (payload)

Изображение [6]: Декодирование полезной нагрузки (payload)


"iss" означает "issuer", это "название" системы, которая выдала нам токен JWT. "Exp" показывает дату истечения срока действия, как вы знаете, "sub" означает "subject", он может содержать идентификатор пользователя. В нашем случае он содержит имя пользователя. Что ж, мы можем просто отредактировать это и написать "administrator". Обычно редактирование и замена исходной полезной нагрузкой не сработают, потому что должна быть проверка подписи. В нашем случае это сработает, потому что нет проверки подписи. Я имею в виду, что обычно на веб-сайте, если у нас есть токен JWT. Мы можем декодировать полезную нагрузку с помощью BASE64, отредактировать ее так, как мы хотим, и заменить текущей полезной нагрузкой "BASE64". Но это не сработает.

Изображение [7]: Редактирование полезной нагрузки (payload)

Изображение [7]: Редактирование полезной нагрузки (payload)


Мы заменили наше имя пользователя на administrator.


Изображение [8]: Редактирование полезной нагрузки (payload)

Изображение [8]: Редактирование полезной нагрузки (payload)

Мы заменили текущую полезную нагрузку на отредактированную и изменили id=wiener на id=administrator. Теперь мы успешно вошли в систему как администратор. Я уверен, что вы сможете решить дальше удалив пользователя "carlos".

Алгоритм "none"
Представьте, что к полезной нагрузке JWT не была применена цифровая подпись или криптографическая защита. В этом случае мы можем отправить JWT без какой-либо подписи, он будет содержать просто заголовок и полезную нагрузку.

Почему это вообще должно сработать?
Первый случай - это когда JWT не имеет подписи и алгоритма, и система может принять его как действительный (valid). Во втором случае системы могут принять его, но по-прежнему обрабатывать так, будто оно имеет подпись. В первом случае они просто принимают его как есть, во втором случае они принимают это так, как будто оно имеет подпись.

Я собираюсь сделать это вручную, я предпочитаю, чтобы вы тоже делали, как я. Поскольку мы снова (возможно) будем писать простой инструмент, полезно понять, как он работает. Другие атаки более запутанны, чем эта.

Лаборатория №2: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-flawed-signature-verification

В этом случае мы должны вручную декодировать первую и вторую части токена JWT.


Изображение [9]: Вход

Изображение [9]: Вход


Изображение [10]: Проверка токена JWT

Изображение [10]: Проверка токена JWT



Изображение [11]: Декодирование первой и второй части (header+payload)

Изображение [11]: Декодирование первой и второй части (header+payload)

Давайте отредактируем первую часть нашего JWT и заменим название алгоритма на "none".


Изображение [12]: Редактирование заголовка

Изображение [12]: Редактирование заголовка

Как вы видите, в конце закодированных данных есть символ = . Мы должны просто удалить его. Почему мы не можем использовать "="? Потому что JWT разработан для обеспечения безопасности URL-адресов и часто используется в контекстах, где символы типа "=" могут вызывать проблемы с URL-адресами или передачей данных. Как вы знаете из приведенного выше, когда я писал о кодировке URL, знак равенства находится между параметром и значением, поэтому это может вызвать путаницу.

1694008052631.png

Изображение [13]: Редактирование полезной нагрузки

Я отредактировал полезную нагрузку, как делал это в предыдущей лаборатории.

Изображение [14]: Ввод нового JWT.

Изображение [14]: Ввод нового JWT.​

Я объединил закодированную версию заголовка и полезную нагрузку. Добавил точку после каждого из них и отправил запрос. В качестве ответа мы теперь являемся администраторами.

BruteForce ключа
Кое-что я узнаю, пока пишу статью, кое-что я уже знаю и сохранил в своей шпаргалке. Я предпочитаю, чтобы вы сделали то же самое. Я протестировал инструменты JWT, и лучшим из них для bruteforce является JWT Cracker и JWTCat.

Если вы используете Linux, вы можете сделать следующее:
Bash:
git clone https://github.com/brendan-rius/c-jwt-cracker.git
sudo apt update
sudo apt install libssl-dev
sudo make
sudo cp jwtcrack /usr/bin/jwtcrack

Bash:
sudo apt update
sudo apt install python3.11-venv
git clone https://github.com/AresS31/jwtcat
cd jwtcat
python -m venv env
python -m pip install -r requirements.txt

Разница между ними в том, что JWT Cracker хорош для брутфорса X символов, предоставляя алфавит и длину, в то время как JWTCat делает брутфорс с готовым списком слов.

Я буду использовать https://raw.githubusercontent.com/wallarm/jwt-secrets/master/jwt.secrets.list этот список для брутфорса.

Bash:
python3 jwtcat.py wordlist -w jwt.secrets.list <тут токен>

Лаборатория №3: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-weak-signing-key

В этой лаборатории мы должны брутфорсить и попытаться получить секретный ключ. Сначала мы входим в систему как обычно и получаем наш JWT.

Изображение [15]: Вход

Изображение [15]: Вход

Вы уже должны были установить инструменты и список для брутфорса. Пришло время получить секретный ключ при помощи брутфорса.

Изображение [16]: JWTCat

Изображение [16]: JWTCat

Мы получили секретный ключ, теперь мы можем отредактировать полезную нагрузку и заменить имя пользователя на administrator.

Изображение [17]: Редактирование JWT

Изображение [17]: Редактирование JWT


Мы можем использовать новый токен JWT и быть администраторами.

Изображение [18]: Становление администратором

Изображение [18]: Становление администратором


Инъекция заголовка JWK (JWK Header Injection)
Цель этой лабораторной работы - отредактировать JWT, добавить заголовок JWK и подписать нашей собственной подписью. На самом деле мы можем сами сгенерировать заголовок JWK, если захотим. Давайте сначала войдем в систему

Лаборатория №4: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-weak-signing-key

Я решу эту задачу по-своему. Зачем я нужен, если мы собираемся копировать-вставлять ответы из portswigger, верно?

Изображение [19]: Вход

Изображение [19]: Вход


Изображение [20]: Анализ JWT

Изображение [20]: Анализ JWT

Когда мы анализируем наш токен JWT, мы видим, что он зашифрован с помощью открытого и закрытого ключей. Также обратите внимание на наш "kid". Наша работа здесь заключается в создании JWK, мы можем сделать это с помощью https://mkjwk.org. Мы хотим использовать подпись как RS256 и использовать "kid" в качестве ключа, а также поставить "yes" в "Show X.509".

Изображение [21]: Генерирование JWK

Изображение [21]: Генерирование JWK

После создания нашего собственного JWK мы должны заменить значения в редакторе JWT и сгенерировать новый JWT. Замените открытый и закрытый ключи на те, которые мы сгенерировали, замените имя пользователя на "administrator" и замените заголовок таким образом, как я это сделал.

Изображение [22]: Обновление JWT

Изображение [22]: Обновление JWT
Пришло время заменить JWT на тот, который мы сгенерировали.


Изображение [23]: Решение лаборатории

Изображение [23]: Решение лаборатории
Инъекция заголовка JKU (JKU Header Injection)
На самом деле это похоже на предыдущую атаку. Единственное отличие заключается в том, что теперь ключи будут храниться по определенному URL-адресу.

Лаборатория №5: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jku-header-injection
Мы входим в систему как обычно и получаем наш JWT. Уже похоже на рутинную работу whitehat 😅



1694037978671.png

Изображение [24]: Вход

Мы видим, что этот токен JWT такой же, как и предыдущий.

Изображение [25]: Анализ JWT

Изображение [25]: Анализ JWT

Итак, пришло время взять "kid" из нашего токена JWT и использовать его для генерации JWK с открытым и закрытым ключeм.

1694038000446.png

Изображение [26]: Генерирование JWK

Теперь у нас есть JWK, мы должны добавить наши данные JWK в качестве тела на наш exploit-сервер и использовать URL explooit-сервера как JKU. Таким образом, наш JKU содержит веб-ключи JSON

Изображение [27]: Добавление ключей на наш сервер

Изображение [27]: Добавление ключей на наш сервер

Все, что нам теперь нужно сделать, это заменить открытый и закрытый ключи сгенерированными и добавить заголовок "jku" с URL нашего exploit-сервера.

1694038019925.png

Изображение [28]: Обновление JWT




Изображение [29]: Гыотово родня

Изображение [29]: Гыотово родня
Обход пути в заагловке "kid" (Kid Header Path Traversal)
Я чувствую, что скоро стану учителем литературы, преподающим новую infosec лексику. Я знаю, что уязвимости звучат странно по-русски, возможно, это потому, что я не являюсь носителем языка.

Что такое заголовок "kid"?
kid - Key ID - нужен для того чтобы помочь в выборе ключа, когда доступно несколько ключей для проверки JWT. Думайте об этом как об идентификаторе, который показывает, какой ключ используется для подписи.

Лаборатория №6: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-kid-header-path-traversal

Я решу эту лабораторную работу с помощью расширения BurpSuite, до сих пор мы им не пользовались, в этой лаборатории я не смог найти альтернативного способа.



Изображение [30]: Загрузка расширения

Изображение [30]: Загрузка расширения





Изображение [31]: Вход

Изображение [31]: Вход
Хорошо, давайте попробуем зайти в профиль администратора. Очевидно, это перенаправит нас на вход в систему, потому что мы не являемся администраторами. В этом случае давайте перехватим (intercept) трафик.


Изображение [32]: Перехват трафика

Изображение [32]: Перехват трафика

Ладно, нам лучше подождать здесь. Давайте перейдем к нашему расширению и сгенерируем новый симметричный ключ.

Изображение [33]: Генерируем новый симметричный ключ

Изображение [33]: Генерируем новый симметричный ключ

Здесь возникает вопрос, что такое AA= и почему мы его использовали? AA= - это нулевой байт закодированный в base64, что означает, что это ничто. Мы просто ничего не используем в качестве ключа. Мы делаем это, потому что мы не можем оставить ключ пустым, поэтому вместо него мы используем нулевой байт.


1694042183374.png

Изображение [33]: Генерируем новый JWT

Почему мы использовали ../? Почему это вообще работает? Меня это тоже смутило, лично я думаю, что "kid" здесь указывает на конкретный файл, и наша работа состоит в том, чтобы указать его на /dev /null, что тоже ничего не значит. На самом деле /dev/null - это черная дыра, потому что любые отправленные туда данные исчезают. Я видел более странные случаи, чем этот, есть лаборатории, где мы можем выполнить command injection, добавив "&&" и другую команду. Но я не хочу путать это с чем-то другим. Все эти случаи возможны в зависимости от ситуации, даже если некоторые из них звучат абсурдно. В любом случае, не стесняйтесь задавать вопросы, хотя я чувствую себя учителем, когда пишу статью, я такой же студент, как и все мы.


Изображение [34]: Хакнули

Изображение [34]: Хакнули

Это все лаборатории, которые могут "подтолкнуть" вас вперед. Домашнее задание:
Код:
https://portswigger.net/web-security/jwt/algorithm-confusion/lab-jwt-authentication-bypass-via-algorithm-confusion
https://portswigger.net/web-security/jwt/algorithm-confusion/lab-jwt-authentication-bypass-via-algorithm-confusion-with-no-exposed-key

Вы можете подумать, что я решил простые задачи и оставил вам сложные. Вы правы, ученик должен превзойти учителя.
 
Последнее редактирование:
Некоторые случаи

Прежде чем продолжить, я хочу поговорить с вами о некоторых странных атаках.

Первый - подделка заголовков NBF. Представьте себе случай, когда компания платит первому, кто зарегистрируется на их новом демонстрационном веб-сайте. Чтобы проверить первого зарегистрированного пользователя, они используют токены JWT. Каждый токен имеет "NBF", что означает "Not Before". Это означает, что до этого времени JWT никоим образом не может быть использован. Что мы можем сделать в этом случае? Возможны 2 варианта: либо вы редактируете заголовок "nbf" и испытываете свою удачу, либо взламываете сервер и меняете там дату. Не судите меня, это основано на одной из лабораторий, в которых я работал раньше. (как указано в моей шпаргалке)

Второй - CVE-2016-10555. Итак, дело в том, что если у нас есть RS256 и открытый ключ, то мы можем сгенерировать токен JWT в кодировке HS526, который будет работать, так что нам не понадобится никакая дополнительная подпись. Обычно в RS256 нам нужны открытый и закрытый ключи, но в нашем случае мы можем использовать только открытый ключ для генерации HS256, и это будет работать. Скрипт на Python:
Python:
import jwt
key = open("/<EDIT THIS>.crt").read()
encoded = jwt.encode(
{
"id": 1,
 "iat": <EDIT THIS>,
 "exp": <EDIT THIS>
},
    key,
algorithm='HS256')
print "Forged Token: %s" % (encoded)

Третий - Атака на перекрестную ретрансляцию (Cross Service Relay Attack) - Представьте, что есть 2 поддомена одного и того же веб-сайта, каждый из них генерирует разные JWT токены, вы можете зарегистрироваться в одном из них с именем пользователя, которое ранее использовалось первым поддоменом. Предположим, что в первом поддомене есть пользователь “xss”, теперь мы должны зарегистрироваться во втором поддомене, и он сгенерирует токен jwt в соответствии с именем пользователя “xss”, и если вы можете использовать этот токен на первом веб-сайте, это означает, что вы только что осуществили захват учетной записи пользователя "xss" на первом поддомене. В принципе, мы можем захватить учетную запись любого зарегистрированного пользователя в первом поддомене, зарегистрировав пользователя с этим именем пользователя во втором поддомене и используя этот токен JWT. К сожалению, это только теория, и я не могу предоставить какую-либо лабораторию для объяснения этого случая, тем не менее нужно знать, что этот случай возможен.

Честно говоря, это всего лишь 1 случай, который произошел со мной. Это не уязвимость, как они говорят, но все же это очень странно. К тому времени у меня не было знаний, которые я знал бы, чтобы проверить это лучше.

Итак, я тестировал веб-сайт, и у него были токены JWT при входе в систему. Поэтому я решил расшифровать его как base64 и увидел, что у него есть ключ. На самом деле это был секретный ключ. Итак, я использовал его, и внутри этого JWT был еще один JWT и у него тоже был секретный ключ. Во втором токене JWT был еще один JWT, к сожалению, я не знал ключа к этому токену. В то время я сообщил об этом как об уязвимости, но для меня это было слишком сложно. Представьте себе токен JWT внутри токена JWT внутри токена JWT.

Не все кэйсы должны быть раскрыты, верно? Жду интересных кейсов в комментариях!

С уважением grozdniyandy
Специально для xss.pro
 
Для меня, в наиболее точном варианте, шифрование - это процесс преобразования необработанного текста в зашифрованный текст
Это масло маслянное, не точное и ничего не объясняющее.
Шифрование это обратимое преобразование данных с целью сокрытия исходной информации от всех кто не является обладателем ключа шифра.
Текст как тип информации к шифрованию вообще никаким боком.
Согласитесь это нелепо и ничего не объясняет -
Покраска это процесс преобразование не покрашенного забора в покарашенный забор.

Ps:
Не с целью докопатся, а с целью помочь с навыкими изложения.
Будьте внимательней и придирчивей к своим объяснениям.
Умение четко(не двусмысленно), кратко, не противоречиво, объяснить суть - это важно прежде всего для вас, потому что есть связь между тем как человек мыслит и тем как излагает мысль.
Работайте над собой.
 
Это масло маслянное, не точное и ничего не объясняющее.
Шифрование это обратимое преобразование данных с целью сокрытия исходной информации от всех кто не является обладателем ключа шифра.
Текст как тип информации к шифрованию вообще никаким боком.
Согласитесь это нелепо и ничего не объясняет -
Покраска это процесс преобразование не покрашенного забора в покарашенный забор.

Ps:
Не с целью докопатся, а с целью помочь с навыкими изложения.
Будьте внимательней и придирчивей к своим объяснениям.
Умение четко(не двусмысленно), кратко, не противоречиво, объяснить суть - это важно прежде всего для вас, потому что есть связь между тем как человек мыслит и тем как излагает мысль.
Работайте над собой.
Я могу допускать ошибки, я говорю об этом в каждой своей статье, вы вольны их исправлять

Ты прав. Если есть что-то еще, что вы хотели бы подправить, я буду рад это прочитать. Я стараюсь улучшить навыки самоизложения, у меня большие проблемы с передачей мыслей. Я поддерживаю людей, пытающихся помочь в этом.
 
Почему мы должны использовать его, когда у нас есть cookie?
Я надеюсь вы имели в виду сессии)

Посмотрите как web приложения хранят данные сессий. Обычно для этого создается отдельное хранилище (БД, файлы, RAM)
А если наше приложение уже большое и ему требуется два сервера для обработки запросов? Остается только один вариант - база данных.
Из за этого растет нагрузка на БД и она занята бесконечной обработкой однотипных запросов. Появляется риск существенно увеличить время ответа и получить отказ в обслуживании.
А если у вас несколько сервисов? Сервису не всегда нужно иметь доступ к базе данных сессий. Например может быть достаточно только имени пользователя. Зачем предоставлять доступ к БД для всех сервисов? Ограничимся JWT и уберем потенциальную точку входа.

это пришло к нам от умов, которые создали PUT и вместо этого используют POST
На скриншоте ниже видно что отправляется запрос x-www-form-urlencoded. Попробуйте отправить PUT запрос с помощью тега form
 
А если у вас несколько сервисов? Сервису не всегда нужно иметь доступ к базе данных сессий. Например может быть достаточно только имени пользователя. Зачем предоставлять доступ к БД для всех сервисов? Ограничимся JWT и уберем потенциальную точку входа.
Тут и появляется атака на перекрестную ретрансляцию
На скриншоте ниже видно что отправляется запрос x-www-form-urlencoded. Попробуйте отправить PUT запрос с помощью тега form
Это из "большой теории взрыва" где Леонард говорит "Hilo" и Шелдон потом использует "From the mind that brought you Hilo" (чтобы понять намек нужно посмотреть)
Почему они используют это как сессию
Я тут намекал как раз на то что вы пишите "Зачем предоставлять доступ к БД для всех сервисов? Ограничимся JWT и уберем потенциальную точку входа." - Тоесть токен используется не по цели
 
Я знаком с тем что вы написали. Первоначально я хотел объяснить новые атаки JWT, к сожалению, у меня нет лаборатории, чтобы протестировать их. Я вижу, вы разработчик, и если вы сможете создать уязвимое приложение для новых атак, это было бы здорово.

Изображение [1]: Использование сессий

Изображение [1]: Использование сессий



Изображение [2]: Использование JWT

Изображение [2]: Использование JWT​



Я настоятельно советую всем ознакомиться с этим: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf.
 
Тут и появляется атака на перекрестную ретрансляцию
Сервисы не осуществляют выпуск токенов. В таком сценарии мы наоборот стараемся изолировать их от доступа к излишним пользовательским данным.
Я бы привел такой пример: Есть сервис который выдает токены. И есть сервис выставления оценки заказу (по 5 бальной шкале. Нравится ли вам сроки доставки? Качество обслуживания?). Зачем сервису оценки иметь доступ к базе с паролями пользователей? Для обработки запроса достаточно только имени или ID пользователя. И конечно сервис оценки никогда не должен выпускать токены, потому что выдачей токенов занимается только сервис выдачи токенов

Тоесть токен используется не по цели
Полностью согласен, в данном случае это ошибка с стороны создателя таска.

Я вижу, вы разработчик, и если вы сможете создать уязвимое приложение для новых атак, это было бы здорово.
Давайте это обсудим в PM
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх