В рубрику "Оборудование и технологии" | К списку рубрик | К списку авторов | К списку публикаций
Перед разработчиками стоят трудные задачи, решение которых не всегда очевидно. Поэтому они сосредоточены в первую очередь на поставленной задаче, а безопасность уже потом, когда решение будет найдено. Но так бывает не всегда. Разработчик, загруженный большим объемом работы, может забыть уделить чему-то должное внимание и случайно что-то пропустить, а если система очень сложная – не заметить незапланированную возможность использовать созданный функционал не так, как это задумывалось изначально.
В результате возникают достаточно интересные уязвимости, позволяющие атакующему злоумышленнику влиять на взаимодействие систем и серверов, стоящих "далеко" за интерфейсом уязвимой системы и прямого доступа к которым нет. Отчасти это напоминает взлом замка отмычками, когда через замочную скважину можно проводить манипуляции с элементами замка, не имея полного представления об устройстве системы, но оказывая влияние на внутренние механизмы. В конечном итоге это может дать доступ к части внутреннего функционала системы, недоступного снаружи, а при дальнейшем развитии вектора – "открыть дверь" полностью.
Суть уязвимости заключается в небезопасном применении пользовательских данных в выборе сервера или системы, к которым нужно обратиться за какой-либо информацией или ресурсами. Это может быть загрузка картинки с указанием ее ссылки в сети Интернет или некорректная организация работы с API-сервером. Для примера возьмем вариант с загрузкой аватарки на сервер по ссылке в GET-параметре.
Вот как задумывалось использовать функционал изначально:
GET /?url=http://images.com/image.jpg.
Однако если разработчики не уделили должное внимание безопасности, то злоумышленник может указать ссылку, провоцирующую сервер на несанкционированный запрос:
А теперь пару слов о каждом пункте.
В корпоративной (или иной) сети часто присутствуют разные Web-сервисы или другие службы для внутреннего пользования. Как правило, подобные сервисы не имеют авторизации или могут содержать конфиденциальную информацию (например, внутренний портал о сотрудниках корпорации).
SSRF-уязвимости бывают в системах с разным функционалом, каждый случай имеет свои особенности. В каких-то ситуациях можно получать ответ от внутреннего сервера и не особо влиять на содержимое запроса, а в других – полностью управлять соединением, вплоть до организации сессий с FTP-сервером или базами данных.
Примеры запроса:
На практике для эксплуатации такой уязвимости пишется скрипт, который перебирает все возможные варианты внутренних IP-адресов и интересующих злоумышленника портов. На выходе атакующий знает расположение основных внутренних серверов и запущенные на них службы. Далее при позволении SSRF инициируются запросы уже к конкретной службе для получения информации или подбора учетных данных.
Например, во время аудита крупного банка через SSRF удалось получить доступ ко всем аккаунтам клиентов, фактически не нарушая внешний периметр банка. В Web-приложении одного из иностранных филиалов этого банка была найдена SSRF-уязвимость, через которую была просканирована внутренняя сеть и выявлен список серверов баз данных MSSQL. Через эту же уязвимость был организован подбор учетных данных к банковским базам данных, который увенчался успехом, что впоследствии привело к возможности доступа к любому банковскому аккаунту.
Для взаимодействия со службами внутри сети используются разные схемы URI, такие как dict://, ftp:// and gopher://.
Не всегда ответ на запрос доступен полностью, иногда выдается только ошибка. Вот по этой ошибке и можно судить об успешности/неуспешности запроса. К примеру, если сканировать порты сервера через SSRF, то об открытом порте может свидетельствовать "Ошибка обработки данных", а о закрытом – "Не удалось установить соединение", и т.д.
Множество систем и сервисов обладают Web-интерфейсами на локальном IP-адресе, доступ к которому несанкционированно раскрывает информацию атакующему.
Например, для Apache HTTP можно получить список последних запросов с GET-параметрами, полным URL-адресом и IP посетителей в данный момент:
GET /?url=http://localhost/server-status.
Данная информация может открыть путь до админки, бэкапа или даже идентификатора сессии авторизованного пользователя.
Аналогичная ситуация для любителей AWS/Amazon EC2 и OpenStack:
GET /?url=http://169.254.169.254/ latest/meta-data/.
Возможно множество других вариантов, все зависит от конкретной системы и ее настройки.
Тут все просто: внешнюю ссылку можно попробовать подменить на путь к локальному файлу, используя схему URI file:///:
GET /?url=file:///etc/passwd
Такой способ позволяет прочесть многие конфиги и исходные коды Web-приложения и найти учетные данные для полноценной авторизации на сервере и последующего его захвата.
Из необычных кейсов: на внешнем пентесте клиента выявили SSRF, через которую была скачана часть исходных кодов Web-приложения. Проанализировав исходники, мы обнаружили несанкционированную возможность загрузки файлов на сервер, через которую он уже и был захвачен.
Обычно запрос, инициируемый через SSRF, отправляется в определенном формате на API-сервер и может содержать в себе авторизационные данные, начиная от строчки Basic-авторизации и заканчивая сессионными токенами. Злоумышленник формирует запрос на подконтрольный ему сервер и изучает пришедший к нему запрос, находит в нем авторизационные данные и может уже напрямую обращаться к API-серверу, если он доступен из сети атакующего, или использовать эти авторизационные данные для подбора к другим сервисам или в связке с прочими атаками.
На нашем опыте мы так получали доступы к разному функционалу и серверам, от Sentry до административных API.
Конечно, в реальной жизни такие легкие SSRF, как в описанных примерах, встречаются реже. Обычно уязвимый параметр спрятан в глубине большого запроса в JSON- или XML-формате. Имеются разнообразные фильтры, которые усложняют подмену данных в запросе и пытаются навязывать их определенный формат. Подобные случаи затрудняют поиск и эксплуатацию уязвимостей, но их суть остается прежней. Поэтому нужно внимательно относится к безопасности разработки, повышать осведомленность разработчиков о разных типах уязвимостей и их возможных последствиях, проводить независимые аудиты безопасности ключевых информационных систем и тестирование на проникновение инфраструктуры компании.