# Интенсив 9 ## Задание 1 :::info Развенуть решение ELК на Linux host ::: ELK у меня уже был развернут в докере для универских лаб. запустим контейнеры в режиме демона, чтобы логи не летели: ![](https://i.imgur.com/KHrQN3x.png) теперь переходим к проверке. ### Elasticsearch Команда: `curl -X GET "localhost:9200" -u elastic:changeme`. В самом задании вы просили отправить запрос без логина и пароля, но уже вроде как с 19 года такие запросы не проходят, поэтому изпользуем флаг -u Ответ: ![](https://i.imgur.com/9eWZxnw.png) ### Kibana в браузере пишем http://192.168.132.148:5601. В результате видим приветсвие. ![](https://i.imgur.com/SnfbN4a.png) Далее можно писать http://localhost:5601, ибо результат будет тот же ![](https://i.imgur.com/8IuF1h8.png) ### Logstash На скриншоте видно, что он слушает tcp порт 5044. ![](https://i.imgur.com/9GvHV8d.png) #### А вот его настройки. Блок **input**: потоки данных от приложений-сборщиков логов принимаем на 5044 порт. Часть с tcp здесь не нужна, но мне нужна для себя, поэтому закроем на неё глаза 😅🙃 Блок **filter**: так как логи отправляются в формате json, нам необходимо сделать следующий фильтр, чтобы парсить json из поля *message*. Блок **output**: передавать данные в эластик с указанным индексом, где первая часть - это имя отправителя логов, а вторая - дата. Также указала логин и пароль, чтобы всё всегда заходило) ![](https://i.imgur.com/fVclmjb.png) ## Задание 2 :::info Развернуть стенд с windows + sysmon. Настроить логирование Sysmon. Должны быть события с id 10 ::: Event_id 10 в sysmon - это доступ к памяти процесса (lsass). Некоторые процессы порой обращатся к ней, но чтобы не ждать неопределённое количество времени создадим это событие сами. Для этого можно в разделе *Подробности* в диспетчере задач найти **lsass.exe** и сдампить его. В результате получим событие 10 Если посмотреть на него подробнее, то мы увидим, что доступ до lsass был осуществлённ из диспетчера задач. ![](https://i.imgur.com/xDHGD6i.png) кстати, если завершить принудительно lsass, то получается приколный вывод на обычные команды, а комп через минуту перезапускается. ![](https://i.imgur.com/R7g1Aqy.png) **Пара слов о настройке сисмона:** для базовой настроки я использовала конфиг с этого [резитория](https://github.com/SwiftOnSecurity/sysmon-config). Но события 10 в нём были отключены, поэтому дописала в файл конфиг ниже. Он тоже из интернета, но ссылку на него потеряла, поэтому прикрепляю так. :::spoiler Конфиг для sysmon (тык, чтобы увидеть) ``` <RuleGroup name="" groupRelation="or"> <ProcessAccess onmatch="include"> <!-- Detect Access to LSASS--> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\lsass.exe</TargetImage> <GrantedAccess>0x1FFFFF</GrantedAccess> </Rule> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\lsass.exe</TargetImage> <GrantedAccess>0x1F1FFF</GrantedAccess> </Rule> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\lsass.exe</TargetImage> <GrantedAccess>0x1010</GrantedAccess> </Rule> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\lsass.exe</TargetImage> <GrantedAccess>0x143A</GrantedAccess> </Rule> <!--Dumping credentials from services or setting up a keylogger--> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\csrss.exe</TargetImage> <!--Mitre T1098--> <!--Mitre T1075--> <!--Mitre T1003--><!-- depending on what you're running on your host, this might be noisy--> <GrantedAccess>0x1F1FFF</GrantedAccess> </Rule> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\wininit.exe</TargetImage> <!--Mitre T1098--> <!--Mitre T1075--> <!--Mitre T1003--><!-- depending on what you're running on your host, this might be noisy--> <GrantedAccess>0x1F1FFF</GrantedAccess> </Rule> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\winlogon.exe</TargetImage> <!--Mitre T1098--> <!--Mitre T1075--> <!--Mitre T1003--><!-- depending on what you're running on your host, this might be noisy--> <GrantedAccess>0x1F1FFF</GrantedAccess> </Rule> <Rule groupRelation="and"> <TargetImage name="technique_id=T1003,technique_name=Credential Dumping" condition="is">C:\Windows\system32\services.exe</TargetImage> <!--Mitre T1098--> <!--Mitre T1075--> <!--Mitre T1003--><!-- depending on what you're running on your host, this might be noisy--> <GrantedAccess>0x1F1FFF</GrantedAccess> </Rule> <Rule groupRelation="or"> <GrantedAccess name="technique_id=T1003,technique_name=Credential Dumping">0x0810</GrantedAccess> </Rule> <!-- Detect process hollowing--> <Rule groupRelation="or"> <GrantedAccess name="technique_id=T1093,technique_name=Process Hollowing">0x0800</GrantedAccess> <GrantedAccess name="technique_id=T1093,technique_name=Process Hollowing">0x800</GrantedAccess> </Rule> <!-- Detect process process injection--> <Rule groupRelation="or"> <GrantedAccess name="technique_id=T1055,technique_name=Process Injection">0x0820</GrantedAccess> <GrantedAccess name="technique_id=T1055,technique_name=Process Injection">0x820</GrantedAccess> </Rule> </ProcessAccess> </RuleGroup> ``` ::: ## Задание 3 :::info VM2 - Подключить WinlogBeat модуль по сбору событий на VM2 к ELK на VM1 ::: Сначала качаем приложение через vpn, потом редактируем файл, который представлен на скриншоте. По условию задания было не понятно, какие журналы пересылать. Но в пятом задании упоминалось о том, что нужно отфильтровать и показать только журналы sysmon & security, поэтому я отправляю их и ещё один дополнительный, чтобы потом можно было увидеть работу фильтра в пятом задании. Указываю, куда их отправлять (*output**), затем куда складывать логи и как их хранить (*loggin**). ![](https://i.imgur.com/TdHZ55K.png) Запускаем службу в диспетчере задач (можно это делать и через повершелл, но так быстрее для меня) ![](https://i.imgur.com/iWEm19o.png) Теперь зайдём на сервер. Мы можем создать индекс ![](https://i.imgur.com/TZUz3Hr.png) и увидеть отправленные события. ![](https://i.imgur.com/kIDXKru.png) ## Задание 4 :::info VM2 - Сэмулировать перехват хэшей паролей на VM2 c ипользованием mimikadze ::: Для начало нам было необходимо отключить защитника винды. Потом скачиваем мимикац и запускаем через cmd от имени админа (mimikatz.exe -> privilege::debug, чтобы проверить возможность действий). Выгружаем пароли: *sekurlsa::logonpasswords* ![](https://i.imgur.com/ZM1DtUn.png) Идём в Event_Viewer, находим событие: ![](https://i.imgur.com/3VBtpp2.png) ## Задание 5 :::info VM1 - Кибана настроить Дэшборды с построением визуализации группировки событий по MSGID с журналов VM2: security, sysmon ::: Создаём дашбор, группируем по полю **event_id**, увеличиваем в настройках количество столбцов с 5 до 100, чтобы отображались все id событий, иначе они группируются в "other". Получаем это, но здесь логи из трёх журналов, а нам нужно из двух ![](https://i.imgur.com/uBtek0U.png) Поэтому добавляем фильтр по полю **winlog.channel** с оператором *"is one of"* (ибо нам нужно или один журнал, или другой), так как в этом поле как раз записано имя журнала. ``` winlog.channel is one of Security, Microsoft-Windows-Sysmon/Operational ``` ![](https://i.imgur.com/fYVr1Qu.png) Сохраняем, смотрим. ![](https://i.imgur.com/jWapzg5.png) ## Задание 6 :::info VM1 – в Kibana настроить фильтр событий дампа паролей из шага 4, используя wildcard ::: **wildcard** - это использование "?" (любой один символ) и cимвола "*" (сколько угодно любых символов). Мы фильруем по двум полям: - *winlog.eventdata.SourceImage* - *winlog.eventdata.TargetImage* Так как мимикац может располагаться в любой папке, то ставим "*" сразу после поля, после неё пишем mimikatz.exe и соединяем со вторым полем с помощью логического И. **Фильтр:** ``` winlog.event_data.SourceImage:*mimikatz.exe AND winlog.event_data.TargetImage:*lsass.exe ``` Видим его во вкладке Open ![](https://i.imgur.com/EEatPkg.png) Результат работы - два события подошли. ![](https://i.imgur.com/WXs2xIm.png) ## Бонусное задание ### Часть 1. Подготовка стенда :::info VM1 – развернуть Apache Nifi. VM1 – настроить отправку Syslog сообщений на самого себя по 514 порту UDP. Отправить настроенный поток событий Syslog в Elasticsearch на VM1 через Nifi. Имя индекса Elasticsearch должно содержать дату создания индекса. ::: #### Установка Скачиваем [Nifi Apache](https://archive.apache.org/dist/nifi/1.16.3/). Распаковываем (`tar -xvf nifi-1.16.3.tar.gz`) и запускаем от root (`cd /bin && ./nifi.sh start`), чтобы потом не было проблем :::warning перед запуском я также установила java-11 ::: Переходим на страницу :::warning Небольшое пояснение скринов с разными адресами далее: Изначально я скачала 13 версию nifi, зашла в браузер на localhost:8080 (скрин ниже, как раз соответствует пункту из задания), начала создавать процессы, но ничего не работало. ListenSyslog не получал ничего. ![](https://i.imgur.com/3yvLQAe.png) Поэтому было принято решение установить новую версию, но с ней тоже возникли интересности, ибо по 8080 порту она не подключалась, а на 8443 была страница с авторизацией. А вот где брать пароль и логин?? Конечно же в гугле! Там есть [всё](https://jd-bots.com/2021/08/22/how-to-get-the-username-and-password-for-nifi/). Нужная команда `cat nifi-app_2022-10-10_16.0.log | grep -i 'generated'` далее скопировать логин и пароль Дальше я оставила скрины с 8443-портом. Предположим, что во время пилота это взбрло в голову заказчику) ::: Всё запускается, логи идут (видно, что отправлены в finally) ![](https://i.imgur.com/bQchgEv.png) #### Настройка rsyslog (он уже установлен, а так как является по сути аналогом обычного syslog решила не занимать и так маленькое количество памяти другой утилитой) Переходим в конфигурационный файл и снимаем комментарии со строк про приём логов на 514 порт udp ![](https://i.imgur.com/MhzLXBF.png) Прописываем какие логи (с любого источника, но со статусом информация, ибо у меня очень быстро уходит память при настройках "все со всего") и куда (наш локальный интерфейс) отправлять ![](https://i.imgur.com/zJUAvcR.png) Прописываем строчку на хранение логов: ![](https://i.imgur.com/bJrOOOt.png) Проверяем в wireshark - syslog шлёт логи: ![](https://i.imgur.com/XcDD2lP.png) #### Организуем коннект с elasticsearch В nifi выбираем два процесса: **ListenSyslog** и **PutElasticHTTP** первый процесс логи принимает по порту udp 514 (причём только в локальной сети) и передает второму процессу ![](https://i.imgur.com/A2iaxxc.png) Конфигурация ListenSyslog: ![](https://i.imgur.com/WKyp9kf.png) второй пока их не отпрвляет, разберёмся с настройкой Конфигурация PutElasticHTTP: Важный момент, я указала логин и пароль, так как были проблемы при работе с winlogbeat URL адрес указываю локальный, а также определяю формат индекса ![](https://i.imgur.com/LYFk8y4.png) Разобрались: elastic может принимать только данные в формате JSON, при прямой пересылке из ListenSyslog это условие нарушается. Поэтому создаём третий процесс - **AttributesToJSON**. Его имя говорит само за себя - получить атрибуты -> выдать их в формате JSON. Конфигурация AttributesToJSON: ![](https://i.imgur.com/7l0Og97.png) Теперь наша схема выглядит так: ![](https://i.imgur.com/MULIZTv.png) Перейдём в эластик и создадим индекс, а затем проверим его в списке Создание: ![](https://i.imgur.com/ySWwfE7.png) Список: ![](https://i.imgur.com/VeO4AV1.png) :::warning Снова небольшое отступление... Как вы можете видеть, у меня нет индексов с winbeat. Причина банальна: пересоздавала огромное множество виртуалок, удаляла старые, чтобы освободить место на ноутбуке, ибо не сразу поняла, что ставить \*.* @..... в rsyslog.conf не самая лучшая идея 😅 ::: ### Часть 2. Обогащение и изменение поля. За обогащение отвечает процесс *UpdateAttribute*. Добавим его на схему. ![](https://i.imgur.com/VvlP1kH.png) Базовые настройки весьма простые: добавить атрибут (имя любое, но лучше говорящее) -> определить значение (можем добавлять как константные значение, но нам они не особо нужны, так и динамические, используя существующее поле с информацией) Так как нам нужно вместо ip всегда выводить тот набор букв, используем константное значение. Конфигурация ![](https://i.imgur.com/tgleqHL.png) Теперь перейдём в Elasticseach и посмотрим Discovery. До изменения: ![](https://i.imgur.com/2UR8m3H.png) После: ![](https://i.imgur.com/nNBtOVS.png) ### Часть 3. Индексируемое поле времени изначально была идея использовать новый процесс (как в это [статье](https://nathanlabadie.com/adding-a-timestamp-to-elasticsearch-from-apache-nifi/)), но насколько я поняла, использовать такие запросы уже в эластике нельзя (но имя индексы я уже изменила 😬) Поэтому пришлось разбираться с UpdateAttribute, что было не очень легко, ибо документация немного лаконична. Не уверена, что дело во всех атрибутах, но при конфигурации из прошлого задания и добавлении атрибута @timestamp ничего не менялось. При этом сохранялся атрибут с временной меткой и именем syslog. Поэтому в новой конфигурации я удаляю атрибуты с именем syslog, а затем переопределяю им имена, чтобы информация логирования не пропала. Здесь же переопределяю атрибут @timestamp, выберем с точностью до мини секунд (благодаря этой [статье](https://blog.davidvassallo.me/2018/09/19/apache-nifi-from-syslog-to-elasticsearch/) и части [документации](https://www.elastic.co/guide/en/beats/filebeat/current/processor-timestamp.html)). Новая конфигурация ![](https://i.imgur.com/PQw6R7t.png) Долгожданный результат ![](https://i.imgur.com/vPHaiaW.png) А теперь зайжём в Discovery: ![](https://i.imgur.com/rbsNEkk.png) ### Заключение Nifi действительно удивительное приложение, было сложно привыкать к нему, но всё +- получилось. Ещё его прикольная функция с группой процессов пригодилась бы в самом начале, чтобы не запускать всё отдельно. Но о ней я прочитала уже когда всё сделала.