DoS-уязвимость в HTTP-сервере Apache

0
5

Недавно, была обнаружена уязвимость в веб-сервере Apache, которой подвержены практически все его версии.

Уже доступен эксплоит, который в несколько десятков потоков выполняет простой скрипт:

HEAD / HTTP/1.1
Host: www.example.com
Range: bytes=0-,50,51,52,53,54,,51299,51300
Accept-Encoding: gzip
Connection: close

Тем самым вызывая сбой, связанный с тем, что при обработке запроса, содержащего большое число диапазонов (например, «Range:bytes=0-,5-1,5-2,5-3,…,5-1000″) в сочетании с использованием gzip-сжатия отдаваемого контента, расходуется слишком много памяти. Например, если в заголовке Range передана тысяча диапазонов, то Apache пытается отдельно сжать каждый диапазон. Так как каждая операция сжатия требует достаточно много памяти (даже для сжатия одного байта выделяется буфер для сжатия блока), в сумме легко исчерпать всю доступную память. Для осуществления удачной атаки достаточно отправить около 50 подобных запросов с составным Range на сервер.

Чтобы проверить, подвержен атаке ваш сервер или нет, стоит выполнить команду: (файл обязательно должен быть статическим)

curl I H «Range: bytes=0-1,0-2» s www.example.com/static_file.txt | grep Partial

и если в ответ получаете — 206 Partial Content, то ваш сервер — надо защитить.

Блокировка длительных последовательностей Range в Apache

Внесите один из вариантов в .htaccess:

# Вариант 1:
RewriteEngine On
RewriteCond %{HTTP:Range} bytes=0-[09]+, [NC,OR]
RewriteCond %{HTTP:Range} bytes=([09-],){4,} [NC,OR]
RewriteCond %{HTTP:Range} bytes=[09,-]+,0-(,|$) [NC]
RewriteRule . http://%{SERVER_NAME}/ [NS,L,F]
# Вариант 2:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(HEAD|GET) [NC]
RewriteCond %{HTTP:Range} ([09]*-[09]*)(\s*,\s*[09]*-[09]*)+
RewriteRule .* — [F]
# Вариант 3:
RewriteEngine On RewriteCond %{HTTP:Range} bytes=0-.* [NC]
RewriteRule . http://%{SERVER_NAME}/ [R=302,L]

Блокировка длительных последовательностей Range в nginx

Добавить директивы:

proxy_set_header Range «»;
proxy_set_header Request-Range «»;

Решение от разработчиков Apache

Так, как уязвимость может быть эксплуатирована и через заголовок Request-Range, то следует применить это решение:
Использование SetEnvIf для Apache 2.0 и 2.2:

# Удаляем заголовок Range, если в нем более 5 диапазонов
SetEnvIf Range (:,.*){5,5} bad-range=1
RequestHeader unset Range env=bad-range
RequestHeader unset Request-Range
# помещаем в лог попытки атаки
CustomLog logs/range-CVE-20113192.log common env=bad-range

Использование mod_rewrite для Apache 1.3 и 2.x:

RewriteEngine on
RewriteCond %{HTTP:range} !(bytes=[^,]+(,[^,]+){0,4}$|^$)
RewriteRule .* — [F]
RequestHeader unset Request-Range

Официальный отчет о наличии уязвимости