Атака algorithm confusion
Атаки путаницы алгоритмов (также известные как атаки «key confusion») происходят, когда злоумышленник может заставить сервер проверять подпись JWT с использованием иного алгоритма, чем задумали разработчики сайта. Если этот случай обработан некорректно, это может позволить злоумышленникам подделывать валидные JWT с произвольными значениями без знания секретного ключа подписи сервера.
Симметричные и асимметричные алгоритмы
JWT могут подписываться с использованием разных алгоритмов. Некоторые из них, например HS256 (HMAC + SHA‑256), используют симметричный ключ. Это означает, что сервер применяет один и тот же ключ и для подписи, и для проверки токена. Очевидно, этот ключ нужно хранить в секрете, как пароль.

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

Как следует из названий, закрытый ключ должен оставаться секретным, но открытым ключом часто делятся, чтобы любой мог проверить подписи токенов, выпущенных сервером.
Как возникают уязвимости путаницы алгоритмов?
Уязвимости путаницы алгоритмов обычно возникают из‑за некорректной реализации библиотек JWT. Хотя фактический процесс проверки подписи различается в зависимости от алгоритма, многие библиотеки предоставляют единый, независимый от алгоритма метод проверки подписей. Эти методы полагаются на параметр alg в заголовке токена, чтобы определить тип проверки, который следует выполнить.
Ниже упрощённый псевдокод того, как может выглядеть объявление такого универсального метода verify() в библиотеке JWT:
Проблемы возникают, когда разработчики сайта, используя этот метод, предполагают, что он будет работать исключительно с JWT, подписанными асимметричным алгоритмом, например RS256. Из‑за этого ошибочного предположения они могут всегда передавать фиксированный открытый ключ в метод, например так:
В этом случае, если сервер получит токен, подписанный симметричным алгоритмом, таким как HS256, универсальный метод verify() библиотеки будет трактовать открытый ключ как HMAC‑секрет. Это значит, что злоумышленник может подписать токен с помощью HS256 и открытого ключа, а сервер использует этот же открытый ключ, чтобы проверить подпись.
Выполнение атаки путаницы алгоритмов
Атака путаницы алгоритмов в общих чертах включает следующие шаги:
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:
После загрузки расширения откройте вкладку JWT Editor Keys в главной панели Burp.
Нажмите New RSA Key. Во всплывающем окне вставьте ранее полученный JWK.
Выберите переключатель PEM и скопируйте полученный PEM‑ключ.
Перейдите на вкладку Decoder и закодируйте PEM в Base64.
Вернитесь на вкладку JWT Editor Keys и нажмите New Symmetric Key.
В диалоге нажмите Generate, чтобы сгенерировать новый ключ в формате JWK.
Замените сгенерированное значение параметра
kна Base64‑закодированный PEM‑ключ, который вы только что скопировали.Сохраните ключ.
3. Измените ваш JWT
Когда у вас есть открытый ключ в подходящем формате, вы можете изменить JWT как вам нужно. Убедитесь, что заголовок alg установлен в HS256.
4. Подпишите JWT с использованием открытого ключа
Подпишите токен алгоритмом HS256, используя открытый RSA‑ключ в качестве секрета.
Получение открытых ключей по существующим токенам
Если открытый ключ недоступен напрямую, вы всё ещё можете протестировать путаницу алгоритмов, выведя ключ из пары существующих JWT. Этот процесс относительно прост с помощью инструментов вроде jwt_forgery.py. Его, наряду с несколькими полезными скриптами, можно найти в репозитории rsa_sign2n.
Также есть упрощённая версия этого инструмента, которую можно запустить одной командой:
Инструмент использует предоставленные JWT для вычисления одного или нескольких возможных значений n. Не беспокойтесь о том, что это значит — важно лишь то, что только одно из этих значений соответствует n, используемому ключом сервера. Для каждого потенциального значения скрипт выводит:
Base64‑закодированный PEM‑ключ в форматах X.509 и PKCS1.
Поддельный JWT, подписанный каждым из этих ключей.
Чтобы определить корректный ключ, используйте Burp Repeater и отправьте запрос с каждым из поддельных JWT. Сервер примет только один из них. Затем вы можете использовать соответствующий ключ для построения атаки путаницы алгоритмов.
Для получения дополнительной информации о том, как работает этот процесс, и деталей использования стандартного инструмента jwt_forgery.py, обратитесь к документации в репозитории.
Last updated