Вилкой в **** или WAF Bypass — тестируем Web Application Firewall

Итак, вы купили компьютер Web Application Firewall. В каком количестве предстоит ловить ложно-положительные срабатывания (False Positive), вы, как счастливый обладатель коммерческого продукта (а не какого-то там бесплатного), вскоре узнаете. Если повезет — их будет мало, если нет — готовьтесь постоянно составлять правила исключения.

Есть несколько критериев, по которым можно оценивать WAF, но основные из них — количество ложно-положительных (FP) и ложно-отрицательных (FN — False Negative) срабатываний. Если оценить количество FP можно сразу после ввода WAF в эксплуатацию, то пропуски атак выявить сложнее. Чаще всего для этого используются различные сканеры уязвимостей, вроде Acunetix или Wapiti, но это не совсем правильно, т.к. основной упор в них делается на поиск недостатков веб-приложений, а не WAF.

Информация предоставлена исключительно в ознакомительных целях. Инструментарий не предназначен для использования в противоправных или противозаконных целях. Не нарушайте законодательство.

WAF Bypass Tool

Являясь разработчиком WAF, перед каждым релизом мы проводим его тестирование, одним из основных этапов которого является поиск пропусков атак. Поняв, что сканеры уязвимостей работают долго и не решают эту задачу полностью, мы начали писать собственные тесты. Так появился еще один инструмент — WAF Bypass.

Шли годы, появлялись новые техники обхода WAF, которые мы добавляли и меняли подход к написанию полезных нагрузок, поэтому некоторые первые пейлоады выглядят немного коряво, но со временим мы до них доберемся. WAF Bypass содержит наборы полезных нагрузок для проверки разных типов уязвимостей — от XSS и SQLi до раскрытия чувствительных данных и открытого редиректа:

  • Open Redirect (OR)

  • Cross Site Scripting (XSS)

  • Remote File Execution (RCE)

  • Server-Side Request Forgery (SSRF)

  • Local and Remote File Include (LFI / RFI)

  • Injection (SQLi, NoSQLi, LDAP, SSI, SSTI)

  • Unwanted Access или sensitive data disclosure (UWA)

WAF Bypass содержит множество различных способов обхода, например такие:

  • множественный URLEncode

  • Base64Encode

  • HTML Entity Encode

  • UTF-8/16 Encode

  • UTF-8 Text Collation

  • манипуляции с multipart/form-boundary

  • использование специфичного метода (HTTP method)

  • Расщепление запроса с использованием различных символов (null-byte, экранирование и прочее)

  • и другие.

Принцип работы

WAF Bypass написан на Python 3 и распространяется в виде готовых скриптов или Docker-образа. Поддержка различный опций (использование прокси-сервера, ограничение параллельных потоков, тайматутов, определение блок-кодов ответа сервера и т.д.) позволяет гибко управлять инструментом, результаты выводятся в консоль в виде таблиц или в JSON-формате (удобно для интеграции с собственными ИБ-системами или сервисами).

Вывод в формате таблицыВывод в формате таблицы

В процессе сканирования происходит отправка больше 2.000 запросов, при этом скрипт контролирует ответы от сервера на случай, если тестируемый WAF забанил IP или начал возвращать некорректный ответ.

Вывод в JSON-формате после обработки утилитой jq (bash)Вывод в JSON-формате после обработки утилитой jq (bash)

Параметры запуска

WAF Bypass содержит основные и дополнительные параметры запуска. Для быстрого старта достаточно склонировать проект, установить необходимые PIP-зависимости и указать цель. Перед использованием отключите функционал авто-бана в WAF.

# git clone https://github.com/nemesida-waf/waf_bypass.git /opt/waf-bypass/
# python3 -m pip install -r /opt/waf-bypass/requirements.txt
# python3 /opt/waf-bypass/main.py --host='example.com'

Не пытайтесь повторить это дома! Только на улице ©

Дополнительные параметры позволяют сделать управление инструментом более гибким:

  • '--proxy' (--proxy='http://proxy.example.com:3128') — адрес прокси-сервера для доступа к цели.

  • '--header' (--header 'Authorization: Basic YWRtaW46YWRtaW4=' or --header 'Authorization: Basic YWRtaW46YWRtaW4=' --header 'X-TOKEN: ABCDEF') — позволяет задать дополнительные заголовки (полезно, если цель использует Basic-аутентификацию или другие механизмы ограничения доступа.

  • '--block-code' (--block-code='222' or --block-code='403' --block-code='222') — позволяет задать статус (ы) ответа WAF при блокировании запроса (полезно, если WAF использует отличные от 403 статусы ответа или использует различные статусы для разных типов блокировок).

  • '--threads' (--threads=15) — позволяет задать количество параллельных потоков при сканировании (по умолчанию 10).

  • '--timeout' (--timeout=10) — позволяет задать время ожидания ответа от сервера (по умолчанию 30).

  • '--json-format' — вывод результатов в формате JSON (по умолчанию в виде таблиц).

Примеры обходов

Пока писал статью — забыл про все техники байпасов, также, как и все забыли про нашумевший в в конце 21 года Log4Shell. Хорошо, что есть выступление на PHDays, где рассказываю об обходе WAF и недостатках сигнатурного анализа.

Все, вспомнил! Начну с простого, но понятного примера — если веб-приложение позволяет взаимодействовать с bash и мы можем проэксплуатировать RCE, например:

cmd=...; /bin/cat /etc/passwd

Мы получим 403, т.к. WAF находит в запросе вхождение /etc/passwd. Используя особенность преобразования bash, обфусцируем (какое красивое слово) пейлоад:

cmd=...; /bin/cat /et?/pa??wd

Попробуйте выполнить это в консоли, чтобы убедиться, что работает (главное, не удалите французскую локаль: rm -fr). Вот и первый способ обхода.

Пример второй. Используя ту же полезную нагрузку (чтоб два раза не вставать), выполним двойное экранирование:

cmd=...; /bin/cat /etc\\/pa\\ss\\wd

До bash нагрузка дойдет в виде cmd=...; /bin/cat /etc\/pa\ss\wd, где отлично отработает интерпретатором. На этом, конечно же, мы останавливаться не будет и продолжим офускацию:

cmd=...; /b'i'n\/?at /e't'c\/\pa??\wd

Опять же, на радостях главное не удалять французскую локаль! Ладно, думаю, суть байпаса понятна, давайте разберем другие примеры.

Вы, наверное, знаете, про конструкцию alert('1'). Но результат можно представить и другими способами:

onerror='alert`1`'
top[/al/.source+/ert/.source](1)
al\u0065rt(1)

А пейлоад x может выглядеть так:

x

Ну и в завершении, для тех, кто считает, что SQL-инъекция обязательно должна содержать скобки и кавычки, можно рассмотреть такой пейлоад:

1 union select password from users

То есть в БД уйдет примерно такой запрос:

SELECT foo FROM bar WHERE id = 1 UNION SELECT password FROM users;

Кстати, с SQLi есть еще одна фишка — в строке поиска можно использовать другой набор символов UTF-8 Text. Выглядеть это будет примерно так:

SELECT * FROM users WHERE name LIKE 'admin';

admin, представленный набором Halfwidth and Fullwidth Forms, будет равносильно admin (Basic Latin), несмотря на то, что это разные наборы символов — то есть результат выполнения SQL будет идентичным, но WAF, скорее всего, не сможет нормализовать символы до Basic Latin.

Заключение

Количество пропусков атак зависит от разных факторов: какие механизмы и способы нормализации запросов используются, насколько качественно они написаны, насколько качественно написан сам код и т.д. Единственное, что может объединять такие решение — наличие этих пропусков. Можно много и красиво рассказывать о «черных рынках», куда плохие ребята ходят за хлебом и байпасами, можно парсить различные паблики и твиттер, но с этой проблемой нужно бороться. WAF Bypass позволяет узнать о недостатках вашего WAF раньше, чем это сделает злоумышленник.

Если статья вам понравилась — ставьте лайки и звоните на пейджер, или просто задавайте вопросы в комментариях.

© Habrahabr.ru