Apache -X0 или http запрос с пустым методом как вектор атаки

Хотим рассказать о поведении вебсерверов на не совсем обычные запросы и то, что код иногда обрабатывает их не так, как вы ожидаете на примере куска легаси кода. Так же затронем очевидные прописные истины аналогичные “Почему вебсервер должен быть первой линией обороны” и “Почему вы должны знать все о вашей конфигурации”.

TL;DR; Apache из дефолтной конфигурации принимает все методы (Request method) и передает на сторону сервера приложения.

Во время анализа кода одной CMS был обнаружен такой кусок кода, что представлен ниже. Что-то в нем сразу насторожило!

weak code

Пример уязвимого кода: https://gitlab.com/dc20e6/research/apache-x0

Как потом узнали у разработчиков, они считали что “Не может быть запроса” без метода. И поэтому оставили console mod без авторизации, так как если у тебя есть доступ к SSH, то тебя уже мало что остановит. Соответсвенно все действия администратора можно провести без авторизации, если ты в console mode.

Если что, правильный путь это проверять тип интерфейса через PHP: php_sapi_name, но мы то знаем что каждый самый умный и знает как делать правильно :) И давайте посмотрим как можно оботи проверку, указанную выше. Так как мофицировать код у нас нет прав, да и задачи такой нет, то будем смотреть на то, как это обрабатывается на стороне веб-сервера.

NGINX, lighttpd

Эти вебсерверы проверяют все согласно RFC (в основном rfc7231 и rfc7237 и ничего лишнего не пропускают, выплевывая на запросы кроме тех, что разрешены ошибки. Как по мне – использование white list в данной ситуации логично и правильно.

nginx method check 1 nginx method check 2

light method check 1 light method check 2

Apache

Но вот ребята из Apache Software Foundation решили иначе и из коробки пропускают все, что ты передашь как метод.

apache method check

Понимая это и зная что в CURL можно играться с методами приступим к фаззингу. И после непродолжительной операции мы видим, что такую проверку можно забейпасить запросом curl -X0 ....

Да, удивлению не было предела. Действительно 0 (aka zero) воспринимается Apache как пустой метод.

Таким образом POC этого “0-Day” выглядит вот так

curl -X 0 -v 'https://web.local/admin.php?...&user_id=1&user_data[password1]=NewP4ssw0rd&user_data[password2]=NewP4ssw0rd'

И так можно сбросить пароль главного админа минуя авторизацию, но это, как понимаете, только начало, если мы хотим что-то больше пенетратить ;)

Обратившись к поиску, например по GitHub с запросом empty($_SERVER['REQUEST_METHOD, мы можем понять что так делают и количество упоминаний такой простой проверки 1M+.

И согласно февральского отчета 2018 года от Netcraft мы видим что у Apache подавляющее большинство серверов February 2018 Web Server Survey.

Фикс для Apache

Фикс для конфигурации Apache простой и заключается в указании разрешенных методов

<LimitExcept GET POST HEAD>
    Order deny,allow
    Deny from all
</LimitExcept>

Ах, да, про истины

  • “вебсервер должен быть первой линией обороны”. Тут теперь надеюсь, стало еще понятнее после прочтения статьи.
  • “вы должны знать все о вашей конфигурации”. А тут могу порекомендовать читать документации, следить за исследованиями, обновляться и не ставить “галку” автоматический режим. Описывайте вашу инфраструктуру в формате IaC (Infrastructure as Code), ведь хорошо что за окном 2k19 и есть множество инструментов для этого, подобных Salt/Ansible/Terraform.

Выводы тут нужно делать каждому самому, как и то, что делать дальше с этой информацией тоже ;)

Да, немного кэп, но все-таки подавляющее большинство не конфигурируют сервера, а пользуются дефолтными конфигами.

P.S.

Хотелось бы порекомендовать посмотреть доклады со встречи [0x03] - Как делать разработку WEB приложений безопаснее и корректнее, а сервера устойчивее , где мы говорили про настройки серверов, а также заопенсурсили то, о чем говорили :)


Исследование было проведено участником сообщества DC20e6 Алексеем @extor Егорычевым