16 Января, 2013

Интересный случай с SSRF.

Alexey Sintsov
Интересный случай с SSRF.


В последнее время в Интернетах и в узком кругу ИБ специалистов активно обсуждаются концепты, примеры и техники проведения “новой” атаки - SSRF. Хотелось бы рассказать об одной такой атаке. Данный случай интересен и тем, что его трудно классифицировать по существующим меркам “угроза-уязвимость”. То есть, есть конкретная атака и есть реализация конкретной угрозы, но если разбирать “уязвимости” отдельно, то угрозы - другие. И этот пример, на мой скромный взгляд, показывает, что “теория ИБ” и классификация в нашей теме - сильно отстает от практики и не всегда применима в том виде, что она есть сейчас.


В качестве базы, для тех, кто не в курсе что есть SSRF атака, рекомендую к прочтению: http://andrepetukhov.wordpress.com/2012/11/09/%D1%82%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D1%8B-xxe-ssrf-%D0%B8-%D0%B2%D1%81%D0%B5-%D0%B2%D1%81%D0%B5-%D0%B2%D1%81%D0%B5/

Для остальных и коротко: 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 - https://s1.domain.com/?url=http://ya.ru


Конечно есть сервер SSO.SSO: Сервер авторизации.
Host: sso.domain.com

//бага 4 - redirect: https://sso.domain.com/?afterauth=http://s1.domain.com
//редирект работает только в для родного домена и списка сервисов!

Документация:
Сервис проходит авторизацию по REST API.

1. Аутентифкация. Начало.

1.1. Сервис S1 проверяет куку ‘code’. Если она не пуста, то готу 2.
2.2. Сервис делает редирект на сервис SSO: https://sso.domain.com/getAuth?ID=S1
2.3. SSO проверяет PHPSESSIONID, если для данной сессии есть аутентифкационные данные, то делает обратный редирект по параметру ID=S1: https://s1.domain.com/authDone?code=0cc1166f5a3012a1bc3eafff018acb31 , где code берется из данных сессии по соотвествующему ID. Если code там нет, то готу 2.7
Если аутентификации по сессии нет, то готу 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 https://sso.domain.com/api/check/<code> ; HTTР/1.1

Header-Signature: ashJiTfV537Gfcf64f8hg4FgDkkkA785F5g/hjkR4Ed==
Header-ID: S1
Header-Data: “ https://sso.domain.com/api/check/<code> ;”


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

Задачу решил без проблем i Sciurus .

Эксплойт:
3.1 Omisión de la autenticación
https://s1.domain.com/authDone?code=../../?afterauth=http://s1.domain.com%3Furl=http://my.domain/get_any_json

Вот такая интересная, а главное простая и мощная SSRF атака. В чем ошибка?

1. Работа по GET запросу в REST API---> Ну и что? Все запросы подписаны! Никто в этот API сунуться не сможет, он закрыт для Интернетов и открыт только для легитимных сервисов только.
2. Не фильтруется значение токена: ></../?= и тд
---> А зачем его фильтровать? Какая уязвимость тут? токен "*&%<xss.>'SQL111" - просто вернет ошибку {error:'not found'}. Нет вектора.
3. Redirect/OpenRedirect
---> низкий приоритет, атака клиент-сайд.
4. S1 обрабатывает редиректы HTTP, что позволяет его перекинуть на другой хост.---> Так редирект с SSO, который злоумышленник не контролирует
Вот так все по отдельности низкопробные баги, и даже совсем не уязвимости(кроме редиректа), а функциональные мелочи. Но вот все вместе - атака, с хорошим, таким, ущербом. SSRF тут вообще без XXE/RFI как и говорил Андрей и без всяких враперов Владимира. Более того, изначально запрос вообще подписан! И третье, непосредственно выполняя атаку, нельзя поменять целевой хост (это стало возможным только с помощью двух redirect'ов).
или введите имя

CAPTCHA