# Гришанов Матвей Сергеевич – Интенсив №2. Нормализация и корреляция событий информационной безопасности.
[toc]
---
## Установка утилиты PTSIEMSDK GUI
Скачиваем подготовленный архив и извлекаем из него файлы в выбранную заранее директорию.

---
Переходим в директорию **gui** и запускаем **standalone** приложение.

---
## Изучение пользовательского интерфейса утилиты
Вкладка **"Редактор объектов"** -- область, которая используется для создания и редактирования формул и правил.

---
Вкладка **"Сценарии"** -- область, предназначенная для создания симуляции работы **SIEM**.

---
Вкладка **"Настройка"** -- данная область отвечает за настройки параметров **пути**, **редактора объектов**, **сценариев**. Во вкладочке **общее** можно сменить локализацию программы, выбрав русский язык или английский.




---
### Меню "Справка"
Меню **"Справка"** -- вызывается с помощью клавиши **(F1)** или по нажатии на клавишу в правом нижнем углу интерфейса программы.
Вкладка **"Таксономия"** -- используется для описания всех полей, использующихся в системе.
:::info
:information_source: Данный раздел справочника пригодится для написания формул нормализации.
:::

Так как во всех событиях описывается субъектно-объектное взаимодействие, то во вкладке **"Таксономия"** мы можем видеть поля:
1. Субъектов (**тех, кто начал взаимодействие**)

2. Действий (**описывают действие над объектом**)

3. Объектов (**тех, над кем взаимодействие совершается**)

4. Адреса (**источника взаимодействия**)

5. Адреса (**получателя**)

6. Описания источника события

7. Другие

8. Настройки агрегации инцидентов

---
Вкладка **"Горячие клавиши"** -- содержит в себе все **"хоткеи"** программы.

---
## Настройка папки с результатами для сценариев
Для того, чтобы приступить к работе в приложении необходимо указать папку, куда будут сохраняться все результаты работы во вкладке **"Сценарии"**.
Заходим во вкладку **"Настройка"** и выбираем **"Пути"**.

---
Далее в области **"Прочее"** задаём папку для результатов.

---
# Нормализация события
Нормализация события — это процедура приведения необработанного события к нормализованному виду в соответствии с заранее заданным для источника и типа события правилом нормализации.
Из этого следует, что нормализованным событием называется то событие, которое состоит из полей, заполненных необработанными данными согласно составленному правилу нормализации.
## Разработка формулы нормализации для событий 1-ого типа
Cоздаём формулу нормализации, используя кнопочку **"Создать"** в правом верхнем углу.

---
Далее необходимо импортировать сырые события в рабочее пространтсво.

---
Выбираем файл read_config_raw_events.txt в качестве необработанного события.

---
В области **"Исходное событие"** появилось загруженное событие.

---
Для того, чтобы увидеть его полностью -- необходимо включить **"Перенос по словам"** в контекстном меню, которое открывает по нажатии ПКМ.

---
После смены режима отображения.
1. Первое событие.

2. Второе событие.

Беглый анализ позволяется понять, что события отличаются только по параметрам времени и пути.
---
Переходим к вставке шаблона, где выбираем **TEXT**.

Вставленный шаблон **TEXT**.

:::info
:information_source: Исходя из возможностей приложения, возможно использовать 4 типа шаблона:
**TEXT** -- неструктурированная строка.
**JSON** -- структурированный формат.
**TABULAR** -- очень похож на формат **JSON**, чаще всего используется с **DB**.
**EVENTLOG** -- используется для логов **Windows** (похож на **JSON**).
:::
---
Далее мы вставляем **"Первое событие"** в форматную строку **TEXT**.

---
:::info
:information_source: Начинаем постепенно редактировать нашу строку.
:information_source: Анализируем её и выбираем статические участки **(Якорные)** и динамические участки **(Их необходимо парсить и сохранять в поля)**.
:information_source: А с использованием **"Токенов"** мы разбираем событие на части и таким образом получаем данные.
:::
---
Начнём с **даты**, которая является **динамическим участком**.

---
Заменяем **дату** на специальный **токен** `DATETIME` и сохраняем метку времени в поле `time`.
:::info
:information_source: Для выбора поля используем справочник утилиты. Также частенько поглядываем в **developguide**.
:::

---
Участок события распарсится и будет сохранён в метку времени `time`.
:::warning
:warning: Так как присвоение полю time было сделано в форматной строке, то строчку `time = ` из шаблона необходимо удалить.
:::

---
Следующий фрагмент `aix53`, который является источником события (узлом-источником), мы присвоим полю `src.hostname`, а в качестве токена будем использовать **WORDDASH** (используется для распознавания отдельных слов).

---
Далее строка `local0:info` -- это сообщение и оно информационное.
Оставляем без изменений.
---
Уникальным идентификатором типа события является следующий фрагмент -- `OS_CONF_READ`. Согласно справочнику идентификатор типа события использует поле **msgid**.

---
Следующим фрагментом является имя пользователя -- `mp`. В данном случае пользователь является субъектом, поэтому поле -- `subject.account.name`. Типом данных является `STRING`.

---
Фрагмент `OK` является показателем действия (**OK|FAIL|FAILURE**). Используя справочник, можно понять, что полем будет являться `datafield1`. `WORD` -- токен.

---
Следующий фрагмент `cat`, который является именем утилиты, использованной для чтения файла. Пользуясь справочником, можно понять, что полем будет являться `subject.process.name`. `STRING` -- токен.

---
Фрагмент `/etc/shadow` - это полный путь к файлу, который считывают утилитой `cat`. Используем поле `object.fullpath` и токен `STRING`.

---
Заполняем поля необходимые для проведения тестового сценария.
```
subject = "account" # выбираем этот параметр, так как имеется имя пользователя.
action = "view" # используем просмотр.
object = "file" # файл, который указан по пути /etc/shadow
#Воспользуемся if else для того, чтобы разделять status событий, которые могут быть как успешными, так и неудачными.
if datafield1 == "OK" then
status = "success"
else
status = "failure"
endif
importance = "info" # информация
# Поля событий заполняются в соответствии с заданием, используя нижний регистр
event_src.vendor = "ibm"
event_src.title = "aix"
event_src.category = "Operating system"
# Идентификатор нормализации
id = "IBM_AIX_OS_CONF_READ"
```

---
Теперь необходимо провести тестовый запуск правила нормализации. Для того, чтобы запустить проверку - необходимо нажать кнопку "Запуск".


:::success
:star: Тесты прошли успешно!
:::
---
Результат 1-ого события.

Результат 2-ого события.

---
Сохраняем написанное правило нормализации в отдельную папку, которая было создана заблаговременно.

---
## Создание заполненной пользовательской локализации и файла метаинформации с критериями локализации для 1-ого типа событий
Существует возможность создавать и редактировать метаданные для локализации в наборы данных для отладки правил нормализации, обогащения, агрегации и корреляции.
Метаданные используются для хранения правил локализации регистрируемых по правилам событий и описаний правил.
Для того, чтобы открыть поле для редактирования метаданных - необходимо нажать на кнопку **"Редактор метаданных"**.

---
При создании необходимо выбрать стандартный шаблон, чтобы поля редактора метаданных совпадали с теми, что указаны на картинке.
```
#Описание события
EventDescriptions:
- Criteria: <Условие правила локализации 1>
LocalizationId: <Ключ правила локализации 1>
- Criteria: <Условие правила локализации 2>
LocalizationId: <Ключ правила локализации 2>
```
Секция `Criteria` необходима для ввода условия правила локализации.
Секция `LocalizationId` предназначена для ввода идентификатора (ключа) для сопоставления условия правила локализации с одним описанием событий, указанным в поле **RU**, и одним описанием, указанным в поле **EN**.

---
Заполняем поле **"Метаданные"**:
В качестве критериев указываем условия, которые являются определяющими - **OK|FAIL|FAILURE**. Также не забываем отметить ключи правил локализации для их связи.
```
EventDescriptions:
- Criteria: id = "IBM_AIX_OS_CONF_READ" and datafield1 = "OK"
LocalizationId: IBM_AIX_OS_CONF_READ_file_read_SUCCESS
- Criteria: id = "IBM_AIX_OS_CONF_READ" and datafield1 = "FAIL" or datafield1 = "FAILURE"
LocalizationId: IBM_AIX_OS_CONF_READ_file_read_FAILURE
```

---
Заполняем поле **"RU"**:
В данном поле необходимо указать краткие отдельные описания для событий, указав при этом `LocalizationId`.
```
Description: Событие чтения конфигурационного файла операционной системы
EventDescriptions:
- LocalizationId: IBM_AIX_OS_CONF_READ_file_read_SUCCESS
EventDescription: Пользователь {subject.account.name} с именем узла {src.hostname} прочитал конфигурационный файл системы по пути {object.fullpath} с помощью утилиты {subject.process.name}
- LocalizationId: IBM_AIX_OS_CONF_READ_file_read_FAILURE
EventDescription: Пользователь {subject.account.name} с именем узла {src.hostname} не смог прочитать конфигурационный файл системы по пути {object.fullpath} с помощью утилиты {subject.process.name}
```

---
Заполняем поле **"EN"**:
Аналогичным образом заполняем поля и для **EN-локализации**.
```
Description: Operating system configuration file read event
EventDescriptions:
- LocalizationId: IBM_AIX_OS_CONF_READ_file_read_SUCCESS
EventDescription: User {subject.account.name} with hostname {src.hostname} read the system configuration file at {object.fullpath} using the {subject.process.name} utility
- LocalizationId: IBM_AIX_OS_CONF_READ_file_read_FAILURE
EventDescription: User {subject.account.name} with hostname {src.hostname} could not read system configuration file at {object.fullpath} using {subject.process.name} utility
```

---
Проведем тестирование.
Необходимо зайти во вкладку **"Сценарии"**, где нужно настроить параметры `BUILD` и `RUN`.
`BUILD FORMULAS` - необходимо выбрать папку, где находится наша формула нормализации.
`BUILD LOCALIZATION` - выбираем папку, где находится локализация.
В параметрах `RUN` выбираем файл с исходными события и ставим галочки на пунктах `NORMALIZE` и `LOCALIZE`.

---
Нажимаем кнопку **"Запуск"** и начинаем тестирование.

---
:::success
:star: Все локализации успешно сработали!
:::




---
## Файлы тестов
[Тесты правила нормализации для события 1-ого типа](https://disk.yandex.ru/d/WHU7fqwTGAOnAQ)
---
## Разработка формулы нормализации для событий 2-ого типа
Следующим шагом в выполнении данной домашней работы становится написание второго правила нормализации.
Создаем новое правило нормализации и выбираем **"TEXT"** шаблон для формулы.
Вносим в поле текст наше необработанное событие.

---
Первым делом заменяем фрагмент `<134>`, так как он может динамически изменяться в событиях. Используем токен `NUMBER`.

---
Следующим фрагментом является дата, которая будет сохраняться в метку времени `time`. Она в свою очередь имеет токен `DATETIME`.

---
Далее источник события, который мы обозначаем с помощью поля `src.hostname` и токена `WORDDASH`. Также отмечаем, что этот фрагмент опционален, используя символ `?`.

---
Уникальным идентификатором типа события является следующий фрагмент -- `USER_Login`. Согласно справочнику идентификатор типа события использует поле **msgid**.

---
Фрагмент `OK` является показателем действия (**OK|FAIL|FAILURE**). Используя справочник, можно понять, что полем будет являться `datafield1`. `WORD` -- токен.

---
Следующим фрагментом является имя пользователя -- `ektest`. В данном случае пользователь является субъектом, поэтому поле -- `subject.account.name`. Типом данных является `STRING`.

---
Последним фрагментом является протокол передачи данных (уровня приложения по модели **OSI**). Полем является `protocol.layer7`, а токеном `WORD`.

---
Заполняем оставшиеся поля аналогичным образом, что и в предыдущем правиле нормализации. Изменяем параметр `action` и `object`, а также `id`.
```
subject = "account"
action = "login"
object = "system"
if datafield1 == "OK" then
status = "success"
else
status = "failure"
endif
importance = "info"
event_src.vendor = "ibm"
event_src.title = "aix"
event_src.category = "Operating system"
id = "IBM_AIX_USER_LOGIN"
```

---
Проверяем работу правила нормализации на исходных событиях.


:::success
:star: Тестирование прошло успешно!
:::
---
Результат 1-ого события.

Результат 2-ого события.

---
Сохраняем правило нормализации в заранее подготовленной папке.

---
## Создание заполненной пользовательской локализации и файла метаинформации с критериями локализации для 2-ого типа событий
В редакторе метаданных заполняем все поля аналогично предыдущему правилу нормализации. Изменяем описание событий.

---
Проведем тестирование.
Необходимо зайти во вкладку **"Сценарии"**, где нужно настроить параметры `BUILD` и `RUN`.
`BUILD FORMULAS` - необходимо выбрать папку, где находится наша формула нормализации.
`BUILD LOCALIZATION` - выбираем папку, где находится локализация.
В параметрах `RUN` выбираем файл с исходными события и ставим галочки на пунктах `NORMALIZE` и `LOCALIZE`.

---
Нажимаем кнопку **"Запуск"** и начинаем тестирование.

---
:::success
:star: Все локализации успешно сработали!
:::




---
## Файлы тестов
[Тесты правила нормализации для события 2-ого типа](https://disk.yandex.ru/d/_ZXA3RG0lNuW3A)
---
# Корреляция событий
**Корреляция событий** -- это процесс обнаружения событий информационной безопасности путем анализа потока нормализованных событий. При обнаружении в потоке событий
такой их последовательности, которая указана в условии одного из заранее настроенных правил корреляции, регистрируется корреляционное событие.
Создаем **правило корреляции** тем же образом, что и правило нормализации.

---
Директива **event** предназначена для объявления события, подлежащего корреляции. В каждом правиле корреляции нужно объявить хотя бы одно событие.
Для указания полей события и условия отбора используются инструкции **key** и
**filter**.
Формат вызова:
```
event <Название события>:
key:
<Поле события 1>, <Поле события 2>, ...
filter {
<Условие отбора события>
}
```
Инструкция **key** директивы **event** предназначена для указания полей события, по значению которых поток нормализованных событий будет разделяться на несколько потоков.
Инструкция **filter** директивы event предназначена для настройки условия отбора события.


---
Директива **rule** предназначена для описания правила корреляции. В директиве нужно указать название правила корреляции и условие его выполнения. Название должно быть уникальным в рамках всего набора правил корреляции (может состоять из букв латинского алфавита, цифр, знаков подчеркивания и точки, должно начинаться с прописной буквы).
Название правила корреляции: `IBM_AIX_success_reading_and_logon`
Условие выполнения:`(Successful_Reading -> Successful_Login) with different subject.account.name`
Также не забываем добавить оператор `timer`, который в нашей работе отвечает за то, что события произошли в течение 5 минут.

---
Инструкция **init** директивы **rule** предназначена для объявления переменных, используемых в инструкциях on и **insert_into** или в директиве **emit**. Переменным вы можете присвоить определенные значения. Блок операторов инструкции **init** выполняется один раз при регистрации первого события последовательности в условии правила корреляции.
В данной работе инструкция init не используется.

---
Инструкция on директивы **rule** (обработчик события) предназначена для выполнения
блока операторов при регистрации указанного события (событие должно быть объявлено в
директиве **event**).
Записываем блоки операторов, которые будут содержаться в правиле корреляции.


---
Директива **emit** предназначена для заполнения полей корреляционного события (названия
полей нужно начинать со знака доллара). Директива выполняется при выполнении условия
правила корреляции.

---
Итоговый код:
```
event Successful_Reading:
key:
event_src.host #Хост(источник события)
filter
{
correlation_name == null #Название корреляционного события
and event_src.title == "aix" #Название источника события
and action == "view" #Действие
and object == "file" #Объект
and status == "success" #Статус
and object.fullpath == "/etc/shadow" #Полный путь до объекта
}
event Successful_Login:
key:
event_src.host
filter
{
correlation_name == null
and event_src.title == "aix"
and action == "login"
and object == "system"
and status == "success"
}
rule IBM_AIX_success_reading_and_login: (Successful_Reading -> Successful_Login) with different subject.account.name timer 5m
init {}
on Successful_Reading
{
$event_src.hostname = event_src.hostname
$object.process.name = object.process.name
$subject.account.name = subject.account.name
}
on Successful_Login
{
$event_src.hostname = event_src.hostname
$protocol.layer7 = protocol.layer7
$datafield1 = subject.account.name
}
emit {
$correlation_type = "event"
$subject = "account"
$action = "access"
$object = "profile"
$status = "success"
$importance = "info"
}
```
---
Создаем сценарий из двух нормализованных событий, которые были получены в ходе предыдущего задания.
```
{"subject": "account", "action": "view", "object": "file", "status": "success", "datafield1": "OK", "event_src.category": "Operating system", "event_src.title": "aix", "event_src.vendor": "ibm", "id": "IBM_AIX_OS_CONF_READ", "importance": "info", "msgid": "OS_CONF_READ", "object.fullpath": "/etc/shadow", "src.hostname": "aix53", "subject.account.name": "mp", "subject.process.name": "cat", "time": "2022-05-19T09:50:06Z"}
{"subject": "account", "action": "login", "object": "system", "status": "success", "datafield1": "OK", "event_src.category": "Operating system", "event_src.title": "aix", "event_src.vendor": "ibm", "id": "IBM_AIX_USER_LOGIN", "importance": "info", "msgid": "USER_Login", "protocol.layer7": "ssh", "src.hostname": "sovma131", "subject.account.name": "ektest", "time": "2022-09-22T05:01:48Z"}
expect 1 {}
```
Запускаем составленный тестовый сценарий.

:::success
:star: Правило корреляции успешно сработало!
:::

---
## Файлы тестов
[Тесты правила корреляции](https://disk.yandex.ru/d/PcEDxUKV8elHEA)
---