Веб-безопасность/Атаки SSRF
Содержание
Микросервисная архитектура
Архитектурный стиль микросервисов — это подход, при котором единое приложение строится как набор небольших сервисов, каждый из которых работает в собственном процессе и коммуницирует с остальными используя легковесные механизмы, как правило HTTP. Сами по себе эти сервисы могут быть написаны на разных языках и использовать разные технологии хранения данных. Такой подход противопоставляется монолитному стилю, при котором вся логика по обработке запросов выполняется в единственном процессе.
При построении приложения с микросервисной архитектурой недостаточно установить защиту только на входе.
При разработке ставятся следующие задачи:
- взаимная аутентификация микросервисов;
- авторизация запросов к микросервисам;
- защищенный транспорт.
Аутентификация и авторизация
Аутентификация - процедура проверки подлинности пользователя.
Авторизация - процедура проверки наличия прав на действие.
Схемы
Существует следующая традиционная схема URL:
<схема>:[//[<логин>[:<пароль>]@]<хост>[:<порт>]][/<URL‐путь>][?<параметры>][#<якорь>]
В этой записи:
- схема - схема обращения к ресурсу; в большинстве случаев имеется в виду сетевой протокол;
- логин - имя пользователя, используемое для доступа к ресурсу;
- пароль - пароль указанного пользователя;
- хост - полностью прописанное доменное имя хоста в системе DNS или IP-адрес хоста;
- порт - порт хоста для подключения;
- URL-путь - уточняющая информация о месте нахождения ресурса; зависит от протокола;
- параметры - строка запроса с передаваемыми на сервер (методом GET) параметрами. Начинается с символа ?, разделитель параметров — знак &;
- якорь - строка, которая относится к ресурсу, который подчинен другому первичному ресурсу; пример: https://course.secsem.ru/wiki/Веб-безопасность/Введение_в_веб-технологии#Ip.
Кроме стандартной схемы HTTP/HTTPS существуют следующие стандартные протоколы.
- схема GOPHER - сетевой протокол распределённого поиска и передачи документов;
- схема TFTP - используется главным образом для первоначальной загрузки бездисковых рабочих станций (ПК без несъёмных средств для долговременного хранения);
- схема File - потенциальное обращение к диску;
- схема FTP, SFTP, LDAP и т.д.
SSRF
Атака SSRF - Server Side Request Forgery - возможна в случае наличия уязвимости ПО, позволяющей злоумышленнику спровоцировать сервер на отправку запроса на произвольный адрес. Рассмотрим веб-чат, который позволяет прикреплять к сообщениям картинки-карточки, добавляя ее URL. Причем карточки формируются на бекенде. Предполагается, что при загрузке карточки приложение будет обращаться по указанному URL и формировать карточку.
Но злоумышленник может предоставить в качестве URL картинки некий внутренний адрес, таким образом получив несанкционированный доступ к сканированию внутренней сети компании и отправке HTTP-запросов во внутреннюю сеть (где микросервисная архитектура).
Payloads
Рассмотрим некоторые полезные нагрузки которые могут быть использованы при SSRF.
- произвольные HTTP GET запросы с отображением ответа
- localhost;
- внутренние ресурсы:
- Gitlab;
- Redmine;
- Jenkins и т.п.
- произвольные HTTP GET запросы «слепой случай»
- код ошибки;
- время отклика.
- если удастся перехватить запрос, то в нем могут быть полезны
- user-agent - стек технологий;
- дополнительные заголовки при взаимодействии микросервисов;
- cookie или JW token - при большом везении.
- прочее
- MySQL (Port-3306);
- FastCGI(Port-9000);
- WSGI (Port-9000);
- Memcached (Port-11211);
- Redis (Port-6379);
- Zabbix (Port-10050);
- SMTP (Port-25)
Пример
Рассмотрим приложение, код которого расположен ниже.
<?php
/**
* Check if the 'url' GET variable is set
* Example - http://localhost/?url=http://testphp.vulnweb.com/images/logo.gif
*/
if (isset($_GET['url'])){
$url = $_GET['url'];
/**
* Send a request vulnerable to SSRF since
* no validation is being done on $url
* before sending the request
*/
$image = fopen($url, 'rb');
/**
* Send the correct response headers
*/
header("Content-Type: image/png");
/**
* Dump the contents of the image
*/
fpassthru($image);}
Злоумышленник имеет полный контроль над параметром URL, он может делать произвольные запросы к любому веб-сайту и к ресурсам на сервере. Рассмотрим несколько примеров запросов. Запрос к Apache HTTP Servers жертвы.
GET /?url=http://localhost/server-status HTTP/1.1 Host: example.com
Атакующий может получить доступ к внутренним сервисам, например матаданным экземпляра облачной службы.
GET /?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1 Host: example.com
Кроме того атакующий может обратиться к нестандартной схеме.
GET /?url=file:///etc/passwd HTTP/1.1 Host: example.com
При использовании приложением curl, то атакующий может использовать схему URL dict: // для отправки запросов любому хосту на любом порту и отправки пользовательских данных.
GET /?url=dict://localhost:11211/stat HTTP/1.1 Host: example.com
Обход фильтрации
В качестве простых средств защиты можно проверять схему в ссылке и работать только с HTTP/HTTPS и также проверять адрес в ссылке и блокировать запросы на внутренние подсети (192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 127.0.0.0/8...) Но этого недостаточно, есть различные способы обхода подобной фильтрации.
Собственные DNS записи
Возможно создавать собственные DNS записи, указывающие на локальные адреса.
DNS rebinding
Основная идея DNS rebinding - обмануть SOP. Алгоритм:
- регистрация домена (attacker.com) + контроль над DNS-сервером
- ответы имеют короткое время жизни
- предотвращение кэширования
- жертва переходит на вредоносный домен
- DNS-сервер возвращает настоящий IP сервера с вредоносным кодом (JS)
- вредоносный скрипт исполняется
- новый запрос DNS для данного домена
- ответ: attacker.com находится на новом IP (напр. внутренний)
- получен доступ к внутренней структуре (SOP)
Перенаправление
Создание внешнего ресурса, цель которого - перенаправить на внутренний ресурс. Возможно изменение схемы. Запрос:
https://hackers-normal-site.com
Ответ:
HTTP/1.1 302 Found Date: Fri, 24 Aug 2018 12:15:36 GMT Location: http://169.254.169.254/
Альтернативные представления
- многие библиотеки поддерживают сокращения: 127.0.0.1 и 127.1 для них – одно и то же;
- многие библиотеки поддерживают отличные от десятичного представления октетов: 127.0.0.1 и 0177.1 для них – одно и то же;
- многие библиотеки поддерживают смешанные представления октетов: 127.127.0.1 и 0x7f.0177.1 для них – одно и то же;
- например, для cURL нет разницы между 127.0.0.1 и 127.1, и 0177.1, и 0x7f.1, и 2130706433.
IPv6
Не стоит забывать про Ipv6. Возможно он поддерживается и тогда
127.0.0.1 == 0:0:0:0:0:0:0:1 == [::1]
Неоднозначные URL
Использование разных стеков технологий может привести к разночтению URL защитой и бекендом.
Защита
Для уменьшения опасности SSRF стоит:
- ограничить доступ к внутренней инфраструктуре для потенциально подверженных SSRF серверов:
- ввести межсервисную аутентификацию;
- использовать внешний прокси;
- ограничить поддерживаемые схемы;
- отключить поддержку перенаправлений или проверять каждый шаг;
- валидировать доменные имена;
- разобраться как используемая библиотека обрабатывает адреса.