В этой статье мы расскажем о корреляторе, который используем в продуктах Positive Technologies. В качестве примера возьмем MaxPatrol SIEM. Начнем с того, что именно мы подразумеваем под термином «коррелятор».
Большинство наших ИБ-решений получают на вход поток событий безопасности. Задача коррелятора — выявить в нем определенную последовательность (цепочку) событий в заданном временном окне. Типичный пример — brute force. Мы видим последовательность из нескольких попыток авторизации с некорректным паролем, которая завершается вводом правильных данных. Это пользователь вспомнил пароль или его подобрал злоумышленник? Инцидент нужно зафиксировать и проанализировать, а иногда лучше сразу заблокировать учетную запись.
Чтобы эффективно решать задачу поиска цепочек, входящие события нужно подготавливать. Как минимум, данные из разных источников важно нормализовать — привести к единому виду. Кроме того, события нужно обогащать по заранее подготовленным справочникам. Например, чтобы определять пользователей с правами администраторов и автоматически повышать уровень важности инцидентов. Вернемся к brute force: если свести все события авторизации к общей схеме, можно написать корреляционное правило для определения атаки в любой информационной системе, поставляющей события в коррелятор.
Устанавливаем правила
Любому продукту ИБ, в основе которого лежит экспертиза, нужны методы доставки экспертных знаний. В нашем случае это язык правил. Мы разработали DSL, с помощью которых специалисты, в том числе сотрудники наших клиентов и интеграторов, могут создавать правила для ряда продуктов Positive Technologies. Соответственно, важным элементом процесса становится SDK. К примеру, вместе с MaxPatrol SIEM поставляется набор консольных инструментов для разработки и тестирования правил.
В идеальном мире экспертиза работает из коробки, но в реальности для корректной реализации правил зачастую требуется дополнительная информация. Например, список контроллеров домена. Соответственно, правилам нужно предоставлять доступ к внешним источникам информации. Во время разработки MaxPatrol SIEM мы пробовали разные варианты реализации этой функциональности:
- Активные списки — именованные коллекции в Redis. Это простой, дешевый и вполне рабочий подход. Тем не менее в этом случае трудно работать с большими коллекциями и сценариями со сложной структурой.
- Второй вариант — проекции активов — появился благодаря MaxPatrol 10. Мы выгружали часть данных об активах в Mongo, куда мог ходить коррелятор.
- Финальным вариантом стала интеграция коррелятора с libfpta — реализация настраиваемых табличных списков. При этом коррелятор использует их не только на чтение, но и на запись. Тем самым мы даем экспертам возможность сохранять определенные данные событий и обращаться к ним в дальнейшем.
Аналогичным образом в коррелятор можно вносить репутационные списки, индикаторы компрометации и другую внешнюю информацию. С точки зрения эксперта работа с данными в правилах будет выглядеть как обращение к табличному списку.
Из чего состоят правила:
- Описание событий. У каждого события должен быть фильтр — с его помощью коррелятор понимает, что именно нужно анализировать. Ключ события нужен для идентификации инстанса корреляции. Например, в случае того же brute force в роли ключа может выступать имя пользователя или кортеж «имя пользователя плюс адрес сервера», если нужно ловить атаки на отдельных серверах.
- Rule. Описание последовательности, которую нужно найти: события, их количество, порядок и временной интервал.
- Результат. Для всех событий в цепочке выполняется on-обработчик, который позволяет совершать разные операции с табличными списками. Сюда же входит emit — результат работы коррелятора.
Теперь о том, как все это реализовано:
- Фильтры событий и ключи рассчитываются на роутере. Рассчитанный ключ позволяет отправить событие, предназначенное конкретному инстансу корреляции, на нужный шард. На выходе из роутера событие должно получить полный список инстансов и может попасть в разные воркеры коррелятора.
- При попадании события в коррелятор его содержимое складывается в кэш, а все данные (инстанс, тип, время и идентификатор) обрабатываются воркером. Именно здесь при каждом входящем событии состояние инстанса корреляции пересчитывается на предмет того, было ли правило выполнено. Проверка соответствия каждый раз выполняется заново, потому что у нас нет гарантий, что события идут на вход последовательно.
- При выполнении правила корреляции система отправляет сообщение в рендерер. Его задача — получить данные о событии из кэша, выполнить on-обработчики и другие действия в рамках правила. Затем он выдает коррелированное событие наружу.
Коррелятор в MaxPatrol SIEM
Переходим непосредственно к MaxPatrol SIEM. Система содержит четыре типа правил для соответствующих сервисов, а также табличные списки с данными. Сегодня мы подробно поговорим о правилах нормализации и корреляции. Задача первых — приводить разношерстные события из разных источников к единому виду для последующей обработки. Вторые позволяют выявлять определенные активности в инфраструктуре на основе потока нормализованных событий. Но прежде чем переходить непосредственно к правилам, поговорим о схеме описания нормализованных событий.
На старте разработки продукта мы использовали концепцию Common Event Expression и постепенно расширяли ее. В первых версиях это был набор сущностей с уникальными атрибутами, в том числе в части именования. По мере увеличения числа поддерживаемых событий у нас неоднократно возникала необходимость в расширении списка сущностей, их атрибутов и более подробной классификации объектов.
Со временем мы наработали существенную базу событий и правил их нормализации, провели анализ схемы и пришли к нескольким выводам:
- Схема быстро разрастается, и с ней становится все труднее работать.
- При описании конкретного события одновременно используется лишь малая часть доступных полей и сущностей.
- В описаниях сущностей много дублирующихся по смыслу атрибутов.
Тогда мы решили по-другому взглянуть на описание события: отказались от уникальных атрибутов для каждой сущности и перешли к двум базовым сущностям — «субъект» и «объект». У каждой из них есть набор атрибутов для описания смыслового взаимодействия в событии, где назначение атрибутов определяется классификацией объекта и субъекта. Кроме того, мы выделили отдельные сущности для описания сетевого взаимодействия и источника события (он не всегда участвует в наблюдаемом взаимодействии).
Новый подход помог сократить количество дублирующихся по назначению полей и упростил процесс работы со схемой. Кроме того, он позволяет расширять список классифицирующих значений для объекта и субъекта без добавления новых атрибутов. Само собой, по мере роста экспертизы и усложнения рассматриваемых сценариев схема пополняется новыми атрибутами и классификаторами, но это происходит уже не так быстро, как при расширении исходной концепции.
Правила нормализации
В основе правил нормализации лежит язык eXtraction and Processing (XP). Он был разработан для создания правил преобразования данных в процессе обработки событий.
Структурно правило нормализации можно представить в виде двух блоков (см. рис. 4).
Если первый выполняется успешно и событие подходит под заданные условия, начинается выполнение второго. Переходим к примерам.
На рис. 5.1 и 5.2 показан разбор текстового неструктурированного лога от nginx, сообщающего о закрытии соединения. Первичный разбор события и проверка условий отбора выполняются с помощью форматной строки TEXT. Ее основными элементами являются типизированные токены, которые позволяют разбирать меняющиеся от события к событию участки без использования сложных регулярных выражений. Другой важный элемент TEXT — якоря в виде текстовых данных, которые постоянны для рассматриваемого события (подсвечены зеленым цветом).
У событий могут быть опциональные участки. Задавать опциональность и ожидание альтернативных данных можно в форматной строке с помощью специальных конструкций. В представленном примере знаки вопроса используются для обозначения опциональных участков, а вертикальные черты — альтернативных методов разбора.
Если данные, извлеченные в форматной строке, не требуют дополнительной обработки, их можно сразу поместить в поля нормализованного события. В противном случае их нужно сохранить во временные переменные, наименование которых начинается с символа $, чтобы иметь к ним доступ для последующей обработки. После первичного парсинга и проверки условий управление передается в основную часть правила, где происходит дополнительная обработка данных и формирование финального нормализованного события.
Периодически встречаются события, содержащие данные сразу в нескольких форматах. Например, это может быть текстовый лог, часть которого представляет из себя структурированные данные JSON. Или же в структурированном событии табличного вида (плоский JSON) в одном из полей может находиться полноценная XML-структура, из которой нужно извлечь определенные значения.
Для подобных случаев предусмотрен механизм, позволяющий обрабатывать части событий как самостоятельные целевые события. Фактически это вложенное правило нормализации, которое описывается внутри конструкции из ключевых слов subformula и endsubformula. Вызов обработки осуществляется с помощью функции submessage.
На рис. 6.2 и 6.3 показана обработка данных разными функциями. Таким образом можно привести информацию к подходящему для дальнейшей работы формату или представить в удобном для безопасника виде.
Правила корреляции
Кейс № 1
Начнем с простого кейса по обнаружению попытки создания и удаления учетной записи в течение короткого интервала времени. Для этого нужно фиксировать два события. Поскольку мы рассматриваем в качестве источника ОС Windows, их можно поймать с помощью поля msgid, в котором идентификатор события сохраняется в терминологии источника. Обратите внимание на ключевое слово key: с его помощью задаются значения, по которым события будут группироваться в инстанс. Отметим, что при формировании ключа инстанса названия полей не важны — роль играют только их значения. Таким образом, в инстанс можно собирать события из разных полей, главное, чтобы они имели одни и те же значения и порядок.
В коде на рис. 8 используется ключевое слово «filter::». Оно вызывает макросы — участки фильтров, вынесенные в отдельные объекты для переиспользования в правилах корреляции и обогащения. В данном кейсе применяются два макроса. NotFromCorrelator отсеивает корреляционные события. CheckWL_Specific_Only является составной частью большого экспертного механизма исключений и скрывает в себе логику обращений к нескольким табличным спискам. Этап фильтрации событий происходит в сервисе роутера.
Нам нужно обнаружить строгую последовательность событий — сначала создание, затем удаление пользователя, поэтому при описании последовательности мы используем оператор строгого следования «->». Также мы задаем временной интервал в 1 час — для этого существует несколько операторов. В данном случае применяем within: он используется с цепочками, в которых однозначно определено количество ожидаемых событий (без опциональных).
Цепочка собирается в сервисе коррелятора.
После сбора цепочки начинается обработка исходных событий и формирование корреляционного. Для этого используются on-обработчики, в которых может выполняться произвольный XP-код (в том числе для получения доступа к данным табличных списков). Пользователь может обратиться к полям исходного события, временным переменным в рамках инстанса корреляции, а также к полям результирующего события, выделенным знаком $. В данном случае код обработчика максимально прост: мы сохраняем нужные данные исходных событий в результирующее.
Правило завершает блок emit: если цепочка собрана успешно, он всегда выполняется последним. С его помощью мы получаем доступ к полям корреляционного события и временным переменным.
Кейс № 2
Второй кейс: если пользователь обладает правами локального администратора на сервере сертификации, он может экспортировать сертификат CA и выписывать сертификаты для других пользователей домена. Как это отследить?
Первое и главное событие (обязательное) — факт экспорта сертификата. В поле msgid оно будет иметь значение 5059. В условиях отбора задается дополнительная фильтрация по полям object.type и object.name. Второе событие (опциональное) — факт запуска утилиты certutil с параметром backupkey для экспорта сертификата. В рамках фильтра используем еще один экспертный макрос — для отлова событий запуска процессов в Windows. В качестве параметра передаем ему наименование исполняемого файла утилиты. Еще одно опциональное событие — факт доступа к объекту сетевого ресурса. Оно нужно для случаев, когда экспорт сертификата выполняется удаленно. В рамках этого фильтра нас интересуют файлы с расширением .pfx. Ключ для группировки событий максимально прост: это узел, на котором они произошли.
Переходим к описанию цепочки. В данном случае неважно, в каком порядке придут события, поэтому вместо оператора строго следования применяем and. Поскольку два из трех событий опциональны, помечаем их фильтры квантификатором «?». Для задания временного интервала используем ключевое слово timer. Timer отличается от within тем, что после взведения он будет ожидать заданное количество секунд (даже после прихода всех обязательных событий), чтобы отловить в потоке опциональные события.
Далее идут обработчики. Из обязательного события Key_Migration мы можем забрать только имя сертификата. Также заполняем поля важности и типа корреляции, если событие попало в цепочку первым и им еще не были присвоены значения.
Поймали событие запуска процесса утилиты certutil? Повышаем уровень важности до высокого в принудительном порядке, даже если обязательное событие Key_migration уже заполнило это поле. Также анализируем поле object.process.cmdline на наличие признаков, по которым можно определить использованные инструменты. Значение certipy будет признаком утилиты certsync — при экспорте она задает сертификату такое имя. При наличии этого признака устанавливаем тип корреляционного события в incident и записываем информацию об использованном инструменте в alert.context.
Таким образом, опциональное событие в цепочке может изменить важность корреляционного. В этом же обработчике сохраняем в результирующее событие информацию об аккаунте и о процессе. Остается последнее опциональное событие, возникающее при удаленном экспорте сертификата. Из него мы забираем информацию об атакующем.
Кейс № 3
Еще один кейс: обнаружение факта использования ВПО для выгрузки информации из контроллера домена. В этом случае рассмотрим только цепочку. Нас интересует комбинация квантификатора с верхней открытой границей «+» и оператора with_different, позволяющего задать поле, значение которого для всех пойманных событий должно различаться.
В инстанс попадут все подходящие под фильтр DNSZone_Query события, у которых различаются значения поля object.query. Если в потоке встретится несколько событий с одинаковым значением, в инстанс попадет только одно.
Возможности правил корреляции
- Реализация цепочек разной сложности: от одного события с заданной фильтрацией до сложных комбинаций фильтров с указанием последовательности, квантификаторов и дополнительных условий.
- Использование подхода каскадных корреляций. Сложные и длительные кейсы можно разделить на этапы в виде подправил, результаты работы которых отлавливаются вышестоящим правилом. Таким образом можно осуществлять промежуточную фиксацию.
- Выделение тематических участков фильтров правил корреляции в отдельные макросы для удобного переиспользования в неограниченном количестве правил. Функциональность избавляет от дублирования кода, помогает быстрее разрабатывать новые правила и позволяет централизованно вносить корректировки в несколько правил сразу.
- Реализация в обработчиках логики любого уровня сложности (в рамках языка XP).
- Возможность составления сложных запросов к табличным спискам, включая агрегатные функции. Запросы можно вызывать в фильтрах или обработчиках — чтобы извлечь из табличных списков нужную информацию и сохранить в поля корреляционного события.
Конвейер в MaxPatrol SIEM
Коррелятор является частью большого конвейера, который мы интегрируем в наши решения. Рассмотрим MaxPatrol SIEM.
Помимо нормализации, агрегации и обогащения, события также проходят этап привязки к активам (resolver). События из коррелятора идут обратно в агрегатор и могут использоваться в других корреляциях. Таким образом, эксперты строят цепочки из нескольких корреляций, выделяя общие части (например, авторизацию в каком-либо сервисе или создание пользовательской сессии), которые можно оформить как отдельные коррелированные события. Отдельно вынесен сервис нотификаций, который может сформировать в продукте инцидент из специальным образом созданного события.
При написании собственной экспертизы для MaxPatrol SIEM нужно помнить, что одним-единственным правилом корреляции можно легко устроить цикл. Защищаемся мы от подобных ситуаций мониторингом. Если правило генерирует слишком много событий, оно может быть выключено автоматически. При этом графы коррелятора будут физически пересобраны без него, а пользователь увидит предупреждение в интерфейсе.
Элементы нашего конвейера используются в разных продуктах Positive Technologies. Самый полный комплект — в PT SIEM и PT XDR. Нормализатор и коррелятор применяются в PT ISIM и PT Sandbox, агрегатор — в PT AF. В открытый проект SOLDR конвейер поставляется в виде freeware-модуля.