Строго не судите, это моя первая статья из цикла инфобеза, так сказать таблетки для памяти, ну и если кому-то пригодится, то заработанный плюс в карму.
Идея возникла спонтанно, во время обучения понял что получаю опыт, сталкиваясь с кучей ошибок которых можно было бы избежать будь я немного внимательней. Но так как жизнь идёт своим чередом, а сампо предполагает что ты будешь грызть гранит науки всё таки самостоятельно (пускай и с поддержкой наставника и нейронки).
ELK использует аббревиатуру от стека инструментов, это Elastic Search, Logstash и Kibana.
Каждый инструмент используется для определённых задач.
Elastic Search: представляет из себя базу данных для полнотекстового поиска использующую индексы Lucene, см Apache Lucene.
Logstash: используется как конвейер для пайплайна при сборе информации, а именно, сбор, обработка: фильтрация, анализ, обогащение и отправка.
Kibana: интерфейс визуализации, грубо говоря фронтэнд для работы.
Каждый из описанных выше заслуживает отдельной статьи, и не одной. Но мы сегодня поговорим о написании корреляционного правила.
Итак у нас установлен ELK (попозже вернёмся к этой теме, и установим её на своём сервере.)
Наверху слева (три полоски), располагается интерфейс для быстрого перехода в нужные вкладки. Но также можно переключится на нужную нам общую вкладку: В данный момент Security.
Перед нами открывается следующий вид.
С левой стороны находится опция Rules - правила.
На выбор есть несколько опций, но нас интересует Detection rules (SIEM)
На текущий момент уже создано пару правил, одно из них включено, другое выключено. (тестовый стенд)
Разберем на примере того как это было сделано с Wget+chisel
Wget утилита используемая в основном для скачивания, chisel утилита для пентеста способная обходить системы защиты. В данном случае пример приведён для простоты и упрощения.
Задача: при скачивании файла chisel утилитой wget должен быть алерт с названием правила: wget+chisel
Для того чтобы всё это работало нам нужна программа для сбора логов. Таковой является auditd он же Linux Audit Daemon - программа для сбора и записи событий.
Ставим auditd
apt-get install -y auditd audispd-plugins
Почему ставим auditd audispd-plugins?
Если плагин не установлен то:
1) все события идут в /var/log/audit/audit.log
2) События попадают туда в сыром виде, которые читать очень сложно, по умолчанию ставится плагин predefined fields plugin, который после обработки сырых логов приводит их в удобочитаемый для человека вид. Что-то вроде XML.
3) С плагином события дублируются в syslog даже если audit.log повреждён, по умолчанию ставится syslog plugin.
4) С плагином возможна отправка данных в logstash (инструмент в ELK - который собирает данные из разных источников, затем обрабатывает (фильтрация, анализ, обогащение) их и отправляет далее) плагин по умолчанию ставится af_unix plugin
5) С плагином идёт предобработка и последующая фильтрация событий
6) Список установленных плагинов можно посмотреть в /etc/audisp/plugins.d/
Для начала надо посмотреть какие правила у нас есть:
sudo auditctl -l
Где sudo повышение прав
Правила аудита задаются с помощью утилиты управления auditctl
-l вызов списка имеющихся правил, --list = То есть список.
При запуске auditd правила читаются из основного файла с правилами который загружается первым `/etc/audit/audit.rules` и дополнительные файлы с правилами которые загружаются вслед за основным, где разные правила могут быть в разных файлах, файлы загружаются в алфавитном порядке`/etc/audit/rules.d/*.rules`
Где каждая строка является аргументом то есть командой для auditctl
Структура audit
/etc/audit/ # Корневой каталог
├── audit.rules # Основной файл с системными правилами
└── rules.d/ # Дополнительный каталог
├── 10-base-config.rules # Базовые правила
├── 30-network-monitoring.rules # Сетевые правила
├── 40-file-integrity.rules # Правила мониторинга файлов
└── 99-finalize.rules # Конечные финальные правила
Я не хочу изменять правила в уже имеющемся основном каталоге, поэтому я создам новое правило:
sudo nano /etc/audit/rules.d/50-soc-monitoring.rules
в рамках которого и буду работать.
Добавляем правило:
-a always,exit -F path=/usr/bin/wget -F perm=x -F auid>=1000 -F auid!=4294967295 -k wget_monitoring
-a = действие
always = всегда добавляет в лог запись
exit = условие когда вызов завершён, то есть системное событие исполнилось.
-F path /usr/bin/wget = -F условие в котором путь равен /usr/bin/wget
-F perm=x = права доступа равно выполнение (x=execute)
-F auid>=1000 = auid это специальный ID пользователя который больше > или равно = 1000 то есть обычные пользователи.
-F auid!=4294967295 = != не равно неустановленному или системному, 4294967295 в беззнаковом формате 4294967295 равно -1.
-k wget_monitoring = key он же ТЭГ или имя правила по которому можно будет искать.
загружаем дополнительные правила
sudo augenrules --load
Перезагружаем службу
sudo systemctl restart auditd
Загружаем файл используя wget
Открываем ELK и ищем по тэгу наше правило: wget_monitoring для того чтобы это сделать надо перейти в Analytics - Diccover
В разделе Data view: необходимо убедиться что вы будете искать там где надо. В нашем случае index файла winlogbeat- (мы к этому ещё вернёмся в другой статье, так как там в связи с происходящими в мире событиями установка filebeat это целое приключение.)
Ищем созданное нами правило: wget_monitoring
Получаем вот это:
Вообще интерфейс настраивается вдоль и поперек, но останавливаться сейчас нет времени, позже вернёмся к этому в другой статье.
Правило сработало, но во первых, мы не знаем по какой ссылке заходил пользователь, во вторых нам надо как-то увязать это в правиле для железобетонной уверенности в том что ложных срабатываний не будет.
Для этого ищем лог типа SYSCALL - так как именно этот тип интерфейса служит связкой прикладного ПО с ядром системы.
Дальше будет куча текста но уже как есть, с форматированием в ДЗЕН беда:
event.originaltype=SYSCALL msg=audit(1764539992.995:4810): arch=c000003e syscall=59 success=yes exit=0 a0=55b6563c4670 a1=55b6563e43e0 a2=55b6563e3a10 a3=8 items=2 ppid=1594 pid=2253 auid=1000 uid=1000 gid=1003 euid=1000 suid=1000 fsuid=1000 egid=1003 sgid=1003 fsgid=1003 tty=pts0 ses=1 comm="wget" exe="/usr/bin/wget" subj=unconfined key="wget_monitoring"ARCH=x86_64 SYSCALL=execve AUID="admin" UID="admin" GID="admin" EUID="admin" SUID="admin" FSUID="admin" EGID="admin" SG
Увы это не даёт полной картины, о том куда ходил пользователь, и потребовалось время для ресерча. Нам нужно правило, в котором будет видно с какими аргументами пользователь запускал софт, таким оказался аргумент который как оказалось используется в Linux вообще везде.
SYSCALL в свою очередь связан с EXECVE при запуске ПО. Для того чтобы было общее понимание того как это происходит:
Пользователь передаёт команду на запуск программы: SYS с параметрами EXECVE - ядро считывает параметры атрибутов утилиты, собирает нужную информацию и только после этого, даёт команду на запуск. Поэтому логов типа EXECVE может быть несколько.
-S execve = гарантирует что в лог запишется не только факт запуска программы, но и его ключи. Добавляем его в правило.
-a always,exit -S execve -F path=/usr/bin/wget -F perm=x -F auid>=1000 -F auid!=4294967295 -k wget_monitoring
Получаем ещё один лог:
messagetype=EXECVE msg=audit(1764539992.995:4810): argc=2 a0="wget" a1="https://github.com/jpillora/chisel/releases/download/v1.7.0/chisel_1.7.0_linux_amd64.gz"@timestampDec 2, 2025 @ 13:32:15.086@version1agent.ephemeral_idf7df90bf-2d3d-42c3-95c6-b47f0b99cdf5agent.id7da9f55c-2c0f-4879-be7f-656fa1a395deagent.nameid467638-nginx-vmagent.typefilebeatagent.version8.19.7cloud.account.idproject-idcloud.availability_zoneru-central1-acloud.instance.nameid
Особо пытливые уже заметили одинаковые аргументы в параметрах msg=audit(1764539992.995:4810), данная метка создаётся когда есть несколько записей в рамках одного времени и\или события. Что кстати не отменяет того что время и даже дата может быть совсем другим. И на самом деле всё сложнее. Но в нашем случае этого достаточно.
Но теперь у нас есть уверенность в том что если кто-то запустит WGET с попыткой скачать CHISEL, сработает alert.
Теперь нам нужно настроить корреляцию в ELK.
Перед этим надо понимать какие поля распарсил Elastic search так как нам нужно знать какие поля увязывать друг с другом.
Открываем лог, для детализации, для этого воспользуемся стрелочками (в разные стороны) у окошка с датой, после нажатия иконки стрелочки будут сведены вместе и в этом случае справа от общих логов появится окно с нужными нам данными.
Ищем наше правило в SYSCALL, WGET_MONITORING, оно находится в графе event.original и message
Так же открываем лог с EXECVE и ищем CHISEL
тоже самое находится и в message.
Теперь мы знаем в каких полях искать ключевые метки.
Открываем Security - Rules - Detection rules (SIEM) - Create new rule - Costum query (хотя для реальных сложных кейсов понадобится Event correlation)
Разница между типом правил является, грубо говоря для простых правил используется KQL для сложных EQL.
Для примера:
KQL - найди мне фотографию красной машины с номером 1234.
EQL - найди мне фотографию красной машины с номером 1234, остановившуюся у банка у Золотой улице, дом 12, в 15:00, уехавшую оттуда в 15:30, покажи фотографии за этот промежуток времени у этого банка.
При создании правила указывает в каком индексе смотреть, указывается это в Index patterns, указывает маркеры событий, wget_monitoring и chisel.
Выглядит это так:
Указываем имя, описание, критичность события, тэг и сколько очков вы бы дали если бы это оценивали в этих самых очках - оценка риска.
Также одно из важных опций, расписание - Schedule, runs every - запускать с какой периодичностью, и additional look-back time - добавляет время за прошедший период чтобы не пропустить прошедшие события. Очень полезно если хотите понимать были ли у вас алерты в прошлом. После этого сохраняйте настройки.
Запомните этот параметр, так как если захотите что-то проверить у себя, и запустите правило с этим параметром в одну минуту, то алерта вы не получите.
В каждой организации есть свой регламент создания правил, строго его придерживайтесь.
Можно создать событие Event Correlation используемый синтаксис вместо KQL -> EQL, в принципе всё тоже самое, но например можно добавить: Мы видим два события: wget_monitorng + chisel + и это обязательно должно произойти на одной АРМ не больше чем в пять секунд.
Пример скрипта:
sequence by host.name with maxspan=5s [ any where event.original : "*wget_monitoring*" ] [ any where event.original : "*chisel*" ]
По созданию правил тоже отдельная тема, так как можно много чего прикрутить в этом колхозе. Я уже не говорю о платной версии которая ну очень крутая.
Надеюсь эта статья была для вас полезной.