Атака algorithm confusion

Атаки путаницы алгоритмов (также известные как атаки «key confusion») происходят, когда злоумышленник может заставить сервер проверять подпись JWT с использованием иного алгоритма, чем задумали разработчики сайта. Если этот случай обработан некорректно, это может позволить злоумышленникам подделывать валидные JWT с произвольными значениями без знания секретного ключа подписи сервера.

Симметричные и асимметричные алгоритмы

JWT могут подписываться с использованием разных алгоритмов. Некоторые из них, например HS256 (HMAC + SHA‑256), используют симметричный ключ. Это означает, что сервер применяет один и тот же ключ и для подписи, и для проверки токена. Очевидно, этот ключ нужно хранить в секрете, как пароль.

jwt-symmetric-signing-algorithm.jpg

Другие алгоритмы, такие как RS256 (RSA + SHA‑256), используют асимметричную пару ключей. Она состоит из закрытого ключа, которым сервер подписывает токен, и математически связанного открытого ключа, который может использоваться для проверки подписи.

jwt-asymmetric-signing-algorithm.jpg

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

Как возникают уязвимости путаницы алгоритмов?

Уязвимости путаницы алгоритмов обычно возникают из‑за некорректной реализации библиотек JWT. Хотя фактический процесс проверки подписи различается в зависимости от алгоритма, многие библиотеки предоставляют единый, независимый от алгоритма метод проверки подписей. Эти методы полагаются на параметр alg в заголовке токена, чтобы определить тип проверки, который следует выполнить.

Ниже упрощённый псевдокод того, как может выглядеть объявление такого универсального метода verify() в библиотеке JWT:

Проблемы возникают, когда разработчики сайта, используя этот метод, предполагают, что он будет работать исключительно с JWT, подписанными асимметричным алгоритмом, например RS256. Из‑за этого ошибочного предположения они могут всегда передавать фиксированный открытый ключ в метод, например так:

В этом случае, если сервер получит токен, подписанный симметричным алгоритмом, таким как HS256, универсальный метод verify() библиотеки будет трактовать открытый ключ как HMAC‑секрет. Это значит, что злоумышленник может подписать токен с помощью HS256 и открытого ключа, а сервер использует этот же открытый ключ, чтобы проверить подпись.

Note

Открытый ключ, которым вы подписываете токен, должен быть абсолютно идентичен открытому ключу, сохранённому на сервере. Это включает использование того же формата (например, X.509 PEM) и сохранение любых непечатаемых символов, таких как переводы строк. На практике может потребоваться поэкспериментировать с форматированием, чтобы атака сработала.

Выполнение атаки путаницы алгоритмов

Атака путаницы алгоритмов в общих чертах включает следующие шаги:

Атака algorithm confusion

Атака algorithm confusion

3. Измените ваш JWT

4. Подпишите JWT с использованием открытого ключа

В этом разделе мы подробно рассмотрим этот процесс и покажем, как выполнить такую атаку с помощью Burp Suite.

1. Получите открытый ключ сервера

Серверы иногда публикуют свои открытые ключи как объекты JWK по стандартной конечной точке, например, сопоставленной с /jwks.json или /.well-known/jwks.json. Они могут храниться в массиве JWK под названием keys. Это называется JWK Set.

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

2. Преобразуйте открытый ключ в подходящий формат

Хотя сервер может публиковать открытый ключ в формате JWK, при проверке подписи токена он использует свою копию ключа из локальной файловой системы или базы данных. Она может храниться в другом формате.

Чтобы атака сработала, версия ключа, которой вы подписываете JWT, должна быть идентична локальной копии на сервере. Помимо совпадения формата, должен совпасть каждый байт, включая непечатаемые символы.

В рамках примера допустим, что нам нужен ключ в формате X.509 PEM. Вы можете преобразовать JWK в PEM с помощью расширения JWT Editor в Burp:

  1. После загрузки расширения откройте вкладку JWT Editor Keys в главной панели Burp.

  2. Нажмите New RSA Key. Во всплывающем окне вставьте ранее полученный JWK.

  3. Выберите переключатель PEM и скопируйте полученный PEM‑ключ.

  4. Перейдите на вкладку Decoder и закодируйте PEM в Base64.

  5. Вернитесь на вкладку JWT Editor Keys и нажмите New Symmetric Key.

  6. В диалоге нажмите Generate, чтобы сгенерировать новый ключ в формате JWK.

  7. Замените сгенерированное значение параметра k на Base64‑закодированный PEM‑ключ, который вы только что скопировали.

  8. Сохраните ключ.

3. Измените ваш JWT

Когда у вас есть открытый ключ в подходящем формате, вы можете изменить JWT как вам нужно. Убедитесь, что заголовок alg установлен в HS256.

4. Подпишите JWT с использованием открытого ключа

Подпишите токен алгоритмом HS256, используя открытый RSA‑ключ в качестве секрета.

Получение открытых ключей по существующим токенам

Если открытый ключ недоступен напрямую, вы всё ещё можете протестировать путаницу алгоритмов, выведя ключ из пары существующих JWT. Этот процесс относительно прост с помощью инструментов вроде jwt_forgery.py. Его, наряду с несколькими полезными скриптами, можно найти в репозитории rsa_sign2n.

Также есть упрощённая версия этого инструмента, которую можно запустить одной командой:

Note

Для запуска любой версии инструмента нужен Docker CLI. При первом запуске команда автоматически подтянет образ из Docker Hub, что может занять несколько минут.

Инструмент использует предоставленные JWT для вычисления одного или нескольких возможных значений n. Не беспокойтесь о том, что это значит — важно лишь то, что только одно из этих значений соответствует n, используемому ключом сервера. Для каждого потенциального значения скрипт выводит:

  • Base64‑закодированный PEM‑ключ в форматах X.509 и PKCS1.

  • Поддельный JWT, подписанный каждым из этих ключей.

Чтобы определить корректный ключ, используйте Burp Repeater и отправьте запрос с каждым из поддельных JWT. Сервер примет только один из них. Затем вы можете использовать соответствующий ключ для построения атаки путаницы алгоритмов.

Для получения дополнительной информации о том, как работает этот процесс, и деталей использования стандартного инструмента jwt_forgery.py, обратитесь к документации в репозитории.

Last updated