HTTP request smuggling
Лабораторные работы
Если вы уже знакомы с контрабандой HTTP-запросов и просто хотите попрактиковаться на серии намеренно уязвимых сайтов, ознакомьтесь со ссылкой ниже для обзора всех лабораторных работ по этой теме.
Что такое HTTP request smuggling?
Контрабанда HTTP-запросов — это техника вмешательства в то, как веб-сайт обрабатывает последовательности HTTP-запросов, получаемые от одного или нескольких пользователей. Уязвимости контрабанды часто носят критический характер, позволяя злоумышленнику обходить средства защиты, получать несанкционированный доступ к конфиденциальным данным и напрямую компрометировать других пользователей приложения.
Контрабанда запросов в основном связана с запросами HTTP/1. Однако сайты, поддерживающие HTTP/2, могут также быть уязвимы в зависимости от их архитектуры бэкэнда.
Что происходит при атаке контрабанды HTTP-запросов?
Современные веб-приложения часто используют цепочки HTTP-серверов между пользователями и конечной прикладной логикой. Пользователи отправляют запросы на фронтенд-сервер (иногда его называют балансировщиком нагрузки или обратным прокси), и этот сервер пересылает запросы на один или несколько бэкэнд-серверов. Такой тип архитектуры становится всё более распространённым и в некоторых случаях неизбежен в современных облачных приложениях.
Когда фронтенд-сервер пересылает HTTP-запросы на бэкэнд-сервер, он обычно отправляет несколько запросов по одному и тому же бэкэнд-сетевому соединению, поскольку это намного эффективнее и производительнее. Протокол очень прост: HTTP-запросы отправляются один за другим, и принимающий сервер должен определить, где заканчивается один запрос и начинается следующий:
В этой ситуации крайне важно, чтобы фронтенд и бэкэнд согласованно определяли границы между запросами. Иначе злоумышленник может отправить неоднозначный запрос, который будет интерпретирован фронтендом и бэкэндом по-разному:
В таком случае злоумышленник заставляет часть своего фронтенд-запроса интерпретироваться бэкэнд-сервером как начало следующего запроса. Фактически эта часть приклеивается к следующему запросу и способна вмешаться в то, как приложение обрабатывает этот запрос. Это и есть атака контрабанды запросов, и её последствия могут быть разрушительными.
Как возникают уязвимости контрабанды?
Большинство уязвимостей контрабанды HTTP-запросов возникает из-за того, что спецификация HTTP/1 предлагает два разных способа указать, где заканчивается запрос: заголовок Content-Length и заголовок Transfer-Encoding.
Заголовок Content-Length прост: он указывает длину тела сообщения в байтах. Например:
Заголовок Transfer-Encoding можно использовать, чтобы указать, что тело сообщения применяет блочное кодирование (chunked). Это означает, что тело сообщения содержит один или несколько блоков данных. Каждый блок состоит из размера блока в байтах (в шестнадцатеричном виде), за которым следует перевод строки, затем содержимое блока. Сообщение завершается блоком нулевого размера. Например:
Поскольку спецификация HTTP/1 предоставляет два разных метода указания длины HTTP-сообщений, одно сообщение может одновременно использовать оба метода, что приведет к конфликту. Спецификация пытается предотвратить эту проблему, заявляя, что если присутствуют и заголовок Content-Length, и заголовок Transfer-Encoding, то заголовок Content-Length следует игнорировать. Этого может быть достаточно, чтобы избежать неоднозначности, когда в работе участвует только один сервер, но не тогда, когда два и более сервера объединены в цепочку. В такой ситуации проблемы могут возникать по двум причинам:
Некоторые серверы не поддерживают заголовок
Transfer-Encodingв запросах.Некоторые серверы, поддерживающие заголовок
Transfer-Encoding, можно заставить его не обрабатывать, если заголовок обфусцирован.
Если фронтенд и бэкэнд ведут себя по-разному в отношении (возможно, обфусцированного) заголовка Transfer-Encoding, они могут быть не согласованы в границах между запросами, что приводит к уязвимостям контрабанды запросов.
Как выполнить атаку контрабанды
Классические атаки контрабанды запросов предполагают помещение в один HTTP/1 запрос и заголовка Content-Length, и заголовка Transfer-Encoding и такую их манипуляцию, чтобы фронтенд и бэкэнд обработали запрос по-разному. Точный способ зависит от поведения двух серверов:
CL.TE: фронтенд использует заголовокContent-Length, а бэкэнд использует заголовокTransfer-Encoding.TE.CL: фронтенд использует заголовокTransfer-Encoding, а бэкэнд использует заголовокContent-Length.TE.TE: и фронтенд, и бэкэнд поддерживают заголовокTransfer-Encoding, но один из серверов можно заставить его не обрабатывать, обфусцируя заголовок определённым образом.
Уязвимости типа CL.TE
Здесь фронтенд использует заголовок Content-Length, а бэкэнд — заголовок Transfer-Encoding. Можно выполнить простую атаку контрабанды следующим образом:
Фронтенд-сервер обрабатывает заголовок Content-Length и определяет, что тело запроса имеет длину 13 байт — до конца SMUGGLED. Этот запрос перенаправляется на бэкэнд-сервер. Бэкэнд-сервер обрабатывает заголовок Transfer-Encoding и, следовательно, трактует тело сообщения как использующее блочное (chunked) кодирование. Он обрабатывает первый блок, чей размер указан как нулевой, и, следовательно, воспринимает это как завершение запроса. Последующие байты, SMUGGLED, остаются необработанными, и бэкэнд-сервер воспримет их как начало следующего запроса в последовательности.
Уязвимости типа TE.CL
Здесь фронтенд использует заголовок Transfer-Encoding, а бэкэнд — заголовок Content-Length. Можно выполнить простую атаку контрабанды следующим образом:
Фронтенд-сервер обрабатывает заголовок Transfer-Encoding и, следовательно, трактует тело сообщения как использующее блочное кодирование. Он обрабатывает первый блок, чей размер указан как 8 байт, до начала строки, следующей за SMUGGLED. Затем он обрабатывает второй блок, чей размер равен нулю, и воспринимает это как завершение запроса. Этот запрос пересылается на бэкэнд-сервер.
Бэкэнд-сервер обрабатывает заголовок Content-Length и определяет, что тело запроса имеет длину 3 байта — до начала строки, следующей за 8 [после символа 8 идут два непечатаемых символа \r\n]. Последующие байты, начиная с SMUGGLED, остаются необработанными, и бэкэнд-сервер воспримет их как начало следующего запроса в последовательности.
Поведение TE.TE: обфускация заголовка TE
Здесь и фронтенд, и бэкэнд поддерживают заголовок Transfer-Encoding, но один из серверов можно заставить его не обрабатывать, обфусцировав заголовок тем или иным образом.
Способов обфусцировать заголовок Transfer-Encoding потенциально бесконечное множество. Например:
Каждый из этих приёмов предполагает тонкое отступление от спецификации HTTP. Реальный код, реализующий протокол, редко следует спецификации с абсолютной точностью, и разные реализации обычно по-разному терпимо относятся к отклонениям. Чтобы обнаружить уязвимость TE.TE, необходимо найти такой вариант заголовка Transfer-Encoding, при котором только один из серверов (фронтенд или бэкэнд) его обработает, а другой проигнорирует.
В зависимости от того, можно ли заставить игнорировать обфусцированный заголовок Transfer-Encoding фронтенд или бэкэнд, остальная часть атаки примет ту же форму, что и для уязвимостей CL.TE или TE.CL, описанных выше.
Как выявить уязвимости контрабанды
Обратитесь к следующему разделу за советами о том, как самостоятельно выявлять уязвимости контрабанды HTTP-запросов.
Как эксплуатировать уязвимости контрабанды
Теперь, когда вы знакомы с базовыми концепциями, давайте посмотрим, как контрабанда HTTP-запросов может использоваться для построения ряда атак высокой степени критичности.
Продвинутая контрабанда
Если вы уже прошли остальные лабораторные задания по контрабанде запросов, вы готовы изучить более продвинутые техники.
Контрабанда запросов на стороне браузера
Описанные вами до сих пор техники контрабанды запросов опираются на отправку намеренно некорректных запросов с помощью специализированных инструментов, таких как Burp Repeater. На самом деле те же атаки можно выполнить с использованием полностью совместимых с браузером запросов, которые рассинхронизируют два сервера посредством совершенно обычного заголовка Content-Length.
Это даже позволяет запускать варианты этих атак на стороне клиента, когда браузер жертвы отравляет собственное соединение с уязвимым сайтом. Это не только открывает одиночные серверные сайты для атак в стиле контрабанды запросов, но и позволяет атаковать сайты, к которым у вас нет прямого доступа.
Как предотвратить уязвимости контрабанды HTTP-запросов
Уязвимости контрабанды HTTP-запросов возникают в ситуациях, когда фронтенд-сервер и бэкэнд-сервер используют разные механизмы для определения границ между запросами. Это может быть связано с расхождениями в том, используют ли серверы HTTP/1 заголовок Content-Length или блочное кодирование для определения конца каждого запроса. В средах HTTP/2 распространённая практика понижения версии HTTP-2 для бэкэнда также чревата проблемами и включает или упрощает ряд дополнительных атак.
Чтобы предотвратить уязвимости контрабанды HTTP-запросов, используйте следующие рекомендации:
Используйте HTTP/2 сквозным образом (end to end) и по возможности отключайте понижение версии HTTP. HTTP/2 применяет надёжный механизм определения длины запросов и, при сквозном использовании, защищён от контрабанды запросов. Если избежать понижения версии нельзя, валидируйте переписанный запрос в соответствии со спецификацией HTTP/1.1. Например, отклоняйте запросы, содержащие переводы строки в заголовках, двоеточия в именах заголовков и пробелы в методе запроса.
Заставьте фронтенд-сервер нормализовать неоднозначные запросы, а бэкэнд-сервер — отклонять любые, которые остаются неоднозначными, при этом закрывая TCP-соединение.
Никогда не предполагайте, что у запросов не будет тела. Это фундаментальная причина уязвимостей как CL.0, так и клиентских десинхронизаций.
По умолчанию разрывайте соединение, если при обработке запросов срабатывают исключения на уровне сервера.
Если вы маршрутизируете трафик через прямой прокси (forward proxy), по возможности убедитесь, что включён upstream HTTP/2.
Как показано в учебных материалах, отключение повторного использования соединений с бэкэндом помогает смягчить некоторые виды атак, но это всё равно не защищает от атак туннелирования запросов.
Last updated