Атаки десинхронизации на основе паузы
С виду защищённые сайты могут содержать скрытые уязвимости десинхронизации, которые проявляются только если сделать паузу посередине запроса.
Обычно серверы настроены с таймаутом чтения. Если они больше не получают данных в течение определённого времени, то считают запрос завершённым и отправляют ответ — вне зависимости от того, сколько байтов было указано в заголовках. Уязвимости десинхронизации на основе паузы могут возникать, когда сервер прерывает чтение запроса по таймауту, но оставляет соединение открытым для повторного использования. При определённых условиях такое поведение даёт альтернативный вектор как для серверных, так и для клиентских desync-атак.
Серверная десинхронизация на основе паузы
Можно использовать технику на основе паузы для вызова поведения, подобного CL.0, что позволит вам создавать серверные эксплойты, использующие метод контрабанды запросов для веб-сайтов, которые на первый взгляд могут показаться безопасными.
Это зависит от следующих условий:
Фронтенд-сервер должен немедленно пересылать каждый байт запроса на бэкэнд, а не ждать, пока получит весь запрос целиком.
Фронтенд-сервер не должен (или его можно побудить не делать этого) прерывать запросы по таймауту раньше бэкэнда.
Бэкэнд-сервер должен оставлять соединение открытым для повторного использования после таймаута чтения.
Чтобы показать, как это работает, рассмотрим пример. Ниже — стандартная проба на контрабанду CL.0:
POST /example HTTP/1.1
Host: vulnerable-website.com
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 34
GET /hopefully404 HTTP/1.1
Foo: xПредставим, что мы отправляем заголовки на уязвимый сайт, но делаем паузу перед отправкой тела.
Фронтенд пересылает заголовки на бэкэнд и продолжает ждать оставшиеся байты, обещанные
Content-Length.Через какое-то время бэкэнд срабатывает по таймауту и отправляет ответ, хотя обработал лишь часть запроса. В этот момент фронтенд может прочитать этот ответ и переслать нам, а может и нет.
Наконец мы отправляем тело, которое в данном случае содержит базовый префикс для контрабанды.
Фронтенд воспринимает это как продолжение исходного запроса и пересылает по тому же соединению на бэкэнд.
Бэкэнд уже ответил на исходный запрос, поэтому считает эти байты началом нового запроса.
На этом этапе мы фактически добились CL.0-десинхронизации, отравив соединение фронтенд/бэкэнд префиксом запроса.
Уязвимости чаще встречаются, когда сам сервер генерирует ответ, а не просто проксирует запрос в приложение.
Тестирование уязвимостей CL.0 на основе паузы
Проверить такие уязвимости можно в Burp Repeater, но только если фронтенд сразу пересылает вам ответ бэкэнда, сгенерированный после таймаута, что бывает не всегда. Мы рекомендуем расширение Turbo Intruder: оно позволяет ставить запрос на паузу и возобновлять его независимо от того, получили вы ответ или нет.
В Burp Repeater создайте пробу CL.0, как в примере выше, затем отправьте её в Turbo Intruder.
В панели Python редактора Turbo Intruder настройте движок запросов, установив следующие параметры:
Поставьте запрос в очередь, добавив к интерфейсу
queue()такие аргументы:pauseMarker- список строк, после которых Turbo Intruder должен поставить паузу.pauseTime- длительность паузы в миллисекундах.
Например, чтобы сделать паузу после заголовков на 60 секунд:
Поставьте в очередь следом произвольный запрос как обычно:
Убедитесь, что вы логируете все ответы в таблицу результатов:
Сначала в таблице результатов ничего не будет. Но после указанной паузы вы должны увидеть два результата. Если ответ на второй запрос соответствует ожидаемому от провезённого префикса (в нашем случае — 404), это указывает на успешную десинхронизацию.
Клиентская десинхронизация на основе паузы
Теоретически возможно выполнить клиентский вариант CL.0-десинхронизации на основе паузы. К сожалению, нам пока не удалось найти надёжный способ заставить браузер делать паузу посередине запроса. Однако есть потенциальный обход — активная MITM-атака.
Шифрование TLS мешает MITM читать трафик на лету, но ничто не мешает ему задерживать TCP-пакеты по пути от браузера к веб-серверу. Просто задержав последний пакет до тех пор, пока веб-сервер не отправит ответ, вы можете десинхронизировать соединение браузера.
Ход атаки похож на другие CSD-атаки. Пользователь посещает вредоносный сайт, который заставляет его браузер отправить серию кросс-доменных запросов на целевой сайт. В этом случае нужно преднамеренно заполнить первый запрос так, чтобы ОС разделила его на несколько TCP-пакетов. Поскольку вы контролируете заполнение, можно подобрать её так, чтобы финальный пакет имел отличающийся размер и вы могли определить, какой именно пакет задерживать.
Пример того, как это может выглядеть на практике: Browser-Powered Desync Attacks: A New Frontier in HTTP Request Smuggling.
Как предотвратить уязвимости десинхронизации на основе паузы
Меры по предотвращению уязвимостей десинхронизации на основе паузы и других desync-атак смотрите в разделе Как предотвратить уязвимости контрабанды HTTP-запросов.
Last updated