Правила корреляции в KUMA (CookBook)
Этакий "CookBook" по правилам корреляции в KUMA
- Типы правил корреляции
- Активные листы в корреляторе
- Приемы в правилах корреляции
- Тестирование правил корреляции
- Производительность правил корреляции
- Сегментация правил корреляции
Типы правил корреляции
Простое правило (simple)
“Обновить параметры” нужно делать в корреляторе, когда какое-либо правило меняется, чтобы подтянулись актуальные изменения в правилах в коррелятор.
Простое правило (simple) — срабатывает при обнаружении каждого события, удовлетворяющего условиям в одном селекторе.
Типовой пример правила:
Наследуемые поля передаются события из исходного в корреляционное.
Необходимо указывать все поля и переменные участвующие в селекторах в наследуемых полях.
Стандартное правило (standard)
“Обновить параметры” нужно делать в корреляторе, когда какое-либо правило меняется, чтобы подтянулись актуальные изменения в правилах в коррелятор.
Стандартное правило (standard) — срабатывает при достижении определенного порогового значения группы событий, которые удовлетворяют условиям селектора, полей группировки событий (на основе значений поля создается группа) и времени жизни контейнера для группы.
Если частота срабатывания (Rate limiting) явна не указана, то устанавливается лимит умолчанию - 100 срабатываний в секунду. При превышении лимита правило ничего не делает.
Политика хранения базовых событий (Base events keep policy) - указание, какие из базовых событий должны сохраняться в корреляционном. Возможно указать одно из значений:
- first (по умолчанию) - сохранять только первое базовое событие от каждого селектора в корреляционном событии
- last - сохранять только последнее базовое событие от каждого селектора в корреляционном событии
- all - сохранять все базовые события в корреляционном событии
Типовой пример правила:
Возможные действия (допускается указать одно или более) правила:
- On first threshold — создавать корреляционное событие только после первого превышения порога, а двукратное, трехкратное и т.д. превышение порога за время жизни группы игнорировать.
- On every threshold — создавать корреляционное событие после каждого превышения порога за время жизни группы.
- On subsequent threshold — создавать корреляционные событие при всех превышениях порога, кроме первого.
- On timeout — в стандартных правилах есть еще возможность настройки действий по окончании времени жизни группы. Это действие используется в связке с опцией Recovery (Обнуление) в настройках селектора, в каких случаях это уместно и как именно это работает рассматривается ниже.
Необходимо указывать все поля и переменные участвующие в селекторах в группирующих/уникальных полях.
Можно также использовать несколько селекторов. Например, несколько неудачных попыток брутфорса (ловится на основе сработки другого правила корреляции) и успешный вход.
Пример правила с несколькими селекторами:
Можно также рекавери правило. Например, когда событие типа «Вредоносное ПО удалено» не обнаружено в течение 5 минут после получения события «Вредоносное ПО обнаружено».
Бакет (Окно корреляции)
- Бакет открывается на событие из любого селектора, не важно в каком они порядке в правиле, порядок проверяется после наполнения бакета!
- Для каждого набора Identical Fields создается свой бакет.
- Когда событие подпадает под селектор, коррелятор смотрит, есть ли уже бакет с нужным набором полей Identical Fields, если нет - создает, если есть - событие отправляется в существующий.
- Когда под селектор с Unique fields подпадает событие, то проверяется, есть ли уже в бакете события с таким же набором значений для Unique Fields, если есть, то событие не учитывается.
Recovery селектор (Обнуление)
- Бакет открывается только на событие из обычного селектора, на событие из recovery-селектора бакет не открывается никогда!
- Место нахождения селектора с recovery не имеет значения, как только в бакет попадут все нужные recovery-события бакет будет закрыт!
- На recovery-селектор не влияет настройка фильтра Order By.
- Если нужно, чтобы произошло событие А, и не произошло событие Б, при этом событие Б может произойти раньше А, нужно использовать активные листы, т.к. с помощью recovery-селектора такой логики не достичь (см п.1).
Операционное правило (operational)
“Обновить параметры” нужно делать в корреляторе, когда какое-либо правило меняется, чтобы подтянулись актуальные изменения в правилах в коррелятор.
Операционное правило (operational) — наполняют активные листы без создания корреляционного события, механика работы аналогична простому правилу корреляции.
Чтобы просмотреть содержимое списка нужно открыть список активных сервисов (Active services), выбрать службу типа Correlator (поставить галочку слева) и у нее появится активная кнопка Go to active lists (Перейти в активные листы).
При записи в активный лист, в качестве ключевого поля могут быть несколько занчений полей события, для составления комбинированного ключа, при этом в значении ключа это быдет выглядеть так: поле1|поле2|поле3
Активные листы в корреляторе
Активный лист – это контейнер для данных (представляет собой структуру ключ и значение), предназначенный для быстрой записи/чтения динамических данных, доступных всем фильтрам и корреляционным правилам в рамках одного сервиса Коррелятора. Чтобы их посмотреть, нужно из активных сервисов нажать кнопку Смотреть активные листы.
Взаимодействовать с активным листом могут не только компоненты коррелятора, но и пользователи, с помощью Web-консоли и API.
Активные листы работают в памяти коррелятора, также при работе активного листа используется Write-Ahead Log (WAL), который предполагает сохранение каждого изменения состояния в виде двоичного файла на жестком диске. Каждой записи журнала присваивается уникальный идентификатор, позволяющий выполнять дополнительные операции с журналом, такие как сегментация журнала и очистка. Уникальность записей журнала также помогает применять обновления журнала с использованием единой очереди обновлений, обеспечивая последовательные и согласованные обновления.
Синхронизация активного листа между несколькими корреляторами. ВАЖНО это не поддерживаемый и не официальный сценарий. Можно попробовать сделать так: WAL записывается на сетевую папку, примонтиованную к двум корреляторам. И если один из корреляторов упал, скрипт (заранее написанный) запускает службу второго коррелятора. Второй коррелятор перечитает WAL и импортирует данные в лист.
Приемы в правилах корреляции
Сравнение с константой
Сравнение с листом/списком
Аналогично =константе ИЛИ =константе
Содержит список констант регистронезависимый
Ищется заданная подстрока “whoami” или "ipconfig" и др в занчении поля DestinationProcessName
Соответствие регулярному выражению (REGEX)
Должно быть условие регулярного выражения в формате RE2
Работа с подсетями
Содержит любое значение (не пустое)
Активный лист содержит ключ
Ключ листа должен совпадать со значением поля Message
Сравнение по экстра данным в активном листе (неключевому полю)
Где threat_score > 70
Условие с полем TI, сравнение с категорией
Значение feed это именование фидов из CyberTrace, например для фидов Kaspersky бывают такие значения (зависит какие фиды приобретены/подключены):
Фильтр по количеству записей по ключу в активном листе
Где количество записей > 1, используется служебная переменная _count
Другие служебные поля активных листов:
- _count (счетчик количества записей)
- _created (время создания записи UnixTime, в наносекундах)
- _updated (время обновления записи UnixTime, в наносекундах)
- _expires (время окончания жизни записи UnixTime, в наносекундах)
- _key (значение ключевой записи)
Событие истечения времени жизни в активном листе
Возникает служебное событие active list record expired, помимо этого необходимо указать UUID активного листа в поле DeviceExternalID
Значение ключевого поля передатся в DevicePayloadID служебного события.
Работа с активным листом не по его ID
Если указывать ID листа неудобно (а это обычно так), то можно в ключевое поле писать уникальный префикс типа "failed login attempts|username|1.1.1.1" и в события ловить по полю devicePayloadID функцией startsWith "failed login attempts" такой вариант реализации правила не зависит от инсталляции.
Такие события существуют только в рамках коррелятора (служебные события) и не сохраняются в сторадже, их можно поймать только правилом корреляции.
Работа с группами AD
Необходимо указывать полный DN, пример:
Условие фильтра:
Актив находится в определенной категории
Работа с полем Extra в селекторе
Работа с полями типа SA (массив строк) KUMA 3.0+
При операции match к полям типа SA применяется как к строке, т.е. массив представляется в виде строки ["a1", "b2", "c3"] и т.д. Т.е. ко всему массиву сразу, а не к отдельным его элементам по очереди.
При операции contains применяется именно к элементам массива. Т.е. contains [ для массива вернет false, как и contains " или '. Но при этом же, если в массиве есть элемент abc, то contains abc вернет true и contains ab тоже вернет true
Работа с переменными (KUMA 2.1+)
Вход в рабочее время
Документация по функциям переменных.
Сначала извлекается час из таймштемпа, с помощью функции: extract_from_timestamp(Timestamp, ‘h’, ‘Europe/Moscow’)
Условие в селекторе:
Переменные необходимо указывать в группирующих полях:
Работа с Extra
Здесь вместо Event.System.Channel нужно указать интересующее вас поле экстра. Регулярка: ."Event\.System\.Channel":"([^"]+)".
Работа с контекстной таблицей (KUMA 3.0+)
Пример Контестной таблицы:
Примеры переменных:
Извлечение содержимого поля с массивом pc
из контекстной таблицы в тенанте Shared
(только для этого тенанта нужно в переменной это указывать) по ключевому полю user
и его значением DestinationUserName
, назовем переменную ct_value
:
context_table('pc-user@Shared', 'pc', 'user', DestinationUserName)
В событии выглядит это так:
Получение индекса (номер символа) по содержимому поля массива pc
по значению поля DestinationHostName
из контекстной таблицы в тенанте Shared (только для этого тенанта нужно в переменной это указывать) по ключевому полю user и его значением DestinationUserName, назовем переменную ct_contains
:
index_of(DestinationHostName, $ct_value)
Возвращает первую позицию символа или подстроки в строке, расчет индекса начинается с 0. Если в результате работы функции подстрока не была найдена, функция вернёт значение -922337203685477580
Вот как выглядит это в событии, значение ct_contains
в поле FlexNumber1.
Получение количества элементов в поле с массивом pc
из контекстной таблицы (пример в собтии на рисунке выыше в поле FlexNumber2), назовем переменную ct_len
:
len($ct_value)
Если в содержимом поля с массивом pc
из контекстной таблицы есть подстока см. выше описание переменной ct_contains
, то вернуть true
назовем переменную ct_item_exist
:
conditional(`$ct_contains LIKE '-.*'`, 'false', 'true')
Вот как выглядит это в событии, значение ct_item_exist
в поле FlexString2.
Тестирование правил корреляции
Для тестирования правил можно использовать ретроскан (из раздела “События”), предварительно это правило нужно добавить в коррелятор и осуществить выборку интересующих событий запросом (выбрать временной диапазон):
В нашем случае, если правило сработает создастся алерт, заполнятся листы, если это есть в действиях правила корреляции. Также можно включить опцию запуска реагирования.
ыыаыа
Производительность правил корреляции
Написание правил
В правилах корреляции очередность условий в селекторах имеет значение
Уникальные условия надо поднимать вверх в правиле корреляции:
Еще, например, есть правило, в котором в переменную кладется значение из активного листа, а затем эта переменная сравнивается в условии. Так вот в этом случае очередность условий имеет большое значение, так как поменяв условия местами и отодвинув проверку по активному листу в конец, в метриках количество OPS с активным листом уменьшилось со 100000 OPS до 1,1 OPS.
При наличии условия с листами, словарями и т.д., отодвигайте их в конец.
Мониторинг произвоительности
Для мониторинга производительности по корреляции есть метрики, градации веса по операциям в продукте нет, все выполняется быстро благодаря GoLang. Метрики по правилам можно увидеть в разделе метрики, нажав на название “KUMA Collectors” затем выбрав “KUMA Correlators”:
Пример метрик по корреляции:
Сегментация правил корреляции
По умолчанию, если в корреляторе какое-то правило корреляции сработает несколько раз, все созданные в результате этого корреляционные события будут присоединены к одному алерту. Правила сегментации алертов дают возможность определить условия, при которых на основе таких однотипных корреляционных событий будут создаваться разные алерты.
Порядок применения правил сегментации соответсвует порядку правил сегментации созданным в интерфейсе KUMA (могут примениться и несколько сегментаций, если сработка правила корреляции соответствует нескольким правилам сегментации)
Блок-схема работы сегментации (спасибо за наработку интегратору):
Пример работы, есть правило корреляции, которое срабатывает на событие с полем Code равное "777" с разными занчениями SourceUserName, все сработки правила складваются в один Алерт, мы хотим создать отдельные алерты для отдельных пользователей:
Для этог онужно создать правило сегментации ипривязать его к правилу корреляции. Перейдите в Ресурсы - Правила сегментации и нажмите на кнопку Добавить правило сегментации. В нашем случае подойдет тип По группирующим полям:
Указываем свой шаблон именования и группирующее поле - используем поля имени пользователя и Сохраняем:
Далее необходимо привязать правило сегментации к нашему правилу корреляции. Это делается в Параметры - Алерты - вкладка Сегментация. Выбираем необходимый тенант, нажимаем кнопку Добавить, Указываем название, Выбираем правило корреляции и добавлем правило сегментации, затем на каждом шаге все Сохраняем.
По итогу, при появлении событий удовлетворяющих правилу корреляции мы получим отдельные алерты на основе SourceUserName.
Аналогичным образом можно использовать и другие типы правил сегментации.