# Интенсив 2 :::success Все файлы доступны по этой [ссылке](https://disk.yandex.ru/d/h8c8M1zkCGNEQw). В папке **SSH_login_** хранятся файлы для правила нормализации №1, в **read_a_file** - файлы для второго правила нормализации. Также я приложила расширенные файлы с логами (делала их для себя, чтобы проверить работоспособность с разными входными данными), названия сохранила родные Второе задание хранится в папке **correl_rule_for_suspicious_login** Файл с входными данными - **correl_file** ::: # Правила нормализации ## Событие входа пользователя по SSH **Правило нормализации** ![](https://i.imgur.com/Mnh4eKO.png) :::info Посмотрим на строчку 3: данные нам логи всегда начинаются с **<"какое-то число">**. Предпологаем, что оно может меняться, но всегда является числом, поэтому выбираем тип данных *NUMBER*, но в переменнуб не заносим, ибо оно не даст нам особо никакой информации важной. Следующим в логах идёт время. Так как у нас есть таксономическое поле *time*, а время присутствует в любых логах, выбираем тип данных DATETIME и присваиваем его полю time. Часть лога, включающая **event_src.hostname**, встречается в логах не всегда, поэтому делаем эту чать опциональной (используем "?"), а таксономическое поле теперь может теперь принимать одно слово с некоторыми расширениями (имя источника может содержать дефис и подчеркивания, но при 100% уверености в обратном WORDDASH можно заменить на WORD) Поле **datafiled1** содержит одно слово - "OK"|"FAIL"|"FAILURE", показатель того, было ли действие успешным. Впоследствии, на значании этого поля мы создаем условную конструкцию для определения значения поля **success** (9-13 строчки). Имя юзера делалось по аналогии с полем event_src.hostname, единственное, оно не является опциональным, поэтомы знак вопроса мы не ставим. Теперь поговорим про последнюю часть лога: "tty: ssh". Я намеренно оставила её константой, так как посчитала, что нам приходят именно события о подключении по SSH, возможно, так настроены логи ("Событие входа пользователя по SSH:" - это цитата из файла с заданиями, на основании которой я сделала такой вывод). Но если всё-таки нам приходят логи о подключениях по разным протоколам, то мы эту часть должны заменить на tty: {protocol.layer7 = WORD}, а также в методанных вместо SSH написать {protocol.layer7}. Остальные данные были приняты константами на основании двух логов. Начиная с пятой строки, думаю, пояснения не нужны, так как мы просто заполняли необходимые поля в соответствии с доступной информацией. ::: **Листинг** ``` #datafield1 - статуст ssh входа TEXT = '<{NUMBER}>{time = DATETIME} {"Message forwarded from" event_src.hostname = WORDDASH":"?} audit: {msgid = WORDDASH} root { datafield1 = WORD} sshd user: {subject.account.name = WORDDASH} tty: ssh' 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_SSH_login" ``` **Методанные** Здесь у меня 4 условия: * вход успешен, форвардер известен * вход неудачен, форвардер известен * вход успешен, форвардер неизвестен * вход неудачен, форвардер неизвестен Так как я посчитала, что знать о форвардере события (при наличии этой информации) было бы полезно. ![](https://i.imgur.com/nkCpBAj.png) **Запуск сценария и его результат** Сценарий отработал успешно, локализация для разных событий тоже Русский ![](https://i.imgur.com/BIaMmjL.png) Английский ![](https://i.imgur.com/u4x9Dqs.png) ## Событие чтения конфигурационного файла операционной системы **Правило нормализации** ![](https://i.imgur.com/onmpTyU.png) :::info Здесь сделано всё по аналогии с первым правилом, поэтому остановимся только на ключевых моментах. Появилось ещё одно новое поле - datafield2, возвращающее имя приложения, использованного для чтения, формат данных - WORD, так как приложения для чтения не содержат в названии подчеркиваний и дефисов (насколько мне известно, если ошибаюсь, тогда следуюет заменить тип на WORDDASH). Также ввели поле object.path - там хранится путь до файла, который прочитали. Наиболее подходящее значение для поля action - view, а для object - file (хоть оно и устаревшее) Поле satus принмает значение в зависимости от поля datafield1, для это написано условие (10-14 строчки). ::: **Листинг** ``` #datafield1 - статуст просмотра файла (ОК или нет) #datafield2 - с помощью чего был прочитан файл TEXT = '{time = DATETIME} {event_src.hostname = WORDDASH} local0:info audit: {msgid = WORDDASH} {subject.account.name = WORDDASH} {datafield1 = WORD} {datafield2 = WORD} audit object read event detected {object.path = STRING}' subject = "account" action = "view" object = "file" 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 = "read_a_file" ``` **Методанные** Всего два варианта: успешное прочтение или нет. ![](https://i.imgur.com/pq4KZf1.png) **Запуск сценария и его результат** Так же всё запустилось и отработало без ошибок. Русский ![](https://i.imgur.com/BIaMmjL.png) Английский ![](https://i.imgur.com/u4x9Dqs.png) # Правило корреляции ## Листинг :::info Инструкцию init я не стала заполнять (не придумала, какое новое поле необходимо, чтобы потом его использовать), инструкции on содержат в себе просто самое важное поле - имя юзера. Само правило значит, что после события "чтение файла" должно быть событие "вход в систему", причём юзер должен отличаться (это реализовано с помощью оператора with different), а время не должно превышать 5 минут (с помощью оператора within). Кстати, ключами событий стал форвардер событий (единственное, что было общее у них). Фильтрами для событий стали стандартные subject, action, object, status, а в фильтре для события "чтение файла" добавила ещё и object.path (чтобы не было срабатывания на чтение других файлов). ::: ``` event Another_User_login: key: event_src.hostname filter { correlation_name == null and subject == "account" and action == "login" and object == "system" and status == "success" } event Read_the_shadow_file: key: event_src.hostname filter { correlation_name == null and subject == "account" and action == "view" and object == "file" and status == "success" and object.path == "/etc/shadow" } rule Read_the_file_then_login_under_another_user: (Read_the_shadow_file -> Another_User_login) with different(subject.account.name) within 5m init { } on Read_the_shadow_file { $datafield10 = subject.account.name } on Another_User_login { $subject.account.name = subject.account.name } emit { $correlation_type = "event" $subject = "account" $action = "login" $object = "system" $status = "success" $importance = "medium" } ``` ## Методанные Заполнены по анологии с методанными для правил нормализации. ![](https://i.imgur.com/bu4mFeN.png) ## Тесты > Файл с событиями я приложила на яндекс диск. Успешное срабатывание. Все прописанные поля отобразились (отмечены сиреневым на скриншоте) ![](https://i.imgur.com/sIAiwRT.png) Для следующих событий провило не срабатывает (и логично, это просто проверка): * Другой форфардер * Вход в тот же аккаунт * Провальное прочтение * Провальный вход * Разница между событиями больше 5 минут * Читал не тот файл ![](https://i.imgur.com/vrldC6K.png)