Содержание статьи
- Что будет, если не проверять redirect_uri
- Лаба: OAuth account hijacking via redirect_uri
- Злоупотребление открытым редиректом в связке с OAuth
- Лаба: Stealing OAuth access tokens via an open redirect
- Формируем цепочки багов для повышения импакта
- Как работает PostMessage
- Burp Suite и DOM Invader
- Лаба: Stealing OAuth access tokens via a proxy page
- Выводы
Сегодня разберем мисконфиги OAuth, которые встречаются в дикой природе и, хоть сами по себе безобидны, в определенных условиях могут иметь серьезные последствия — вплоть до похека админских аккаунтов. В этой статье я покажу, как искать такие цепочки уязвимостей.
Ты, например, мог слышать про Open Redirect, который часто не воспринимают всерьез и за обнаружение которого не платят Bug Bounty. Но если ты сможешь найти способ красиво заюзать его и повысить импакт до кражи аккаунта, это уже совсем другое дело.
О том, как устроен протокол OAuth и как эксплуатируют базовые уязвимости в нем, читай в моей предыдущей статье — «OAuth от и до. Изучаем протокол и разбираем базовые атаки на OAuth».
Что будет, если не проверять redirect_uri
Схематичное изображение атаки с подменой redirect_uri
Первый кейс простой. redirect_uri — это тот параметр, который говорит серверу авторизации, на какой URL ему нужно направить токен после того, как пользователь войдет через социальную сеть и согласится дать доступ к своим ресурсам.
Приложение на первом этапе авторизации по OAuth, или, в терминологии спеки, этапе Authorization Request, формирует ссылку и указывает в качестве этого параметра подконтрольный ему эндпоинт.
Когда ты входишь через Discord на сайт Midjourney, ссылка выглядит примерно так:
В этом запросе говорится о том, что в конце флоу сервер авторизации не только выдает код, но и должен вернуть пользователя на сайт приложения midjourney.como/auth2/authorize.
По‑хорошему в параметре redirect_uri должен быть вайтлист ссылок, на которые можно редиректить. Такие ссылки обычно указывает владелец приложения, когда его регистрирует. Это позволяет обрубать запрос, если кто‑то подставит свой redirect_uri.
Если вайтлиста нет, это создает пространство для манипуляций. Злоумышленник может взять ссылку из первого этапа и заменить в ней redirect_uri подконтрольным ему сервисом, выложить ее где‑нибудь в социальных сетях и украсть токен после того, как кто‑нибудь уже авторизованный в Discord и в Midjourney перейдет по ней (то же справедливо и для других пар приложений и OAuth-провайдеров).
Сейчас мы разберем это подробнее на реальном примере.
Лаба: OAuth account hijacking via redirect_uri
- Лабораторная работа на сайте PortSwigger
Стартуем и оказываемся на главной странице со странной картинкой.
Главная страница блога
Как и раньше, проходим весь флоу с логином, чтобы собрать все запросы и спокойно проанализировать их. Заходим под аккаунтом wiener.
Уведомление об успешном логине
И оказываемся в личном кабинете.
Флоу авторизации пройден, переходим в Burp. Находим Authorization Request (тот запрос на сервер авторизации, на который нас перенаправило приложение) и отправляем его в Repeater.
Именно в этой ссылке есть уязвимый redirect_uri, который мы и будем эксплуатировать.
Запрос на авторизацию
Уязвимость заключается в том, что в приложении сервера авторизации должным образом (вообще никак) не проверяется redirect_uri. А это значит, что, подменив его, мы можем направить пользователя на собственную страницу, чтобы залогировать чужой токен.
Посмотрим, как это происходит на практике. Меняем в нашем запросе тот URI, который был указан, на адрес эксплоит‑сервера. Он выдается в лабораториях вроде этой, и его можно найти в верхнем меню.
Кнопка с переходом к эксплоит‑серверу
Переходи туда, копируй ссылку и вставляй ее в качестве параметра redirect_uri.
Ссылка на эксплоит‑сервер
У меня это выглядит так.
Подмена redirect_uri адресом эксплоит‑сервера
Можно нажать правой кнопкой мыши и выбрать Copy URL, чтобы скопировать всю ссылку и посмотреть в браузере, как произойдет редирект и в логах появится наш токен.
Нигде ничего вводить уже не надо (так как мы уже вошли на всех сайтах и дали согласие), просто ты прошел цепочку редиректов, и вот уже токен залогирован на нашем эксплоит‑сервере или сервере злоумышленника.
OAuth-токен в access-логах
Это наш собственный токен, а нам нужен токен администратора. Так что возвращаемся на главную страницу эксплоит‑сервера и берем ту же самую разметку с редиректом, которую мы уже использовали в лабораториях из прошлой статьи. Только на этот раз меняем URL на тот, который мы только что скрафтили, где redirect_uri ведет на наш сервер.
У меня получилось так.
Вставляем HTML-разметку в поле Body и сохраняем кнопкой Store.
HTML-разметка для эксплоита
Теперь у нас есть страница, на которую может зайти администратор, и тогда мы украдем его учетку. При посещении страницы произойдет цепочка редиректов для авторизации. Поскольку он уже залогинен в социальной сети, в конце концов он будет перенаправлен на наш сервер, где мы и залогируем его OAuth-токен из URL.
Нажимаем Deliver exploit to victim. В зависимости от нагрузки на серверы PortSwigger запрос может прийти с небольшой задержкой. Мне пришлось подождать несколько минут (в течение которых я жал одну и ту же кнопку), и в конце концов мне прилетело несколько десятков запросов с токеном администратора.
Много залогированных токенов админа
Копируем последний пришедший токен и вставляем в запрос /oauth-callback. Если все пройдет нормально, сервер должен отдать куки и показать, что мы залогинены. Так и произошло. Появилась ссылка на панель администратора, а это значит, что мы не просто зашли, а зашли как админ.
Отправка украденного кода, чтобы получить сессию админа
Заходим через браузер, удаляем пользователя carlos и наслаждаемся победой над еще одной лабой.
Уведомление об успешном прохождении лабы
Злоупотребление открытым редиректом в связке с OAuth
Схематичное изображение Open Redirect
Давай кратко вспомним, что вообще такое Open Redirect.
Open Redirect, или открытое перенаправление, — это такая уязвимость, когда веб‑приложение допускает перенаправить пользователя на произвольные внешние URL-адреса без должной проверки.
Например, у нас есть сайт Google. Он не нуждается в представлении, у него большой кредит доверия, и все компании считают, что домен google.com безопасный, поэтому дают ему некоторые послабления, добавляя в собственные белые списки.
Но если злоумышленники найдут на нем Open Redirect, то они смогут воспользоваться этим доверием и использовать его, чтобы создать ссылку на собственный C2-сервер, обходя детектирование некоторых антивирусов.
Вот пример такой ссылки:
https://www.google.com/url?sa=t&url=https://evil.com
Она была бы уязвимой, если бы сразу направляла на указанный сайт. Хорошим тоном считается предупреждать пользователя, что он покидает легитимный сайт, и не выполнять редирект без его согласия.
Предупреждение о небезопасном сайте
Сам по себе Open Redirect не очень опасен, кроме пограничного случая, связанного с вредоносами, который я описал выше. Но его часто используют в связке с эксплуатацией других веб‑уязвимостей, когда он становится по‑настоящему грозным оружием, позволяющим обходить многие фильтры, заточенные на проверку по регулярке или подстроке.
К примеру, сайт может проверять, что redirect_uri начинается только с https://example.com. Если на этом example.com получится найти Open Redirect, то можно будет и пройти проверку, и эксплуатировать уязвимость, чтобы украсть токен через OAuth.
Лаба: Stealing OAuth access tokens via an open redirect
- Лабораторная работа на сайте PortSwigger
Как всегда, открываем лабораторию и попадаем на главную страницу блога.
Главная страница блога
Логинимся через социальную сеть.
Смотрим историю запросов, берем Authorization Request и пытаемся повторить трюк из предыдущей лабы — для этого заменяем redirect_uri каким‑нибудь своим, например адресом эксплоит‑сервера.