18 июля была опубликована информация о наборе уязвимостей, получившем название HTTPoxy. Используя его, злоумышленники могут подменять переменную окружения HTTP_PROXY, что позволяет им перенаправлять http-запросы к веб-приложениям на свои ресурсы.
Уязвимость была выявлена при участии разработчика компании Vend Доменика Шайрлинка (Dominic Scheirlinck), который в своем блоге на Medium рассказал о том, как она была обнаружена его коллегами в ходе разбора одного из тикетов, поступившем в службу поддержки.
Как это работает
Шайрлинк подробно объясняет принцип работы HTTPoxy. Типичная атака с использованием этого набора уязвимостей выглядит так:
- Атакующий создает специально составленный HTTP-запрос, в котором содержится заголовок Proxy;
- CGI получает запрос и сохраняет значение заголовка в переменную среды HTTP_PROXY;
- CGI приложение запускает собственный веб-клиент, использующий переменную среды HTTP_PROXY в качестве настроек прокси;
- Клиент отправляет запрос, который вместо адреса назначения проксируется через сервер атакующего.
К примеру, так может выглядеть код эксплуатации на нескольких популярных языках:
PHP:
$client = new GuzzleHttpClient();
$client->get('http://api.internal/?secret=foo')
Python:
from wsgiref.handlers import CGIHandler
def application(environ, start_response):
requests.get("http://api.internal/?secret=foo")
CGIHandler().run(application)
Go:
cgi.Serve(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
res, _ := http.Get("http://api.internal/?secret=foo")
// [...]
Более подробные PoC можно найти на GitHub в специальном репозитории HTTPoxy.
Интересный момент заключается в том, что сам баг, который используется в атаке HTTPoxy, был обнаружен пятнадцать лет назад. На сайте, посвященном HTTPoxy, представлено подробное описание истории уязвимости.
Согласно ему, в марте 2001 была обнаружена и исправлена ошибка некорректной обработки заголовков HTTP_PROXY в libwww-perl. В апреле того же года проблема была обнаружена в curl (и также исправлена, хотя и не для Windows). В 2012 году команда проекта Ruby разработала HTTP_PROXY для Net::HTTP — в их системе уязвимости не было.
В ноябре 2013 года она была упомянута в листе рассылки NGINX — пользователь Джонатан Мэттьюс описал ошибку, хотя и не был полностью уверен в своей правоте. В феврале 2015 года уязвимость также была упомянута в списке рассылке Apache httpd-dev. И уже в июле 2016 года сотрудник Vend Скот Джири (Scott Geary) обнаружил баг в реальной системе.
Какие системы уязвимы
Как выяснила команда безопасности Vend, уязвимость содержится во многих современных языках и библиотеках.
- CVE-2016-5386 Go
- CVE-2016-5387 Apache HTTPD
- CVE-2016-5388 Tomcat
- CVE-2016-1000104 mod_fcgi
- CVE-2016-1000105 Nginx cgi script
- CVE-2016-1000107 Erlang HTTP Server
- CVE-2016-1000108 YAWS
- CVE-2016-1000109 HHVM FastCGI
- CVE-2016-1000110 Python CGIHandler
- CVE-2016-1000111 Python twisted
Как обнаружить уязвимость в своем софте
Специалисты компании RedHat разработали небольшой скрипт, позволяющий определить, уязвима ли конкретная система к HTTPoxy.
Для этого администратору сервера необходимо установить следующий CGI-скрипт и сделать его исполняемым:
test.cgi:
#!/bin/sh
echo "Content-Type:text/plain"
echo ""
echo "HTTP_PROXY='$HTTP_PROXY'"
После этого следует вызвать CGI-скрипт с заголовком Proxy:
curl -H ‘Proxy: AFFECTED’ http://my-server-name/cgi-bin/test.cgi
Если вывод команды выглядит следующим образом — сервер не подвержен уязвимости:
HTTP_PROXY="
Если же вывод выглядит не так, к примеру отображается надпись ниже, то система уязвима:
HTTP_PROXY='AFFECTED'
Как защититься
Конечные пользователи веб-приложений в данной ситуации никак не могут повысить уровень своей безопасности, однако разработчики этого программного обеспечения имеют все возможности по его защите.
Для этого им нужно заблокировать заголовки запросов Proxy — сделать это можно очень быстро. Это не должно повредить функциональности приложения, поскольку такие заголовки являются нестандартными и обычно не используются.
К примеру, вот так можно отключить заголовки Proxy в Apache c помощью файла .htaccess:
<IfModule mod_headers.c>
RequestHeader unset Proxy
</IfModule>
Многие ИТ-компании и разработчики софта уже заявили о том, приняли меры к защите своих пользователей от уязвимости HTTPoxy — в их числе Akamai, CloudFlare, исправления выпустила и RedHat.
Эксперты Positive Technologies разработали сигнатуру для Suricata IDS, позволяющую обнаружить использование заголовка “Proxy” в HTTP запросах и предотвратить возможные последствия. Сигнатуру и пример эксплуатации можно найти в официальном репозитории twitter.com/AttackDetection/status/756142402268639232.
Автор: Positive Technologies