• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Гостевая статья ModSecurity DoS + PoC CVE-2019-19886

В октябре 2019 года мы с Эрвином Хегедусом обнаружили две уязвимости в брандмауэре веб-приложений с открытым исходным кодом «libModSecurity» (CVE-2019-19886 от версии 3.0.0 до 3.0.3), которые могут привести к обходу SecRule и отказу в обслуживании. В этой статье я опишу обе уязвимости с помощью PoC на Nginx.


Согласно проекту ModSecurity, libModSecurity является одним из компонентов проекта ModSecurity v3. Кодовая база библиотеки служит интерфейсом для коннекторов ModSecurity, принимающих веб-трафик и применяющих традиционную обработку ModSecurity. В целом, он предоставляет возможность загружать / интерпретировать правила, написанные в формате SecRules, и применять их к HTTP-контенту, предоставленному вашим приложением через Connectors.

Благодаря Эрвину Хегедусу, который, как и я, является членом команды разработчиков OWASP Core Rule Set, мы выявили некоторые проблемы в парсере строк cookie в версиях libModSecurity 3.0.0-3.0.3. Чтобы упростить процесс тестирования, Эрвин создал отдельную программу на C ++ под названием «cookieparse», которая считывает строку cookie из первого аргумента и анализирует ее, сравнивая результаты между «старой» и исправленной версией парсера. Но давайте сделаем шаг назад и сосредоточимся на cookies/

Обход SecRule

Для протокола HTTP строка cookie - это последовательность пар ключ = значение, разделенных символом ";".

c.png

Запрос строки cookie

Даже если поначалу это выглядит просто, есть много способов привести парсер к виду, который не соответствуют тому, что обеспечивает стандарт,например:

f.png


Что меня здесь удивило, так это то, что согласно RFC 6265 строка cookie, отправленная без символа "=", должна полностью игнорироваться. Еще одна интересная вещь:

gt.png


В пункте 3 кажется, что cookie может иметь пустое значение или пустое имя. Я никогда не думал о том, чтобы проверить, что будет делать брандмауэр приложения, пытающийся проанализировать файл cookie с пустым именем. Используя cookieparse, Эрвин обнаружил, что старый парсер не включает часть значения cookie, если строка cookie имеет вид "foo = bar = ciao" :

yh.png


cookieparse output

Как видите, для старого парсера значение cookie foo равно bar, а не bar = ciao, как должно быть. Это означает, что можно внедрить вредоносную полезную нагрузку (такую как SQL-инъекция или межсайтовый скриптинг), просто поместив ее после символа =. Например:

uj.png


cookieparse output with XSS payload

Старый синтаксический анализатор полностью игнорировал бы полезную нагрузку XSS, и можно было бы обойти гипотетическое правило, которое проверяет, содержит ли значение cookie вредоносное содержимое.

DoS уязвимость

Продолжая наши обходные тесты, то, что я обнаружил после, напугало нас и заставило попросить у Trustwave патч и релиз безопасности. Как мы уже говорили, в строке cookie каждое имя и значение отделяются символом =, а каждая пара имя / значение файла cookie - символом ; . После нескольких тестов я начал ставить случайные последовательности ; и = пытается разбить его. Отправив ;=; ничего не произошло, кроме удаления первого ; / что-то пошло не так. Старый парсер выдал следующую ошибку:

io.png


Разговаривая с Эрвином о последствиях, которые эта ошибка может иметь для веб-сервера, на котором работает libModSecurity, я создал докер-контейнер с Nginx и libModSecurity 3.0.3. Отправляя один запрос с заголовком Cookie: = foo Я неполучил никакого ответа от веб-сервера, даже часть заголовка ответа.

ty.png


Nginx error_logs (вверху), curl output (внизу)

При чтении журнала ошибок Nginx становится ясно, что мой предыдущий запрос уничтожил рабочий процесс Nginx, который записал в журнал ту же ошибку «out of range ». С этого момента мне было действительно легко завалить Nginx,просто отправив несколько запросов с помощью curl и непрерывно уничтожая перезапускающиеся рабочие процессы Nginx с помощью:

curl -H 'Cookie: =;' 'http://localhost/?a=[0-10000]'

Протестировав это с Nginx, который проксирует все запросы к WordPress, вот что произошло:

op.png


 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!