HTTP Smuggling
About
Атака, при которой фронт (front-end proxy, HTTP-enabled firewall или цепочка серверов с различной конфигурацией) воспринимает запрос как один (например, он открывает сокет с бэкенд сервером и в рамках одного сокета шлет запросы пользователей), а на бэке он распадается на два (бэкенд по специальным заголовкам понимает, где конец одного запроса и начало следующего).
Делается это с помощью заголовков Content-Length (CL) или Transfer-Encoding (TE).
Как это происходит?
Спецификация HTTP позволяет указать серверу, что запрос завершен, двумя способами. Использовать Content-Length или Transfer-Encoding: chunked.
Content-Length указывает сколько байтов тело запроса. Тогда как Transfer-Encodiing: chunked указывает, что тело запроса будет отправлено кусками, разделенными последовательностями новой строки, причем каждому фрагменту предшествует его размер в байтах (hexadecimal). Тело запроса заканчивается фрагментом нулевой длины.
Спецификация HTTP указывает, что при наличии CL и TE заголовков, CL следует игнорировать. Однако, по разным причинам при отправке обоих этих заголовков в одном запросе может возникнуть конфликты:
Некоторые HTTP сервера не поддерживают TE заголовок
Другие могут его игнорировать при использовании некоторых кодирований/обфускации
Направления проверок
CL.TE: фронт использует CL, бэк — TE
TE.CL: фронт использует TE, бэк — CL
TE.TE: и фронт и бэк используют TE, но они по разному реагируют на обфускацию заголовков
CL.TE
Пример запроса
В PortSwigger есть лаба: https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te
TE.CL
Пример запроса
В PortSwigger есть лаба: https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl Мое решение: https://gist.github.com/IkeMurami/45abe13216559cfb89d3b1397a53fd02
TE.TE
Как указано выше: оба сервера поддерживают заголовок TE, но если он обфусцирован немного, могут на него среагировать по разному. Наша задача: найти такую обфускацию, при которой один сервер обработает заголовок, другой — проигнорирует. Примеры обфускации заголовка:
PortSwigger Lab: https://portswigger.net/web-security/request-smuggling/lab-obfuscating-te-header
Решение:
2xCL
Использование двух Content-Length
— где-то может взяться первый Content-Length
, а на другом сервере — второй
Тогда с первого вернется: UNKNOWN HTTP Method GPOST (как детект)
Подробнее: https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
Еще трюк
I found another way to do HTTP smuggling, you can use T-E: chunKed K is the Kelvin symbol (%E2%84%AA) If the header is converted to lowercase, you get 'chunked' in ascii, if it's converted to uppercase it will stay the same (invalid)
Как детектировать
Timing Techniques
CL.TE Timing Detect
Отправляем незакрытый TE chunk — бэк сервер отваливается по таймауту
TE.CL Timing Detect
Фронт сервер получает запрос двумя чанками, собирает его и отправляет на бэк сервер. Бэк смотрит на CL и ждет остатки данных (которых не будет) => это вызывает значительные временные задержки
Differential responses
CL.TE
Суть в том, что на стороне бэкенд сервер, будет рассматривать этот запрос как:
Если получим 404, сервер уязвим к этому типу атаки
Еще пример из лабы:
TODO: почему это так работает — хз. Надо поднимать свою лабу и дебажить..
TE.CL
Если атака успешна, то на стороне бэкенд-сервера запрос пересоберется в:
Если получим 404 — сервер уязвим к этому типу атаки
Пример запроса:
Notes
При попытке проэксплуатировать этот тип уязвимости, следует помнить о некоторых важных соображениях:
Запросы с нормальным запросом и с пэйлоадом должны быть отправлены с разных сетевых подключений. Отправка обоих запросов через одно и то же соединение не докажет, что уязвимость существует
Запросы с нормальным запросом и с пэйлоадом должны использовать одни и те же имена URL и параметров, насколько это возможно. Тк балансер (фронт сервер) разные URL может отправить на разные бэкенд сервера. Использование одного набора URL и параметров повысит вероятность успешной атаки.
Так как можем попасть в гонку с другими запросами других пользователей, может потребоваться несколько раз провести отправку нормальных и запросов с пэйлоадами для подтверждения уязвимости.
При подтверждении уязвимости надо стараться не затрагивать других пользователей.
Tools
Smuggler extension for Burp: https://kalilinuxtutorials.com/http-request-smuggler-extension-burp-suite/
Python script: https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
WebSocket Smuggle: https://github.com/0ang3el/websocket-smuggle/blob/master/README.md
Exploiting
Source: https://portswigger.net/web-security/request-smuggling/exploiting
Bypass security controls
Rewriting front-end request
Bypass client authentication
Lead to client-side bugs:
Open Redirect
rXSS
WebCache Poisoning
Example: Bypass security control
CL.TE
Пусть фронт-сервер пропускает запросы только к /home. Фронт-сервер видит два запроса /home (синий+красный и зеленый) и он перенаправляет их на бэкенд-сервер.
Бэкенд сервер видит два HTTP-запроса — синий (/home) и красный+зеленый (/admin).
TODO
Сделать лабу на HTTP Smuggling
Mitigation
Убедитесь, что одно и то же серверное программное обеспечение используется как на внешнем, так и на внутреннем серверах, чтобы они синхронизировались, какой заголовок они будут использовать, чтобы предотвратить конфликты (либо Content-Length, либо Transfer Encoding: chunked).
Некоторые провайдеры WAF уже имеют встроенные средства защиты при обнаружении аномальных запросов. Уточните у своего провайдера, есть ли у него поддержка для этого.
Отключите повторное использование внутренних соединений, чтобы каждый внутренний запрос отправлялся через отдельное сетевое соединение.
Papers
Статьи: https://habr.com/ru/post/468489/ https://blog.deteact.com/gunicorn-http-request-smuggling/ https://portswigger.net/web-security/request-smuggling https://www.rcesecurity.com/2020/11/Smuggling-an-un-exploitable-xss/
Labs
HTTP Smuggling lab: здесь внутри и на сокетах и в разных конфигурациях и тп https://github.com/ZeddYu/HTTP-Smuggling-Lab
И норм материал к этому: https://regilero.github.io/english/security/2019/10/17/security_apache_traffic_server_http_smuggling/
Мое скрипт по решению этих лаб: https://github.com/IkeMurami/zscanutils/blob/main/scripts/http_request_over_sockets.py
Last updated