Привет, Хабр!

Меня зовут Андрей Бирюков. Я — независимый эксперт в области ИТ и ИБ, преподаю в учебных центрах и пишу статьи и книги.

В SIEM обнаружение угроз зависит не от количества логов (иначе это уже не SIEM, а помойка хранилище для логов), а от того, могут ли правила точно определить: «какое событие представляет угрозу, насколько серьёзна угроза и что делать дальше».

Wazuh, как народный SIEM с открытым исходным кодом, использует правила в формате XML в качестве ядра механизма обнаружения атак. Многие статьи ограничиваются демонстрацией синтаксиса, но на практике написание, тестирование, переопределение и настройка реагирования для правил представляют собой замкнутый цикл, и любое звено в этом цикле может привести к неработоспособности правила.

В этой статье мы рассмотрим написание пользовательских правил, их последующее тестирование с помощью wazuh-logtest, затем поговорим о переопределении встроенных правил и в завершение затронем вопросы активного реагирования на обнаруженные инциденты.

Минимально жизнеспособное правило: структура и расположение

Для начала давайте немного поговорим об основах написания правил корреляции (не путаем с правилами нормализации (декодерами), которые тоже живут неподалёку).

Итак, все пользовательские правила должны быть размещены в /var/ossec/etc/rules/local_rules.xml, при этом категорически не следует напрямую изменять файлы в /var/ossec/ruleset/rules/, так как эти файлы будут перезаписаны при обновлении.

Пользовательские правила используют диапазон ID 100000–120000, чтобы избежать конфликтов со встроенными правилами.

В качестве примера давайте посмотрим на правило для обнаружения неудачных входов по SSH:

<group name="custom_demo,">
  <rule id="100200" level="10">
    <if_sid>5710</if_sid>
    <match>Failed password</match>
    <description>Пользовательское правило: обнаружен неудачный вход по SSH</description>
  </rule>
</group>

Здесь у нас присутствует поле level, в котором мы определяем шкалу приоритетов в диапазоне 0–15:

  • 0–3 — информационные;

  • 4–7 — низкий приоритет;

  • 8–11 — средний;

  • 12–15 — критические.

Поле if_sid определяет привязку к родительскому правилу. В приведённом примере 5710 — это встроенное правило Wazuh для «неудачного входа по SSH».

Условие срабатывания — match, в данном случае это фраза Failed password. Также match может быть опущено при использовании regex для точного извлечения.

Если правило не срабатывает, то наиболее вероятной причиной является проблема с декодером. То есть поле не было извлечено, и match не находит объект для сопоставления.

Поэтому перед написанием правила сначала используйте wazuh-logtest для просмотра вывода фазы декодирования (Phase 1/2), чтобы убедиться, что такие поля, как srcip, srcuser, правильно извлечены.

Цикл написания и проверки правил

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

1. Просмотр исходных логов

Прежде всего, необходимо просмотреть исходные логи. Для этого убедитесь, что в /var/ossec/logs/ossec.log видны необработанные события, иначе правило будет «слепым».

2. Подготовка правила

Далее подготовим правило в local_rules.xml с последующим сохранением без немедленного перезапуска менеджера.

Запуск без проверки, скорее всего, приведёт к сбою всего SIEM, так что сначала проверим с помощью wazuh-logtest.

3. Проверка с помощью wazuh‑logtest

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

Обратите внимание: если вы изменили только декодер или правило, wazuh-logtest проверит его сразу, но для того, чтобы правило действительно генерировало оповещения в работающем менеджере, необходим перезапуск.

4. Перезапуск менеджера

После успешного прохождения теста перезапускаем wazuh-manager:

systemctl restart wazuh-manager

5. Контроль работы правила

В дальнейшем для того, чтобы убедиться в корректности работы правила, мы можем наблюдать за сообщениями в файле логов ossec.log.

Переопределение встроенных правил

Иногда необходимо внести некоторые изменения во встроенные правила, например повысить уровень критичности с 5 до 10, но прямое изменение файла в ruleset/ будет перезаписано при обновлении.

И здесь правильный подход — это скопировать исходное правило в local_rules.xml и добавить overwrite="yes".

В качестве примера давайте переопределим правила 5710 (несуществующий пользователь SSH) с повышением уровня до 10:

<rule id="5710" level="10" overwrite="yes">
  <if_sid>5700</if_sid>
  <match>illegal user|invalid user</match>
  <description>sshd: попытка входа с использованием несуществующего пользователя (уровень повышен)</description>
</rule>

Но у встроенных правил есть некоторые ограничения, о которых не стоит забывать.

Так, при использовании overwrite теги if_sid, if_group, if_level, if_matched_sid, if_matched_group будут игнорироваться, то есть сохранятся исходные значения.

Это означает, что вы можете изменить level, description, groups и другие поля, но не можете изменить логику привязки правила через overwrite.

Если необходимо изменить логику привязки, следует создать новое правило, а не переопределять уже имеющееся.

От обнаружения к блокировке

За долгие годы работы в интеграции мне неоднократно приходилось быть свидетелем ситуаций, когда какое‑либо защитное решение создавало проблемы после запуска режима автоматического реагирования. Это относится и к IPS, EDR, антивирусам и другим решениям ИБ.

Поэтому прежде, чем реализовывать автоматическое реагирование на инциденты, проведите множество тестов и убедитесь в корректности его работы.

Wazuh Active Response позволяет автоматически выполнять скрипты при срабатывании правила, и ниже мы рассмотрим типичный сценарий блокировки SSH‑брутфорса.

Здесь в качестве предварительного условия у нас будет использование встроенного правила 5763 в Wazuh, которое обнаруживает «SSH‑брутфорс».

В системе также по умолчанию присутствует скрипт firewall-drop (с использованием iptables для блокировки IP).

В файл ossec.conf добавьте блок active-response:

<active-response>
  <disabled>no</disabled>
  <command>firewall-drop</command>
  <location>local</location>
  <rules_id>5763</rules_id>
  <timeout>180</timeout>
</active-response>

Здесь location local означает выполнение на агенте, где произошло событие; timeout 180 — это блокировка на 180 секунд с последующим автоматическим снятием.

После перезапуска менеджера используйте инструмент типа Hydra для имитации брутфорса, и после срабатывания правила 5763 IP атакующего будет заблокирован, а запись о блокировке можно будет увидеть в /var/ossec/logs/active-responses.log.

Важно помнить: Active Response с firewall-drop может при ложных срабатываниях заблокировать легитимных пользователей, общий NAT, системы мониторинга или IP‑адреса шлюза VPN.

Наиболее безопасный подход — привязывать его только к правилам с высокой достоверностью и чёткой атрибуцией источника (например, повторяющиеся неудачные аутентификации с того же исходного IP) и использовать временную блокировку, а не постоянную.

Перед включением обязательно проверьте в тестовой среде заполнение поля srcip и фактический эффект блокировки/разблокировки iptables.

Что может пойти не так

В завершение давайте рассмотрим несколько типовых ошибок при работе с правилами и настройке Active Response.

Прежде всего, у нас может не сработать правило, например из‑за того, что декодер не извлёк целевое поле. Для решения проверьте вывод с помощью wazuh-logtest и затем исправьте правила декодера.

Другие возможные проблемы:

  • Дублирующийся ID. Если после перезапуска появилось сообщение о дублирующемся ID, то, скорее всего, вам нужно добавить overwrite="yes" или изменить ID на пользовательский диапазон.

  • Блокировка неправильного IP. В случае если Active Response заблокировал не тот IP, возможно, правило сработало ложно или srcip указан неверно. Для решения сузьте условия правила, проверьте заполнение поля источника, но сначала протестируйте блокировку вручную.

Весь процесс работы с правилами Wazuh можно обобщить одной фразой:

Сначала правильный декодер, затем правильное правило, после — проверка и только потом реагирование.

Пропуск любого этапа приводит к тому, что правило существует лишь формально, но ничего реально не обнаруживает.

Подведем итог

Народный SIEM Wazuh является достаточно мощным инструментом, который позволяет не только собирать и обрабатывать большие объёмы событий, но и проактивно реагировать на обнаруженные подозрительные активности.

Например, мы можем в автоматическом режиме заблокировать атакующего из интернета, пытающегося подобрать пароль к нашему внешнему узлу доступа по SSH. Однако здесь важно понимать, что неосторожное использование Active Response может привести к ложным блокировкам легальных ресурсов.

В целом важно помнить, что грамотное использование функционала Wazuh позволяет специалистам ИБ существенно повысить оперативность обнаружения и реагирования на подозрительные активности и при этом снизить затраты на их выявление.

Чтобы профессионально внедрять SIEM, важно уметь настраивать правила, связывать события и оценивать качество детектирования. Освоить эти навыки комплексно поможет курс «Специалист по внедрению SIEM».

А разобраться в тонкостях корреляции событий можно на бесплатном открытом вебинаре:

  • 18 ноября в 20:00. «Что SIEM не увидит "из коробки": корреляция событий и оценка качества детектора». Записаться

Другие открытые уроки ноября в дайджесте мероприятий.