В последнее время в Интернетах и в узком кругу ИБ специалистов активно обсуждаются концепты, примеры и техники проведения “новой” атаки - SSRF. Хотелось бы рассказать об одной такой атаке. Данный случай интересен и тем, что его трудно классифицировать по существующим меркам “угроза-уязвимость”. То есть, есть конкретная атака и есть реализация конкретной угрозы, но если разбирать “уязвимости” отдельно, то угрозы - другие. И этот пример, на мой скромный взгляд, показывает, что “теория ИБ” и классификация в нашей теме - сильно отстает от практики и не всегда применима в том виде, что она есть сейчас.
В качестве базы, для тех, кто не в курсе что есть SSRF атака, рекомендую к прочтению:
Для остальных и коротко: SSRF - Server-Side-Request-Forgery. Суть: атака, в результате который мы можем инициировать запросы с атакуемого хоста B на другие компоненты системы, например на хост C. При этом у нас нет прямой возможности послать такой запрос на хост C. Например хост C в локальной сети/DMZ. Таким вот образом мы можем делать разные интересные вещи. В некоторых интересных вариантах, хост C может быть тем же хостом B, только локальный сетевой интерфейс не доступный из Интернетов (то есть атакующему).
В данном посте я хочу рассказать о другом интересном случае проведения SSRF атаки. А хотя нет! Давайте интерактивно, я вам опишу систему, а вы сами проведете атаку в комментах! Победителю вышлю-вручу приз - резиновую уточку 8)
//Ответы от Андрея Петухова, Владимира Воронцова и Сашу Штукера не принимаются =)
Дано:
Имеется сеть сервисов, но нам будет интересен один только.S1: Сервер с персональными данными. Его надо “хакнуть”. Авторизация - Single Sign-On.
Host: s1.domain.com
//бага 1 - open-redirect -
Конечно есть сервер SSO.SSO: Сервер авторизации.
Host: sso.domain.com
//бага 4 - redirect:
//редирект работает только в для родного домена и списка сервисов!
Документация:
Сервис проходит авторизацию по REST API.
1. Аутентифкация. Начало.
1.1. Сервис S1 проверяет куку ‘code’. Если она не пуста, то готу 2.
2.2. Сервис делает редирект на сервис SSO:
2.3. SSO проверяет PHPSESSIONID, если для данной сессии есть аутентифкационные данные, то делает обратный редирект по параметру ID=S1:
Если аутентификации по сессии нет, то готу 2.6
2.4. S1 ставит куку code из параметра code.
2.5. готу 1.1
2.6. Сервер SSO просит ввести логин и проль поп-апом. Стандартная аутентификация в POST запросе на SSO, пример приводить не буду. Стандартно все. Если логин (don_huan например) и пароль верный, то для данная сессия считается аутентифицированной. Если нет, готу 2.6. (капча, csrf токены есть, если что)
2.7. Регистрируется код, записывается в сессию, проверяется что существует такой ID. Если что не так - ошибка.
2.8 готу 2.3
2. Аутентификация - проверка.
2.1. Берется <code> из куки как есть и генерируется REST API запрос c сервера S1 на SSO (не видим пользователю), URL которого подписывается собственным секретным ключом сервера S1:
GET
…
Header-Signature: ashJiTfV537Gfcf64f8hg4FgDkkkA785F5g/hjkR4Ed==
Header-ID: S1
Header-Data: “
…
2.3. Сервер SSO проверяет подпись используя зарегистрированный открытый ключ S1. Проверяет подпись Header-Signature для Header-Data, есличто не так - ошибка, если все верно, то дальше.
2.4. Скрипт обработчик на SSO (/api/check/) проверяет что <code> зарегистрирован, если нет - то ошибка, иначе дальше.
2.5. Возвращается JSON :
{registered_user:”don_huan”}
2.6 Сервер S1 считывает JSON ответ, и выдает пользователю его персональные данные по registered_user. Ну или ошибку, если нет такого пользователя.
--------
Как-то так. В принципе атака очевидна, но... какой эффект! Если есть вопросы - пишите в комментах, я отвечу 8) Варианты то же пишите. Напоминаю, что это был реальный случай, реальной атаки, а не просто теор-выкладка. Так же, после нахождения ответа интересно послушать то, как это можно классифицировать и какие были уязвимости? Кстати, это пример уязвимости, которую я нашел тупо чтением документации 8) P.S. Все совпадения случайны. На самом деле там использовался OAuth, но мне лень было описывать алгоритмы OAuth таким макаром, поэтому я все cильно упростил в данной документации и архитектуре - тем проще ;)
UPD
Задачу решил без проблем
Эксплойт:
3.1 Omisión de la autenticación
Вот такая интересная, а главное простая и мощная SSRF атака. В чем ошибка?
1. Работа по GET запросу в REST API---> Ну и что? Все запросы подписаны! Никто в этот API сунуться не сможет, он закрыт для Интернетов и открыт только для легитимных сервисов только.
2. Не фильтруется значение токена: ></../?= и тд
---> А зачем его фильтровать? Какая уязвимость тут? токен "*&%<xss.>'SQL111" - просто вернет ошибку {error:'not found'}. Нет вектора.
3. Redirect/OpenRedirect
---> низкий приоритет, атака клиент-сайд.
4. S1 обрабатывает редиректы HTTP, что позволяет его перекинуть на другой хост.---> Так редирект с SSO, который злоумышленник не контролирует
Вот так все по отдельности низкопробные баги, и даже совсем не уязвимости(кроме редиректа), а функциональные мелочи. Но вот все вместе - атака, с хорошим, таким, ущербом. SSRF тут вообще без XXE/RFI как и говорил Андрей и без всяких враперов Владимира. Более того, изначально запрос вообще подписан! И третье, непосредственно выполняя атаку, нельзя поменять целевой хост (это стало возможным только с помощью двух redirect'ов).