7 октября 2019 года директор отдела исследований PortSwigger (производителя BurpSuite) опубликовал исследование о новых подходах к HTTP Request smuggling. С их помощью он заработал на bugbounty около $70000. В этой заметке мы коротко выясним суть атаки, инструментарий, а также методики исследования веб серверов, подверженных этой уязвимости. HTTP Request smuggling — атака, направленная на рассинхронизацию frontend веб-сервера и backend веб-сервера, в результате чего злоумышленник может "контрабандой" пронести HTTP запрос мимо Frontend сервера. Картинка из оригинальной статьи служит хорошей демонстрацией:  Подобная атака может привести к самым различным последствиям — внедрению XSS в сессии других пользователей, редиректу пользователей на сторонние ресурсы, отравлению кэша сервера, подобию SSRF и ряду других. В инкарнации HTTP Smuggling 2019 года Джеймс Кеттл эксплуатировал некорректную обработку веб-серверами заголовка  сообщающую, что тело сообщения будет передано частями (RFC). Из-за того, что некоторые веб-серверы не поддерживают chunked передачу, либо по-разному обрабатывают заголовок, frontend будет "видеть" только один запрос, а backend его распознает как два. Более подробно с деталями атаки можно ознакомиться в оригинальной статье, там же есть практическое задание, на котором можно потренироваться находить уязвимость вручную. Для быстрого поиска Джеймс разработал плагин для BurpSuit, на вход принимающий запрос, а на выходе создающий отметку об уязвимости сервиса (если таковая найдется). Нужно сказать, что проблематикой smuggling и других уязвимостей, связанных с работой веб-серверов давно занимается другой исследователь под ником regilero. За последние три года он опубликовал три статьи, описывающие найденные им уязвимости в популярных веб-серверах, большинству из которых присвоены CVE средней и высокой степени критичности. В числе уязвимых серверов — Apache Traffic Server, Jetty, Apsis.  На волне интереса к проблеме, другой исследователь — Nathan Davison, обнаружил уязвимость в HAProxy, который игнорировал некорректно сформированный заголовок и преобразовывал его в следующий вид: Но backend сервер — gunicorn, проксирующий приложение на Flask, заголовок считывал, что и провоцировало уязвимость. Несколько позже ряд других исследователей обнаружили уязвимость (присвоена CVE-2019-16276) в реализации http сервера golang — сервер нормализировал заголовок, если перед доветочием стоял пробел.
Запрос:  После обработки сервером:  Уязвимость могла быть проэксплуатирована в случае, если frontend сервер игнорировал заголовок с пробелом, и использовал Content-Length для подсчета размера запроса. Веб-сервер Caddy, написаный на Go, также был уязвим, поскольку использовал ту же самую библиотеку net/http. Разработчики подтвердили, что после обновления GO и пересборки пакета, проблема исчезает. Автор данной статьи нашел аналогичную проблему в сервере lighthttpd (CVE присвоена не была). На скриншоте видно, что сервер принимает и обрабатывает заголовок, содержащий пробел:   Разработчики не совсем согласны с RFC 7230 (да и автор тоже), и считают что ответственность за некорректную обработку заголовков лежит на прокси, которые пересылают запросы без их нормализации и проверки. Тем не менее, в новом релизе баг будет пофикшен: Такой же баг обнаружен в веб сервере cheroot, используемом фреймворком cherrypy. Этот мини-фреймворк встречается в стартапах, его часто используют для написания API. Баг-репорт висит в статусе opened.  Итак, что же является необходимыми условиями для проверки и эксплуатации уязвимости: Для лучшего понимания и поиска проблем в существующих веб-серверах и прокси разумно развернуть тестовую среду у себя локально с помощью Docker. Пример схемы тестовой среды:  Код приложения: Файл с настройками фронтенда, на примере caddy: Дальше все просто, запускаем приложение: И контейнер: Из магазина Burp устанавливаем HTTP Request Smuggler и Logger ++ для удобства отладки. Далее в Repeater формируем простой запрос, например такой: И отсылаем его, чтобы проверить что все настроено корректно: Теперь запускаем Launch Smuggle Probe и смотрим на ответы.   Самое интересное начинается именно в этот момент. Нужно анализировать запросы и ответы, чтобы понять уязвимы сервисы или нет. Эту часть оставим для пытливого читателя.