Миньковский Евгений MaxPatrol SIEM ptsecurity.ru Agenda: что входит в курс CS • Назначение системы SIEM, Компоненты системы, потоки данных • Asset management • Пользователи и роли • Сбор событий и работа с собранными событиями • Корреляции (обзор некоторых системных правил корреляции) • Инциденты и уведомления • Статистика и отчеты • Troubleshooting, обращение в службу поддержки Agenda: что входит в курс CP • Потоки данных • Написание правил нормализации и работа с SDK • Написание правил корреляции и работа с SDK • Табличные списки, правила обогащения, правила аггрегации Queues 1,2 MaxPatrol UI Web Console Qeue 3: RAW log messages MaxPatrol SIEM MaxPatrol CORE RMQ Host Services & Functions Queues Services & Functions RabbitMQ WebServer Asset Model 1. Scanner managment 2. Asset information 3. Raw log messages Incident DB MaxPatrol Agent Other DB RabbitMQ Receiver Service Generators: Normalization Service Aggregator Service Correlation Service Storage Service Asset Resolution Service Enricher Service Routing Service Notifier Service Frontend Service ElasticSearch Modules Data Sources & Assets audit pentest syslog wineventlog odbclog . Схема взаимодействия компонентов Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server • Установка Core • Установка SIEM • Установка Agent • Инициализация PTKB Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Установка MaxPatrol SIEM Server Версия XX.X Руководство разработчика Повышение привилегий в MaxPatrol-8 CEE-подобная таксономия http://cee.mitre.org Object fields Subject fields Event source info subject subject.name subject.domain subject.id subject.privileges subject.group subject.type subject.version Action with object enum StringField StringField StringField StringField StringField StringField StringField action Result enum s tatus object enum enum object.name StringField object.domain StringField object.id StringField object.property StringField object.value StringField event_src.host StringField event_src.ip StringField event_src.vendor StringField event_src.title StringField event_src.subsys StringField object.group StringField event_src.category StringField object.type StringField event_src.hostname StringField enum object.state StringField object.vendor StringField object.version StringField object.path StringField event_src.category Event Time of event ti me DatetimeField s tart_ti me DatetimeField Service fields uui d Info fields Correlation fields correl ati on_name StringField correl ati on_type enum Category of event\incident category.generi c StringField category.hi gh StringField category.l ow StringField Classifier of event id StringField i mportance enum tcp_fl a g StringField Address fields protocol StringField From ms gi d StringField s rc.hos t l ogon_type NumberField s rc.i p StringField rea s on StringField s rc.ma c MACAddrField i nterfa ce StringField s rc.port di recti on StringField a s s i gned_s rc_i p StringField da ta fi el d1 StringField a s s i gned_s rc_hos t StringField da ta fi el d2 StringField s rc.hos tna me da ta fi el d3 StringField da ta fi el d4 StringField ds t.hos t StringField da ta fi el d5 StringField ds t.i p StringField dura ti on NumberField ds t.ma c MACAddrField count.s ubevents NumberField ds t.port NumberField count.bytes NumberField ds t.hos tna me StringField NumberField a s s i gned_ds t_i p StringField count.bytes _out NumberField a s s i gned_ds t_hos t StringField count.pa ckets NumberField count.bytes _i n count.pa ckets _i n count.pa ckets _out NumberField NumberField StringField NumberField StringField To Other na s _i p StringField UUIDField a s s et_i ds UUIDListField body StringField a gent_i d UUIDField i nput_i d UUIDField ta s k_i d UUIDField recv_hos t StringField recv_i pv4 IPv4Field recv_i pv6 IPv6Field recv_ti me DatetimeField event_type StringField norma l i zed BoolField ta g StringField mi me StringField s ubevents UUIDListField s i te_i d UUIDField type StringField ta xonomy_vers i on StringField genera tor StringField count NumberField Таксономия события: сетевая атака SNAT NIDS recv_ipv4 recv_ipv6 event_src.ip event_src.host event_src.vendor event_src.title Злоумышленник src.ip src.host src.mac src.port Жертва MaxPatrol Agent dst.ip dst.host dst.mac dst.port recv_time Таксономия события: вход в систему Действие (sudo&su) Действие action = login status = success action = login status = success Пользователь ОС subject = account subject.name = yoda object = system Пользователь 1 Пользователь 2 subject = account subject.name = yoda object = account object.name = root Действие (sudo) action = logout status = success Пользователь 2 object = account object.name = root Пользователь 1 Отсутствует в raw Действие action = login status = failure X Действие (sudo&su) action = login status = failure Пользователь ОС subject = account subject.name = yoda object = system X Пользователь 1 Пользователь 2 subject = account subject.name = yoda object = account object.name = root PDQL — Positive Data Query Language SELECT one,two,three — Колонки WHERE condition — Условие (фильтр) ORDER BY one, two DESC — Сортировка Фильтры в PDQL Операторы = != > < >= <= in ["one", "two", "three"] match, startswith, endswith and or (…) ! ((… or …) and !…) not in [1,2,3] Функции match(subject.name, ".*admin.*") !match(subject.name, ".*admin.*") PDQL — Positive Data Query Language Примеры фильтров (object.name in ["root","yoda"]) or (subject.name in ["root","yoda"]) (action = "login") and (subject.id match "<1-500>") subject.name match ".*(admin|админ).*|2#t5%iG171D6Y " object.name match "сепульк([аиуе]|ой)" generator startswith "c" сепулька сепульки сепульке сепульку сепулькой сепульке Документация MaxPatrol 10 ptmpsiemXX.X_qsguide_ru.pdf Quick Start Guide ptmpsiemXX.X_operatorguide_ru.pdf Operator Guide ptmpsiemXX.X_refguide_ru.pdf Reference Guide ptmpsiemXX.X_pdqlsyntax_ru.pdf PDQL Syntax ptmpsiemXX.X_adminguide_ru.pdf Administrator Guide ptmpsiemXX.X_developguide_ru.pdf Developer Guide ptmpsiemXX.X_rn_ru.pdf Release Notes Positive Technologies MaxPatrol SIEM Версия XX.X Quick Start Guide • Развертывание PT MaxPatrol SIEM • Активация лицензии при наличии доступа к сети • Вход в PT MaxPatrol SIEM через PT IAM • Итерфейс PT MaxPatrol SIEM • Начало работы с PT MaxPatrol SIEM • Заведение активов • Сканирование сети • Создание учетной записи • Подключение источника событий • Просмотр событий • Просмотр инцидентов • Обращение в службу технической поддержки Positive Technologies MaxPatrol SIEM Версия XX.X Быстрый старт Operator Guide • Вход в PT MaxPatrol SIEM через PT IAM • Итерфейс PT MaxPatrol SIEM • Статистика: дашборды и виджеты • Работа с активами • Работа с событиями • задачами • инцидентами • табличными списками • правилами корреляции • правилами обогащения • отчетами • Администрирование системы: управление пользователями • мониторинг состояния системы • статус агентов • состояние лицензии и др. • Сбор данных • Схема обработки событий • Обращение в техподдержку • Приложения Positive Technologies MaxPatrol SIEM Версия XX.X Руководство оператора Operator Guide: Сбор данных • Модули: здесь описание модулей и опций по их настройке для профиля сканирования и профиля сбора событий • Профили • Транспорты • Устранение неисправностей Positive Technologies MaxPatrol SIEM Версия XX.X • Задержка событий: параметры кеширования, буферизации и интервалов отправки • Неверное отображение времени событий: тюнинг часовых поясов и сбоя часов на источнике Руководство оператора Operator Guide: Приложения • Типы событий собираемых с ОС Windows Таксономия: • Поля таксономии событий • Значения полей таксономии с типом данных Enum • Правила заполнения поля event_src.category • Правила заполнения полей category.generic, category.high, category.low Работа с событиями: • Математические функции для работы с данными о событиях • Горячие клавиши Positive Technologies MaxPatrol SIEM Версия XX.X Руководство оператора Reference Guide • Список поддерживаемых источников Про каждый источник: • Действия необходимые для настройки источника • Действия необходимые для настройки профиля сбора данных со стороны PT MaxPatrol SIEM Positive Technologies MaxPatrol SIEM Версия XX.X Более 800 страниц Настройка источников PDQL Syntax • Запросы для фильтрации и группировки событий • Запросы для фильтрации инцидентов • Запросы для фильтрации активов, создание динамических групп • Запросы для поиска строк в табличных списках Positive Technologies MaxPatrol SIEM Версия XX.X Приложения • Типы данных • Регулярные выражения (самые базовые конструкции) Синтаксис языка запроса PDQL Administrator Guide • Архитектура PT MaxPatrol SIEM • Выбор конфигурации PT MaxPatrol SIEM • Развертывание разных конфигураций • Активация лицензии Positive Technologies MaxPatrol SIEM Версия XX.X • При наличии доступа к Интернет • При отсутствии доступа к Интернет • Исправление ошибок активации лицензии • Проверка корректности установки • Обновление PT MaxPatrol SIEM • Резервное копирование и восстановление • Администрирование PT MaxPatrol SIEM • Обращение в техподдержку Руководство администратора Administrator Guide: Администрирование PT MaxPatrol SIEM • Управление пользователями и правами доступа • Настройка SIEM на Агенте • Изменение одноузловой конфигурации ElasticSearch с миграцией данных • Подключение служб MP SIEM к клиентскому узлу кластера ElasticSearch • Архивация, восстановление и удаление индексов ElasticSearch • Ротация жураналов компонентов сторонних производителей • Изменение времени устаревания активов • Отправка уведомление по электронной почте • Настройка мониторинга MP Agent • Интеграция с Zabbix Positive Technologies MaxPatrol SIEM Версия XX.X Руководство администратора Developer Guide • Схема обработки событий • Язык XP • Нормализация • Корреляция • Обогащение данных Приложения, Таксономия: • Типы данных • Поля таксономии событий • Значения полей таксономии с типом данных Enum • Правила заполнения поля event_src.category • Правила заполнения полей category.generic, category.high, category.low • Активные списки Positive Technologies MaxPatrol SIEM Версия XX.X Руководство разработчика Release Notes Каждый релиз выходит документ с обзором новых возможностей системы • Новые возможности • Технические особенности • Улучшения • Прочие изменения Positive Technologies MaxPatrol SIEM Версия XX.X Обзор новых возможностей Обработка журнальных сообщений в PT MaxPatrol SIEM ptsecurity.ru Схема работы MaxPatrol SIEM Server Positive Technologies MaxPatrol SIEM Версия XX.X Руководство разработчика Профиль filemonitor, plain_parser Профиль Исходник { Login success: "target_filesystem_type": "WINDOWS", root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 "inputs": { root tty1 "@GUID": { Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 "base_directory": "<Path_to_base_directory>", "encoding": "UTF-8", Login failure: "filename_regex": "(<Filename_regex>)", foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 "parser": { root tty1 "plain_parser": {} }, UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 "reader": { "string_reader": { "end_of_line_delimiter": "\n" } }, "recursion_depth": 0 } }, ..................................................................................... } Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 Профиль filemonitor, plain_parser Профиль Исходник { Login success: "target_filesystem_type": "WINDOWS", root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 "inputs": { root tty1 "@GUID": { Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 "base_directory": "<Path_to_base_directory>", "encoding": "UTF-8", Login failure: "filename_regex": "(<Filename_regex>)", foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 "parser": { root tty1 "plain_parser": {} }, UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 "reader": { "string_reader": { "end_of_line_delimiter": "\n" } }, "recursion_depth": 0 } }, ..................................................................................... } Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 Профиль filemonitor, plain_parser Профиль Исходник { Login success: "target_filesystem_type": "WINDOWS", root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 "inputs": { root tty1 "@GUID": { Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 "base_directory": "<Path_to_base_directory>", "encoding": "UTF-8", Login failure: "filename_regex": "(<Filename_regex>)", foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 "parser": { root tty1 "plain_parser": {} }, UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 "reader": { "string_reader": { "end_of_line_delimiter": "\n" } }, "recursion_depth": 0 } }, ..................................................................................... } Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 Профиль filemonitor, plain_parser «Сырое событие» (raw event) { "_index": "ptsiem_r_2018-02-20", "_type": "raw", "_id": "00000005-a8be-0e64-f000-0023deae69c7", "_score": 2.7208266, "_source": { "mime": "text/csv", "corrections": { "expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"], "time_zone": 10800, "time_delta": 0 }, "tag": "filemonitor", "site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0", "input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4", "recv_time": "2018-02-20T09:46:12Z", "uuid": "00000005-a8be-0e64-f000-0023deae69c7", "recv_ipv4": "10.0.1.49", "body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100", "type": "raw", "task_id": "c769aede-836e-4214-b7f1-7168dcbf535d", "tenant_id": "00000000-0000-0000-0000-000000000004", "normalized": true, "scope_id": "00000000-0000-0000-0000-000000000005" } } Исходник Login success: root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 root tty1 Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 Login failure: foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 root tty1 Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 Профиль filemonitor, plain_parser «Сырое событие» (raw event) { "_index": "ptsiem_r_2018-02-20", "_type": "raw", "_id": "00000005-a8be-0e64-f000-0023deae69c7", "_score": 2.7208266, "_source": { "mime": "text/csv", "corrections": { "expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"], "time_zone": 10800, "time_delta": 0 }, "tag": "filemonitor", "site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0", "input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4", "recv_time": "2018-02-20T09:46:12Z", "uuid": "00000005-a8be-0e64-f000-0023deae69c7", "recv_ipv4": "10.0.1.49", "body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100", "type": "raw", "task_id": "c769aede-836e-4214-b7f1-7168dcbf535d", "tenant_id": "00000000-0000-0000-0000-000000000004", "normalized": true, "scope_id": "00000000-0000-0000-0000-000000000005" } } Исходник Login success: root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 root tty1 Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 Login failure: foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 root tty1 Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 Профиль filemonitor, plain_parser «Сырое событие» (raw event) { "_index": "ptsiem_r_2018-02-20", "_type": "raw", "_id": "00000005-a8be-0e64-f000-0023deae69c7", "_score": 2.7208266, "_source": { "mime": "text/csv", "corrections": { "expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"], "time_zone": 10800, "time_delta": 0 }, "tag": "filemonitor", "site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0", "input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4", "recv_time": "2018-02-20T09:46:12Z", "uuid": "00000005-a8be-0e64-f000-0023deae69c7", "recv_ipv4": "10.0.1.49", "body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100", "type": "raw", "task_id": "c769aede-836e-4214-b7f1-7168dcbf535d", "tenant_id": "00000000-0000-0000-0000-000000000004", "normalized": true, "scope_id": "00000000-0000-0000-0000-000000000005" } } Исходник Login success: root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 root tty1 Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 Login failure: foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 root tty1 Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 Профиль filemonitor, plain_parser «Сырое событие» (raw event) { "_index": "ptsiem_r_2018-02-20", "_type": "raw", "_id": "00000005-a8be-0e64-f000-0023deae69c7", "_score": 2.7208266, "_source": { "mime": "text/csv", "corrections": { "expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"], "time_zone": 10800, "time_delta": 0 }, "tag": "filemonitor", "site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0", "input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4", "recv_time": "2018-02-20T09:46:12Z", "uuid": "00000005-a8be-0e64-f000-0023deae69c7", "recv_ipv4": "10.0.1.49", "body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100", "type": "raw", "task_id": "c769aede-836e-4214-b7f1-7168dcbf535d", "tenant_id": "00000000-0000-0000-0000-000000000004", "normalized": true, "scope_id": "00000000-0000-0000-0000-000000000005" } } Исходник Login success: root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100 root tty1 Tue Jun 7 08:06 still logged in 0.0.0.0 root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 Login failure: foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 root tty1 Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0 UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0 unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0 Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt" { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt" { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt" { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt" { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt" { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt" { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Профиль filemonitor, offset_parser Профиль «Сырое событие» (raw event) { { ..................................................................................... "SLGTYPE.SLGFTYP": "2", "inputs": { "SLGTYPE.AREA": "AU", "@GUID": { "SLGTYPE.SUBID": "W", ..................................................................................... "SLGDATTIM.DATE": "20150205", "encoding": "UTF-16BE", "SLGDATTIM.TIME": "074639", "filename_regex": "(.+.AUD)", "SLGMAND": "700", "parser": { "SLGUSER": "HANNIBAL "offset_parser": { "SLGTC": "SESSION_MANAGER "offsets": [ ", ", "SLGREPNA": "/1BCDWB/DBTSL1T ", ", { "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" }, "SLGLTRM2": "NEF-KISEL-IA { "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA" }, "SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt { "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID" }, { "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" }, { "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" }, { "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" }, { "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" }, { "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" }, { "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" }, { "begin_pos": 64, "length": 16, "name": "SLGLTRM" }, { "begin_pos": 80, "length": 24, "name": "SLGUSER" }, { "begin_pos": 104,"length": 40, "name": "SLGTC" }, ..................................................................................... } Схема работы MaxPatrol SIEM Server Positive Technologies MaxPatrol SIEM Версия XX.X Руководство разработчика MaxPatrol SIEM Правила нормализации ptsecurity.ru Примеры журнальных сообщений TEXT (Syslog) <191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length JSON XML <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> { "TimeVal": "2015-07-21 07:10:59", "DoorIndex": 10, "Contents": "Доступ предоставлен", "OwnerName": "мастер Йода", "NumCom": 4828116 } <Provider Name="Windows Server Update Services" /> <EventID Qualifiers="0">501</EventID> <Level>4</Level> <Task>1</Task> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2016-05-14T17:06:59.000Z" /> <EventRecordID>8156</EventRecordID> <Channel>Application</Channel> <Computer>something.example.com</Computer> <Security /> </System> <EventData> <Data>Update Services Service Started</Data> </EventData> </Event> TEXT (Syslog) CEF — попытка унификации формата CEF:Version|Device Vendor|Device Product| Device Version|Signature ID|Name|Severity|Extension <6>CEF:0|Stonesoft|Firewall|5.3.10|70018|Connection_Allowed|0| spt=27302 deviceExternalId=fw-int-ptk2 node 2 dst=172.2.8.26 app=DNS (UDP) rt=Mar 10 2016 11:09:58 deviceFacility=Packet filter act=Allow deviceInboundInterface=129 proto=17 dpt=53 src=172.2.1.26 dvc=172.2.2.250 dvchost=172.2.2.250 cs1Label=RuleId cs1=236.6 JSON Tabular { "TimeVal":"2015-07-21 07:10:59.000", "DoorIndex":10, "Contents":"Доступ предоставлен", "OwnerName":"Ганнибал Барка", "NumCom":4828116 } EventLog: XML -> JSON via RapidXML { <Event xmlns=" http://schemas.microsoft.com/w..."> <System> <Provider Name="Windows Server Update S..." /> <EventID Qualifiers="0">501</EventID> <Level>4</Level> <Task>1</Task> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2016-05-14T17:..." /> <EventRecordID>8156</EventRecordID> <Channel>Application</Channel> <Computer>something.example.com</Computer> <Security /> </System> <EventData> <Data>Update Services Service Started</Data> </EventData> </Event> "Event": { "xmlns": "http://schemas.microsoft.com/win/2004/08/events/event", "System": { "Provider": { "Name": "Windows Server Update Services" }, "EventID": { "Qualifiers": "0", "text": "501" }, "Level": "4", "Task": "1", "Keywords": "0x80000000000000", "TimeCreated": { "SystemTime": "2016-05-14T17:06:59.000000000Z" }, "EventRecordID": "8156", "Channel": "Application", "Computer": "something.example.com", "Security": null }, "EventData": { "Data": "Update Services Service Started" }}} TEXT — пишем формулу нормализации #<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' TEXT — пишем формулу нормализации #<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' TEXT — пишем формулу нормализации #<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' TEXT — пишем формулу нормализации #<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' TEXT — пишем формулу нормализации #<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' TEXT — пишем формулу нормализации #<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' TEXT — пишем формулу нормализации {$предопределенные=МАКРОСЫ} {WORD} {WORDDASH} {STRING} {LITERAL} {DATETIME} {DURATION} {IPV4} {IPV6} {HOSTNAME} {NTUSER} [a-zA-Z0-9_]+ [a-zA-Z0-9_-]+ \S Operator Guide [hhh]hh:mm:ss,+ RFC-1034,1035,+ tudor\edward {CSV} {CSV(',','"')} {KEYVALUE} {KEYVALUE(';','=')} {REST} TEXT — пишем формулу нормализации TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?} {$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?} {NUMBER?}{":"?}{$origin_id_ip=IPV4| $origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|} {":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?} {object.name="SSH2"|object.name="SSH"} {NUMBER}: {reason="Invalid modulus length"}' if ($origin_id_ip == "127.0.0.1" or $origin_id_ip == "0.0.0.0") then $origin_id_ip = null endif event_src.hostname = coalesce($hostname, $origin_id_hostname) event_src.ip = coalesce($ip, $origin_id_ip) JSON: TABULAR # {"TimeVal":"2015-07-21 07:10:59.000", "DoorIndex":10, # "Contents":"Доступ предоставлен", # "OwnerName":"Ганнибал Барка", "NumCom":4828116} TABULAR = "TimeVal, DoorIndex, Contents, OwnerName, NumCom" COND = $Contents == "Доступ предоставлен" subject = "system" action = "allow" status = "success" object = "account" time = $TimeVal msgid = $Contents JSON: TABULAR # { "TimeVal":"2015-07-21 07:10:59.000", # "DoorIndex":10, # "Contents":"Доступ предоставлен", # "OwnerName":"Ганнибал Барка", # "NumCom":4828116} TABULAR = "TimeVal, DoorIndex, Contents, OwnerName, NumCom" COND = $Contents == "Доступ предоставлен" time = $TimeVal msgid = $Contents JSON: EVENTLOG, raw (после RapidXML) { "EventRecordID": "8156", "Channel": "Application", "Computer": "example", "Security": null "Event": { "xmlns": http://example.com/.../event", "System": { "Provider": { }, "Name": "WSUS" "EventData": { }, "Data": "Update Services Service Started" "EventID": { } "Qualifiers": "0", } "text": "501" } }, "Level": "4", "Task": "1", "Keywords": "0x80000000000000", "TimeCreated": { "SystemTime": "2016-05-14T17:06:59" }, JSON: EVENTLOG { "EventRecordID": "8156", "Channel": "Application", "Computer": "example", "Security": null "Event": { "xmlns": http://example.com/.../event", "System": { "Provider": { }, "Name": "WSUS" "EventData": { }, "Data": "Update Services Service Started" "EventID": { } "Qualifiers": "0", } "text": "501" } }, "Level": "4", EVENTLOG = 'EventID.text="501"' "Task": "1", COND = $Channel=="Application" and "Keywords": "0x80000000000000", $Provider["Name"]=="WSUS" "TimeCreated": { "SystemTime": "2016-05-14T17:06:59" }, JSON: EVENTLOG, formula.xp EVENTLOG = 'EventID.text="501"' COND = $Channel=="Application" and $Provider["Name"]=="WSUS" action = "start" object = "service" status = "success" msgid = $EventID["text"] time = $TimeCreated["SystemTime"] object.name = "Update Services" JSON: "PT_Microsoft_Windows_WMI_Win32_LoggedOnUser" JSON = 'TargetInstance.__CLASS="Win32_LoggedOnUser"' time = win_ticks_to_datetime($TIME_CREATED) subject.domain = lower($Win32_Account['Domain']) subject.name = lower($Win32_Account['Name']) subject.id = $Win32_Account['SID'] JSON: "PT_Microsoft_Windows_WMI_Win32_LoggedOnUser" JSON = 'TargetInstance.__CLASS="Win32_LoggedOnUser"‘ time = win_ticks_to_datetime($TIME_CREATED) subject.domain = lower($Win32_Account['Domain']) subject.name = lower($Win32_Account['Name']) subject.id = $Win32_Account['SID'] Нормализация: Вложенные сообщения { "unixtime": 1466648875, "timegenerated": "2016-06-23 02:27:25.000", "objectname": "DC1-DC-02", "objectdisplayname": "DC1-DC-02", "objectpath": "DC1-DC-02.ptsecurity.ru", "objectfullname": "Microsoft.Windows.Server.2008.AD.DomainControllerRole:DC1-DC-02.example.com;DC1-DC-02", "publishername": "Health Service Script", "number": 17, "category": 0, "eventuser": "N/A", "channel": "Operations Manager", "level": 4, "loggingcomputer": "DC1-DC-02.ptsecurity.ru", "eventdata": "<DataItem type=\"System.XmlData\" time=\"2016-06-23T05:27:25.1476913+03:00\" sourceHealthServiceId=\"52DE6561-458F-28F5-4C75-CCE269716AB5\"><eventdata xmlns=\"http://schemas.microsoft.com/win/2004/08/events/event\"><Data>AD Monitor Trusts</Data><Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data></eventdata></DataItem>", "eventparameters": "<Param>AD Monitor Trusts</Param><Param>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Param>", "rulename": "AD_Monitor_Trusts_Pass_through_2", "rulecategory": "EventCollection", "ruleenabled": 2, "ruleguaranteeddelivery": 0, "rulepriority": 1, "ruleremotable": 0 } XML TABULAR = "{time=timegenerated}, {subject.name=objectpath}, {subject.group=publishername}, number, {event_src.subsys=channel}, {event_src.hostname=loggingcomputer}, eventdata, {datafield2=rulename}" COND = $publishername == "Health Service Script" and $number == 17 submessage("XML","Event_data",$eventdata) submessage("TEXT","Script_info",$script_info) subformula "Event_data" XML = 'DataItem' $script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения endsubformula Нормализация: Вложенные сообщения <DataItem type="System.XmlData" time="2016-06-23..." sourceHealthServiceId="..."> <eventdata xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <Data>AD Monitor Trusts</Data> <Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data> </eventdata> </DataItem> submessage("XML","Event_data",$eventdata) submessage("TEXT","Script_info",$script_info) subformula "Event_data" XML = 'DataItem' $script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения endsubformula subformula "Script_info" TEXT = 'The script {$script=STRING+} completed successfully in {datafield3=NUMBER} seconds.' endsubformula Нормализация: Вложенные сообщения <DataItem type="System.XmlData" time="2016-06-23..." sourceHealthServiceId="..."> <eventdata xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <Data>AD Monitor Trusts</Data> <Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data> </eventdata> </DataItem> submessage("XML","Event_data",$eventdata) submessage("TEXT","Script_info",$script_info) subformula "Event_data" XML = 'DataItem' $script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения endsubformula subformula "Script_info" TEXT = 'The script {$script=STRING+} completed successfully in {datafield3=NUMBER} seconds.' endsubformula Нормализация: Вложенные сообщения <DataItem type="System.XmlData" time="2016-06-23..." sourceHealthServiceId="..."> <eventdata xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <Data>AD Monitor Trusts</Data> <Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data> </eventdata> </DataItem> submessage("XML","Event_data",$eventdata) submessage("TEXT","Script_info",$script_info) subformula "Event_data" XML = 'DataItem' $script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения endsubformula subformula "Script_info" TEXT = 'The script {$script=STRING+} completed successfully in {datafield3=NUMBER} seconds.' endsubformula Функции Математика, логика +, -, *, mod, div and, or, not >, <, >=, <=, ==, != in_list, in_subnet, in_active_set Другое coalesce($one,$two,$three) — вернуть первое не пустое значение match($one,"*.sw?") — истина, если шаблон найден в переменной $one Функции Условные переходы $access_success = ["100", "101", "200", "201", "202", "203", "206", "302", "304"] $access_failure = ["301", "302", "305", "307", "308", "400", "401", "403", "404", "405", "406", "407", "413", "415", "418", "423", "429", "431", "495", "496", "497", "500", "501", "502", "503", "504", "505", "507", "508"] if in_list($access_success, object.state) then status = "success" elif in_list($access_failure, string(object.state)) then status = "failure" else #Остановка работы формулы если неизвесный HTTP код submessage('TEXT', 'break', 'a') endif subformula "break" TEXT = "b" endsubformula Функции Условные переходы reason = switch object.state ... case "400" "Bad Request" case "401" "Unauthorized" case "403" "Forbidden" case "404" "Not Found" ... endswitch TEXT — пишем формулу нормализации #login success #root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100 #login failure #foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100 TEXT = '{$tmp_user_name=WORDDASH} {datafield1=STRING} {WORD} {$MM=WORD}{$DD=NUMBER}{$HH=NUMBER}:{$minutes=NUMBER} {"-"?} {NUMBER?}{":"?}{NUMBER?} {"("?}{$duration_minutes=NUMBER?}{":"?}{$duration_seconds=NUMBER?}{")"?} {"still logged in"?} {$event_src.ip=IPV4}' if $duration_minutes == 0 and $duration_seconds == 0 then status = "failure" else status = "success" endif time = $MM+" "+string($DD)+" "+string($HH)+":"+string($minutes)+":"+"00" if $duration_minutes != null and $duration_seconds != null then duration = $duration_minutes*60 + $duration_seconds endif Функции Преобразование типов, конвертация Синтаксический разбор строк string number (may_be_number) number8 (may_be_number8) number16 (may_be_number16) float (may_be_float) bool ipv4 (may_be_ipv4) ipv6 (may_be_ipv6) macaddr (may_be_macaddr) duration (may_be_duration) datetime (may_be_datetime) epoch_to_datetime epoch_ms_to_datetime win_ticks_to_datetime keyvalue $kv=keyvalue("a=b,c=d","'","=") csv Преобразование строк year, month, day, hour, minute, second, timezone — извлечение подстрок strip("$123.00","$",".00") -> "123" find_substr("$123.00",".") -> 4 length("$123.00") -> 7 substr("$123.00",0,4) -> "$123" upper, lower Локализация Поле text не входит в таксономию события. Да-да, совсем-совсем • ...\formulas\Checkpoint\Endpoint_security\Security_console\Assign_policy\i18n\i18n_ru.xml <?xml version="1.0" encoding="utf-8"?> <Localization locale="ru"> <EventDescriptions> <EventDescription id="PT_Checkpoint_Endpoint_Security_console_Assign_policy_lang">Политика {object.name} была добавлена в группу {object.group} на узле {event_src.ip}</EventDescription> </EventDescriptions> </Localization> • C:\Program Files\Positive Technologies\MaxPatrol SIEM Server\langs\ru.lang id = "PT_Checkpoint_Endpoint_Security_console_Assign_policy_lang"; Политика {object.name} была добавлена в группу {object.group} на узле {event_src.ip} • Поле text в браузере: Политика Deny Hackers была добавлена в группу Networks на узле 192.0.2.123 А какие поля таксономии надо заполнять? • Operator Guide: Описание правил нормализации и корреляции, описание таксономии • Developer Guide: Описание правил нормализации и корреляции, описание таксономии Positive Technologies MaxPatrol SIEM Positive Technologies MaxPatrol SIEM Версия XX.X Версия XX.X Руководство оператора Руководство разработчика MaxPatrol SIEM Правила корреляции ptsecurity.ru Правила корреляции XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: key: subject.name, subject.domain filter { correlation_name == null and subject.name != null and … } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { $count.subevents = $count.subevents + 1 } on Login_success { $subject.name = subject.name $subject.domain = subject.domain $count.subevents = $count.subevents + 1 } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" … } XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: key: subject.name, subject.domain filter { correlation_name == null and subject.name != null and … } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { $count.subevents = $count.subevents + 1 } on Login_success { $subject.name = subject.name $subject.domain = subject.domain $count.subevents = $count.subevents + 1 } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" … } XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: key: subject.name, subject.domain filter { correlation_name == null and subject.name != null and category.generic == "Access" and category.high == "Authentication" and subject == "account" and action == "login" and status == "success" } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: Поток событий subject.name key: subject.domain вперемешку subject.name, subject.domain filter { correlation_name == null and subject.name != null and category.generic == "Access" and category.high == "Authentication" and subject == "account" and action == "login" and status == "success" } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m Подпотоки plantagenet\henry plantagenet\edward plantagenet\richard plantagenet\john tudor\henry tudor\edward tudor\elizabeth XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: key: subject.name, subject.domain filter { correlation_name == null and subject.name != null and category.generic == "Access" and category.high == "Authentication" and subject == "account" and action == "login" and status == "success" } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: key: subject.name, subject.domain filter { correlation_name == null and subject.name != null and … } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { $count.subevents = $count.subevents + 1 } on Login_success { $subject.name = subject.name $subject.domain = subject.domain $count.subevents = $count.subevents + 1 } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" … } XP — eXtraction and Processing. Корреляция event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Login_success: key: subject.name, subject.domain filter { correlation_name == null and subject.name != null and … } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { $count.subevents = $count.subevents + 1 } on Login_success { $subject.name = subject.name $subject.domain = subject.domain $count.subevents = $count.subevents + 1 } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" … } XP — eXtraction and Processing. Корреляция event One: rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { $count.subevents = $count.subevents + 1 } event Other: rule Together: One -> Other on Login_success { $subject.name = subject.name $subject.domain = subject.domain $count.subevents = $count.subevents + 1 } on One { … } on Other { … } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" $category.generic = "Attacks & Recon" $category.high = "Attack" $category.low = "Bruteforce" emit { … } … } XP — eXtraction and Processing. Корреляция event One: rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { … } event Other: rule Together: One -> Other on Login_success { … } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" $category.generic = "Attacks & Recon" $category.high = "Attack" $category.low = "Bruteforce" on One { … } $subject = "account" $action = "initiate" $object = "attack" $status = "success" $object.name = "Bruteforce" on Other { … } emit { … } $id = "PT_SIEM_Bruteforce_success_by_user" $importance = "medium" } XP — eXtraction and Processing. Корреляция event One: rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { … } event Other: rule Together: One -> Other on Login_success { … } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" $category.generic = "Attacks & Recon" $category.high = "Attack" $category.low = "Bruteforce" on One { … } $subject = "account" $action = "initiate" $object = "attack" $status = "success" $object.name = "Bruteforce" on Other { … } emit { … } $id = "PT_SIEM_Bruteforce_success_by_user" $importance = "medium" } XP — eXtraction and Processing. Корреляция event One: rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { … } event Other: rule Together: One -> Other on Login_success { … } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" $category.generic = "Attacks & Recon" $category.high = "Attack" $category.low = "Bruteforce" on One { … } $subject = "account" $action = "initiate" $object = "attack" $status = "success" $object.name = "Bruteforce" on Other { … } emit { … } $id = "PT_SIEM_Bruteforce_success_by_user" $importance = "medium" } XP — eXtraction and Processing. Корреляция event One: rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { … } event Other: rule Together: One -> Other on Login_success { … } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" $category.generic = "Attacks & Recon" $category.high = "Attack" $category.low = "Bruteforce" on One { … } $subject = "account" $action = "initiate" $object = "attack" $status = "success" $object.name = "Bruteforce" on Other { … } emit { … } $id = "PT_SIEM_Bruteforce_success_by_user" $importance = "medium" } XP — eXtraction and Processing. Корреляция event One: rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Login_failure { … } event Other: rule Together: One -> Other on Login_success { … } emit { $correlation_name = "Bruteforce_success_by_user" $correlation_type = "incident" $category.generic = "Attacks & Recon" $category.high = "Attack" $category.low = "Bruteforce" on One { … } $subject = "account" $action = "initiate" $object = "attack" $status = "success" $object.name = "Bruteforce" on Other { … } emit { … } $id = "PT_SIEM_Bruteforce_success_by_user" $importance = "medium" } XP — eXtraction and Processing. Корреляция event One: event Other: # Checkpoint (ssh, opsec) # Cisco ACS # Cisco IOS (ssh, telnet, web) # Cisco Nexus (ssh) # Juniper Junos (ssh, telnet) # UNIX-like # Windows rule Together: One -> Other event Login_success: key: subject.name, subject.domain filter { … } on One { … } event Login_failure: key: subject.name, subject.domain filter { … } rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m on Other { … } on Login_failure { … } on Login_success { … } emit { … } emit { … } Если события не было… event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Infected_object_detect: key: event_src.ip, event_src.host, object.path filter { … } event Infected_object_clean: key: event_src.ip, event_src.host, object.path filter { … } rule Infected_object_detect_and_not_clean_on_event_src_host: (Infected_object_detect -> not Infected_object_clean) timer 5m Если события не было… event One: event Other: rule Together: One -> Other on One { … } on Other { … } emit { … } event Infected_object_detect: key: event_src.ip, event_src.host, object.path filter { … } event Infected_object_clean: key: event_src.ip, event_src.host, object.path filter { … } rule Infected_object_detect_and_not_clean_on_event_src_host: (Infected_object_detect -> not Infected_object_clean) timer 5m Если не было вообще почти ничего event One: event Other: rule Together: One -> Other on One { … } Правило сложения отрицаний Оператор ? rule Session_request_to_network_device_from_unauthorized_host: (SessionStart -> (not LoginFail or not LoginSuccess) -> SessionClose?) timer 2m on Other { … } emit { … } Между SessionStart и возможным SessionClose не было ни LoginFail ни LoginSuccess Если обработать надо первое событие в последовательности Конструкция as event Checkpoint_connection: key: evet_src.host filter { … } rule Port_lookup: ( ((Checkpoint_connection as First_checkpoint_connection -> Checkpoint_connection[9]) with different dst.ip) or ((Junos_connection as First_junos_connection -> Junos_connection[9]) with different dst.ip) or ((Netflow_connection as First_netflow_connection -> Netflow_connection[9]) with different dst.ip) or ((Cisco_fw_connection as First_cisco_fw_connection -> Cisco_fw_connection[9]) with different dst.ip) or ((Cisco_ios_in_connection as First_cisco_ios_in_connection -> Cisco_ios_in_connection[9]) with different dst.ip) or ((Cisco_ios_out_connection as First_cisco_ios_out_connection -> Cisco_ios_out_connection[9]) with different assigned_src_ip)) within 2h on First_checkpoint_connection { … } on First_junos_connection { … } on First_netflow_connection { … } Если одинаковые события должны отличаться некоторым параметром Если одинаковые события должны отличаться некоторым параметром Конструкция with different (Антитеза оператору key из директивы event) rule Port_lookup: ( ((Checkpoint_connection as First_checkpoint_connection -> Checkpoint_connection[9]) with different dst.ip) or ((Junos_connection as First_junos_connection -> Junos_connection[9]) with different dst.ip) or ((Netflow_connection as First_netflow_connection -> Netflow_connection[9]) with different dst.ip) or ((Cisco_fw_connection as First_cisco_fw_connection -> Cisco_fw_connection[9]) with different dst.ip) or ((Cisco_ios_in_connection as First_cisco_ios_in_connection -> Cisco_ios_in_connection[9]) with different dst.ip) or ((Cisco_ios_out_connection as First_cisco_ios_out_connection -> Cisco_ios_out_connection[9]) with different assigned_src_ip)) within 2h on First_checkpoint_connection { … } on First_junos_connection { … } on First_netflow_connection { … } Если в обработчике нужна подстановка (ключ->значение) Конструкция switch case … case … endswitch rule Port_lookup: ( ((Checkpoint_connection as First_checkpoint_connection -> Checkpoint_connection[9]) with different dst.ip) or ((Junos_connection as First_junos_connection -> Junos_connection[9]) with different dst.ip) or ((Netflow_connection as First_netflow_connection -> Netflow_connection[9]) with different dst.ip) or ((Cisco_fw_connection as First_cisco_fw_connection -> Cisco_fw_connection[9]) with different dst.ip) or ((Cisco_ios_in_connection as First_cisco_ios_in_connection -> Cisco_ios_in_connection[9]) with different dst.ip) or ((Cisco_ios_out_connection as First_cisco_ios_out_connection -> Cisco_ios_out_connection[9]) with different assigned_src_ip)) within 2h on First_checkpoint_connection { $src.ip = src.ip $protocol = upper(protocol) $dst.port = dst.port $start_time = time $object.name = switch dst.port case 20 "FTP lookup" case 21 "FTP lookup" case 22 "SSH lookup" case 23 "Telnet lookup" case 25 "SMTP lookup“ endswitch } Если в описании события надо найти параметр в списке Конструкция in_list event Netflow_connection: key: src.ip, protocol, dst.port filter { src.ip != null and event_src.subsys == "netflow" and ( ( upper(protocol) == "TCP" and in_list([20, 21, 194, 530, 161, 162, 135, 1433, 1434, 3299, 25, 389, 636, 445, 1025, 23, 22, 80, 8080, 443, 53, 1521, 1528, 2483, 2484, 3389, 110, 143, 139, 137, 113, 465, 993, 995, 3306], dst.port) ) or ( upper(protocol) == "UDP" and in_list([67, 530, 161, 162, 1434, 389, 636, 80, 8080, 443, 53, 3389, 113], dst.port) ) ) } rule Port_lookup: ( ((Checkpoint_connection as First_checkpoint_connection -> Checkpoint_connection[9]) with different dst.ip) or ((Junos_connection as First_junos_connection -> Junos_connection[9]) with different dst.ip) or ((Netflow_connection as First_netflow_connection -> Netflow_connection[9]) with different dst.ip) or … Найди ошибку event Ad_Admins: key: subject.name filter { correlation_name == null and action == "login" and status == "success" and in_list(["user1", "user2"], subject.name) } rule Ad_admins_login_success: Ad_admin on Ad_admins_login_success { $subject.name = subject.name $src.ip = src.ip $event_src.vendor = event_src.vendor } emit { $correlation_name = "Ad_admins_success" $correlation_type = "incident“ $subject = "account" $action = "create" $object = "alert" $status = "success" $category.generic = "Anomaly" $category.high = "User Behavior Anomaly" $category.low = "Detection" $id = "PT_SIEM_Work_at_night $importance = "medium" } Найди ошибку event Ad_Admins: key: subject.name filter { correlation_name == null and action == "login" and status == "success" and in_list(["user1", "user2"], subject.name) } rule Ad_admins_login_success: Ad_admin on Ad_admins_login_success { $subject.name = subject.name $src.ip = src.ip $event_src.vendor = event_src.vendor } emit { $correlation_name = "Ad_admins_success" $correlation_type = "incident“ $subject = "account" $action = "create" $object = "alert" $status = "success" $category.generic = "Anomaly" $category.high = "User Behavior Anomaly" $category.low = "Detection" $id = "PT_SIEM_Work_at_night $importance = "medium" } Если список надо вести вне правила. (Активные списки) Конструкция in_active_set Если в поле надо поискать шаблон Конструкция match (не путать с выражением из PDQL) event TeamViewer_detect: key: event_src.host filter { correlation_name == null and category.generic == "Configuration Management" and category.high == "System Configuration Management" and in_list(["OS Service Detection","OS Service Modification", "OS Service Resumption"],category.low) and match(object.name,"*TeamViewer*") != false and status=="success" and not in_active_set("authorized_to_run_team_viewer_hosts_list", event_src.host) } Активные списки (active_sets.json) Если надо поместить в инцидент все подобные события за промежуток времени Конструкция timer event TeamViewer_detect: key: event_src.host filter { correlation_name == null and category.generic == "Configuration Management" and category.high == "System Configuration Management" and in_list(["OS Service Detection","OS Service Modification", "OS Service Resumption"],category.low) and match(object.name,"*TeamViewer*") != false and status=="success" and not in_active_set("authorized_to_run_team_viewer_hosts_list", event_src.host) } rule TeamViewer_service_detect: TeamViewer_detect+ timer 10m Модельные корреляции Проекция endpoints C:\Program Files\Positive Technologies\MaxPatrol SIEM Core\Projections\Layers\Projections.xml Fqdn Cvss Env.[AR,CR,IR,AI] Groups IpEndpoints TransportEndpoints. .[Uri,Port,Status, Protocol,Vulners] Softs. .[Uri,Port,Protocol, Type,Vulners] Модельные корреляции Пример: проекция endpoints.TransportEndpoints query WhatsHappened() from endpoints event One: filter {exec_query} event Other: query VulnerPort($ip, $port, $cve) from endpoints { data.TransportEndpoints any ( Uri == $ip and Port == $port and Status == "Open" and Vulners == $cve) } rule Attention: One -> Other on One { … } on Other { … } event ExploitOnVulnerPort: key: dst.ip filter { object == "alert" and action == "detect" and event_src.category == "IDS/IPS" and exec_query("VulnerPort", [dst.ip, dst.port, object.property]) } emit { … } rule Exploit_On_Vulner_Port: ExploitOnVulnerPort Модельные корреляции Пример: проекция endpoints.Groups & TransportEndpoints (Проверка членства актива в группе) query WhatsHappened() from endpoints event One: filter {exec_query} event Other: rule Attention: One -> Other on One { … } on Other { … } query DMZHostWithOpenPort($ip,$port) from endpoints { data.Groups == "DMZ" and data.TransportEndpoints any (Uri == $ip and Port == $port and Status == "Open") } event AttackOnOpenPortInDMZ: key: dst.ip filter { object == "attack" and action == "detect" and status == "success" and event_src.category == "IDS/IPS" and exec_query("DMZHostWithOpenPort", [dst.ip, dst.port]) } rule DMZ_host_attack: AttackOnOpenPortInDMZ[5] within 1d emit { … } Модельные корреляции Пример: проекция endpoints.Groups & TransportEndpoints (Проверка членства актива в группе) query WhatsHappened() from endpoints event One: filter {exec_query} event Other: rule Attention: One -> Other on One { … } on Other { … } emit { … } query UserHosts($ip) from endpoints { data.Groups == "Users" and data.TransportEndpoints any ( Uri == $ip ) } query NetworkDeviceHosts($ip) from endpoints { data.Groups == "Network Devices" and data.TransportEndpoints any ( Uri == $ip ) } event ExploitOnVulnerPort: filter { id == "PT_Cisco_IOS_syslog_SEC_6_IPACCESSLOGS" and exec_query("NetworkDeviceHosts", [event_src.host]) and exec_query("UserHosts", [src.ip]) } rule ACL_deny_packets_from_unauthorized_host: DenyPacketsFromHost Модельные корреляции Пример: проекция endpoints.Env. Как обнаружить угрозу критически важному активу query WhatsHappened() from endpoints event One: filter {exec_query} event Other: rule Attention: One -> Other on One { … } on Other { … } emit { … } query CriticalHost($ip, $hostname) from endpoints { ( data.IpEndpoints == $ip or data.Fqdn == $hostname ) and data.Env.AI == "High" # AR,CR,IR – AvailabilityRequirement etc. } # AI - AssetImportance event Malware_detected_src: filter { correlation_name == null and src.host != null and action == "detect" and category.generic == "Malware" and ( category.low == "Detection" or category.low == "Epidemic" ) and ( importance == "medium" or importance == "high" ) and exec_query("CriticalHost", [src.ip, src.hostname]) } rule Critical_host_threat_detection: Malware_detected_src or Malware_detected_event_src or Attack_detected_dst or Attack_detected_event_src Табличный список ― Разделяются на списки • для правил обогащения и • для правил корреляции ― Записи могут быть постоянными и временными ― Записи могут редактироваться из UI практически «на лету» ― При превышении максимального размера усекаются до типичного Табличный список Список может импортироваться/экспортироваться в формате CSV "_last_changed";"object" "26.04.2018 14:19:47";"малина" "26.04.2018 14:19:47";"крыжовник" "26.04.2018 14:19:47";"ромашка" "26.04.2018 14:19:47";"подснежник" "26.04.2018 14:19:47";"банан" "26.04.2018 14:19:47";"киви" "26.04.2018 14:19:47";"клубника" "26.04.2018 14:19:47";"черника" Табличный список: справочник Пример: применение табличного списка в качестве справочника (ср. с активным списком) query GetSmth() from TableList event One: filter {exec_query} event Other: rule Attention: One -> Other on One { … } on Other { … } emit { … } query Get_File_Extension($extension) from Cryptor_file_extensions { extension == $extension } event File_modified: key: event_src.host, subject.name, subject.domain, datafield3 filter { ( id == "PT_Positive_Technologies_Endpoint_Monitor_filemonitor_FileDataModified" or id == "PT_Positive_Technologies_Endpoint_Monitor_filemonitor_FileOverwritten" or id == "PT_Positive_Technologies_Endpoint_Monitor_filemonitor_FileRenamed" ) and object.type == "file" and status == "success" and exec_query( "Get_File_Extension", [lower(string(regex(object.name, "(\.\w+)$", 1)))] ) } rule Endpoint_monitor_Mass_file_modification: (File_modified[100] with different object.name) within 60s Табличный список: хранение данных Пример: применение табличного списка для хранения промежуточных данных Здесь правило Cisco_FW_Bruteforce_success_from_src_to_dst_by_user_with_tables пишет в список, а правило Cisco_FW_Execute_show_run_after_success_bruteforce читает из него Табличный список: хранение данных Пример: запись в таблицу query GetSmth() from TableList event One: filter {exec_query} event Other: rule Attention: One -> Other on One { … } on Other { … } insert_into { … } emit { … } rule Cisco_FW_Bruteforce_success_from_src_to_dst_by_user_with_tables: (Account_login_failed[5,] -> Account_login_success) within 5m on Account_login_success { $dst.ip = event_src.ip $dst.hostname = event_src.hostname $dst.host = event_src.host $dst.asset = event_src.asset $src.ip = src.ip $src.hostname = src.hostname $src.host = src.host $src.asset = src.asset $subject.name = subject.name $event_src.vendor = event_src.vendor $event_src.title = event_src.title } insert_into Success_bruteforce_on_host_table { host = $dst.host user = $subject.name } Табличный список: хранение данных Пример: чтение из таблицы query GetSmth() from TableList event One: filter {exec_query} event Other: rule Attention: One -> Other on One { … } on Other { … } emit { … } query Host_user_check($host, $user) from Success_bruteforce_on_host_table host == $host and user == $user } event Cisco_ASA_show_run: key: event_src.host filter { event_src.host != null and subject.name != null and id == "PT_Cisco_ASA_FWSM_PIX_syslog_111009_user_executed_show" and match(object.value, "show running-config*") and exec_query("Host_user_check", [event_src.host, subject.name]) } rule Cisco_FW_Execute_show_run_after_success_bruteforce: Cisco_ASA_show_run { Табличный список: агрегатные функции Пример: возврат ассоциативного массива из табличного списка query GetSmth() from TableList qhandler event One: filter {exec_query} event Other: rule Attention: One -> Other init { exec_query } on One { … } on Other { … } emit { … } PositiveTable query PositiveQuery ($check_url) from PositiveTable { Url == $check_url and Url Port Status Duration Port == 22 and Status == "Open" 192.0.2.10 22 Open 41 } 192.0.2.11 22 Open 33 qhandler { 192.0.2.12 22 Open 67 $get_max_duration = max(Duration) $get_min_duration = min(Duration) $get_avg_duration = avg(Duration) $get_count = count() } ... rule Example: Event # Присваивание переменным максимального, минимального и среднего времени # открытия порта 22 для переданного в запрос IP-адреса узла init { $get_duration = exec_query("PositiveQuery", [dst.ip]) $max_duration = $get_duration["$get_max_duration"] $min_duration = $get_duration["$get_min_duration"] $avg_duration = $get_duration["$get_avg_duration"] $count = $get_duration["$get_count"] } Табличный список: агрегатные функции Перечень агрегатных функций Функция Возвращаемое значение min(<Имя столбца>) Наименьший элемент в результатах запросов max(<Имя столбца>) Наибольший элемент в результатах запросов avg(<Имя столбца>) Среднее значение элементов, округленное до целого median(<Имя столбца>) Значение медианного элемента. При четном числе элементов выбирается нижнее медианное значение sum(<Имя столбца>) Суммы всех элементов результатов запроса count() Количество элементов в результатах запроса <Имя столбца> Первый элемент из результатов запроса Табличный список Полный синтаксис запроса query: limit и skip query <Название запроса>(<Аргументы запроса>) from <Название табличного списка> { <Условие запроса> } qhandler { <Ключ 1> = <Функция 1>(<Имя столбца 1>) <Ключ 2> = <Функция 2>(<Имя столбца 2>) ... } limit <Максимальное число возвращаемых строк> skip <Количество строк, исключаемых из результата> MaxPatrol SIEM Правила обогащения ptsecurity.ru Схема работы MaxPatrol SIEM Server Positive Technologies MaxPatrol SIEM Версия XX.X Руководство разработчика Правила обогащения Структура правила обогащения query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> } enrichment <Название правила обогащения> enrich <Название события> enrich_fields { <Блок операторов enrich_fields> } insert_into <Название табл. списка> { <Блок операторов insert_into> } Правила обогащения Структура правила обогащения query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> } enrichment <Название правила обогащения> enrich <Название события> enrich_fields { <Блок операторов enrich_fields> } insert_into <Название табл. списка> { <Блок операторов insert_into> } Директива event — объявление события для обогащения Правила обогащения Структура правила обогащения query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> } enrichment <Название правила обогащения> enrich <Название события> enrich_fields { <Блок операторов enrich_fields> } insert_into <Название табл. списка> { <Блок операторов insert_into> } Директива enrichment — Название правила обогащения Правила обогащения Структура правила обогащения query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> } enrichment <Название правила обогащения> enrich <Название события> enrich_fields { <Блок операторов enrich_fields> } insert_into <Название табл. списка> { <Блок операторов insert_into> } Директива enrich — Обработчик события Правила обогащения Структура правила обогащения query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> } enrichment <Название правила обогащения> enrich <Название события> enrich_fields { <Блок операторов enrich_fields> } insert_into <Название табл. списка> { <Блок операторов insert_into> } Директива query — Объявление запроса к табличному списку Правила обогащения Структура правила обогащения Структура правила корреляции query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> } enrichment <Название правила обогащения> enrich <Название события> enrich_fields { <Блок операторов enrich_fields> } insert_into <Название табл. списка> { <Блок операторов insert_into> } query <Название запроса>(<Аргументы>) from <Название табличного списка> { <Условие запроса> } event <Название события>: filter { <Условие отбора события> exec_query( <Название табл. списка>, <список аргументов>) } rule <Название правила корреляции> on <Название события> { <Блок операторов обработчика> } insert_into <Название табл. списка> { <Блок операторов insert_into> } Правила обогащения: запись в таблицу Инструкция insert_into Арифметические операции при вставке в данных табличный спискок enrichment <Название правила обогащения> enrich <Название события> insert_into <Название табличного списка> { <Имя столбца-ключа> = <Значение ключа> insert_min(<Имя столбца 1>, <Значение для записи 1>) insert_max(<Имя столбца 2>, <Значение для записи 2>) insert_inc(<Имя столбца 3>) insert_dec(<Имя столбца 4>) } Арифметические операции при вставке Перечень агрегатных функций Функция Возвращаемое значение insert_min(<Имя столбца>, $f) Сравниваются два значения: указанное во втором аргументе функции и содержащееся в ячейке столбца, указанного в первом аргументе. В ячейку заносится меньшее из значений insert_max(<Имя столбца>, $f) Сравниваются два значения: указанное во втором аргументе функции и содержащееся в ячейке столбца, указанного в первом аргументе. В ячейку заносится большее из значений insert_inc(<Имя столбца>) Значение ячейки указанного столбца увеличивается на единицу insert_dec(<Имя столбца>) Значение ячейки указанного столбца уменьшается на единицу Табличный список: агрегатные функции Пример: возврат ассоциативного массива из табличного списка query GetSmth() from TableList qhandler event One: filter {…} enrichment Example enrich One: enrich_fields { exec_query } insert_into Table { … } query PositiveQuery ($check_url) from PositiveTable { Url == $check_url and Url Port Port == 22 and Status == "Open" 192.0.2.10 22 } 192.0.2.11 22 qhandler { 192.0.2.12 22 $get_max_duration = max(Duration) $get_min_duration = min(Duration) $get_avg_duration = avg(Duration) $get_count = count() } enrichment Example enrich Event: enrich_fields { $get_duration = exec_query("PositiveQuery", [dst.ip]) $max_duration = $get_duration["$get_max_duration"] $min_duration = $get_duration["$get_min_duration"] $avg_duration = $get_duration["$get_avg_duration"] $count = $get_duration["$get_count"] datafield1 = "Url_" + string(dst.ip) datafield2 = "Max_duration_" + string($max_duration) } PositiveTable Status Duration Open 41 Open 33 Open 67 Табличный список: агрегатные функции Перечень агрегатных функций Функция Возвращаемое значение min(<Имя столбца>) Наименьший элемент в результатах запросов max(<Имя столбца>) Наибольший элемент в результатах запросов avg(<Имя столбца>) Среднее значение элементов, округленное до целого median(<Имя столбца>) Значение медианного элемента. При четном числе элементов выбирается нижнее медианное значение sum(<Имя столбца>) Суммы всех элементов результатов запроса count() Количество элементов в результатах запроса <Имя столбца> Первый элемент из результатов запроса Табличный список Полный синтаксис запроса query: limit и skip query <Название запроса>(<Аргументы запроса>) from <Название табличного списка> { <Условие запроса> } qhandler { <Ключ 1> = <Функция 1>(<Имя столбца 1>) <Ключ 2> = <Функция 2>(<Имя столбца 2>) ... } limit <Максимальное число возвращаемых строк> skip <Количество строк, исключаемых из результата> Спасибо за внимание! ptsecurity.ru