SIEM на практике: дружим Prelude + Cisco IPS и выявляем эксплуатацию HeartBleed через корреляцию

    Доброго времени суток всем!
    Сама по себе тема SIEM является в последнее время популярной. В виду комплексной сложности этих систем, вопросы, связанные с их использованием, глубокие и объемные. Существует довольно много статей (на Хабре и не только), посвященных SIEM. Однако в подавляющем большинстве они затрагивают тему с точки зрения теории, методологии и общих принципов построения процессов. А вот статей, описывающих практические аспекты применения/настройки этих систем, совсем нет катастрофически мало. Эта статья описывает как на практике подружить IPS и SIEM на примере Cisco IPS и Prelude, а также приведен пример правила корреляции, позволяющего выявить успешную эксплуатацию наболевшей в последние дни уязвимости HeartBleed.




    1. Введение / постановка задачи


    Итак, мы внедрили IPS в Inline, что дальше?
    Очевидно, что следующим шагом необходимо как-то следить за тем что IPS отлавливает, в каком количестве, кого и откуда атакуют и т.д.
    Если быть более конкретным:
    1. Нужно поддерживать актуальный для защищаемых хостов набор активных сигнатур.
    2. Для эффективной работы IPS-сенсоров необходимо постоянно «держать руку на пульсе»: нужно постоянно адаптировать сенсор под конкретные сеть и трафик. Достигается это путём настройки правил с исключениями.
    3. Среди множества алертов, полученных от IPS, необходимо выделять действительно важные и критичные.
    4. Для критичных алертов также необходимо обеспечить корректный набор агрессивных действий (блокировка трафика, сброс сессий, бан IP и т.д.), предпринимаемых сенсором, а также оповещения администратора о них.
    5. Состояние самого сенсора также необходимо отслеживать (загруженность сканирующего движка, ошибки обновления, сроки действия лицензий и т.д.).

    Для решения таких задач нужно подобрать удобный и одновременно функциональный инструмент.

    2. «Штатные» средства просмотра событий IPS


    Существует множество способов собирать и обрабатывать события от IPS.
    Из штатных средств просмотра событий от сенсоров Cisco есть такие варианты:

    2.1 Просмотр событий локально на сенсоре


    Это средство, принцип действия которого можно охарактеризовать как «в лоб». На каждом сенсоре существует своё локальное хранилище событий. Само собой, увидеть в нем можно только то, что было обнаружено непосредственно на конкретном сенсоре.



    Какой-либо группировки/агрегации событий по каким-либо признакам не предусмотрено. Максимум, что можно себе позволить – отфильтровать отображаемые события по ряду критериев (критичность сигнатуры, время выборки, показывать/не показывать системные события сенсора). Сам листинг событий при этом выглядит следующим образом:



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

    2.2 Cisco IPS Manager Express


    Следующей «родной» альтернативой предыдущему средству является IME. Это бесплатное решение от Cisco, позволяющее осуществлять конфигурацию и мониторинг событий для максимум 10-ти IPS-сенсоров. В плане конфигурации стоит заметить, что тут речь идёт об общей консоли для устройств, т.е. нет возможности создавать политики конфигурации (за исключением трёх параметров, относящихся к функциям Global Correlation, Reputation Filtering и Network Participation).
    Что касается сбора событий – здесь уже ситуация сильно лучше: алерты от различных сенсоров собираются в общую базу данных.



    Поддерживаются сбор событий как от IPS-апплаинсов/модулей, так и от IOS-IPS роутеров. Есть возможность группировки и фильтрации событий по различным признакам. В каждое событие можно «провалиться» для просмотра более подробной информации:



    Ещё одной полезной функцией IME является возможность оповещать через email о полученных от IPS событиях. Критериев выбора об оповещениях всего два: Attack Severity Rating и RiskRating.



    Хоть IME и является довольно функциональным инструментом, но не лишён ряда ограничений. Один из существенных недостатков это то, что IME не клиент-серверная система, а по сути своей – обычное приложение, использующее базу данных MySQL. В предыдущих версиях IME даже не поддерживался на серверных и x64-битных ОС. Также ограничениями являются максимальное количество поддерживаемых устройств (не более 10-ти) и количество обрабатываемых событий в секунду (100 EPS).

    2.3 Cisco Security Manager


    CSM позиционируется уже как полноценное Enterprise решение, предназначенное для централизованного управления различными устройствами (IPS, ASA/PIX, IOS-роутеры и т.д.). Количество устройств, которыми можно управлять, зависит от приобретенной лицензии. Само управление уже осуществляется на основе политик: можно сделать эталонный набор настроек, который впоследствии можно тиражировать.
    С точки зрения сбора, хранения и отображения событий, CSM очень похож на IME:



    Здесь, как и в IME, имеется возможность группировки/агрегации и фильтрации отображаемых событий по различным критериям. Помимо событий от IPS, в CSM есть возможность также отслеживать события от файрволлов ASA/FWSM/PIX.
    В каждый алерт также можно «провалиться» для просмотра более подробной информации:



    Хотя CSM позиционируется как Enterprise решение, в отличии от того же IME, он не умеет собирать алерты с IOS-IPS (но при этом умеет их настраивать через политики). Также CSM не умеет осуществлять оповещения по e-mail о событиях, отловленных IPS.

    CS-MARS
    Ещё есть была такая система CS-MARS, но проект этот уже довольно давно закрыт, поэтому упоминается он только в качестве исторической справки.


    3. SIEM


    Описанные выше решения хороши каждое по-своему. Но, с точки зрения сбора событий, они являются довольно узконаправленными: кроме событий от IPS (и от файрволлов, в случае с CSM) увидеть в них мы больше ничего и не сможем.

    Довольно часто в моей практике у коллег из соседних отделов возникают вопросы:
    • У нас тут <по каналам загрузка возросла | сервис перестал отзываться | система отъехала | что-то случилось>, не знаете с чем связано?
    • А у вас (у ИБ) там ничего подозрительного не было замечено?
    • etc

    Именно в таких случаях появляется необходимость проверить события с роутеров, свитчей, логи с unix/windows, журналы специфичных систем, антивирусы, почтовые шлюзы и т.д. На самом деле этот список можно продолжать бесконечно.
    А ещё всё это между собой сопоставить по каким-либо критериям (произвести корреляцию), получить на ходу дополнительную информацию о хостах, участвующих в событии: что за ресурс, уязвим или нет, какие порты открыты и т.д.
    Вот здесь и приходят на помощь SIEM системы. Всё вышеперечисленное они делать умеют, а при должном усердии – ещё и автоматизировано.

    Одной из таких систем является малоизвестный в Рунете зверь, по имени Prelude. О нём и пойдёт речь.
    Почему именно о нём?
    1. Он мне нравится.
    2. Он работает (и уже довольно давно).
    3. У него есть OSS версия.
    4. Имеет нативную совместимость с другими OSS-системами.
    5. При желании можно подключить любой источник, который пишет лог.
    6. Из него можно собрать свой собственный «швейцарский нож» под свои задачи выявления, расследования и реакции на инциденты.
    7. Модуль корреляции реализован в виде подключаемых скриптов на Python, что означает гибкость в самом полном смысле этого слова. Полноценный язык программирования дает возможности для написания любых правил корреляции.
    8. Есть удобный интерфейс Prewikka.

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

    3.1 Архитектура Prelude


    В упрощенном варианте архитектуру системы можно представить следующим образом:



    Manager – является ядром системы. Отвечает за прием уже нормализованных (распаренных) событий от LML-агентов, модуля корреляции, сторонних систем или подчиненных менеджеров (доступно в коммерческой версии). Полученные сообщения записывает в базу данных. Также отвечает за оповещения через email.

    LML – агент системы и основной поставщик событий. Осуществляет прием логов от различных систем (через локальный файл или через syslog на UDP-порт). Полученные логи разбирает/нормализует на основе набора правил, состоящих из регулярных выражений. Нормализованные события отдаёт Manager-у. LML может работать как локально (на одном сервере с Manager-ом), так и удаленно.

    Correlator – модуль корреляции. Подключается к Manager-у как агент. Производит корреляцию поступивших в Manager событий на основе плагинов, реализованных в виде Python-скриптов.

    DataBase – собственно база данных, где хранятся все события, обработанные системой.

    3rd Party Systems – сторонние системы с поддержкой IDMEF, позволяющие подключать их напрямую к Manager-у.

    Prewikka – основной интерфейс системы, реализованный на Web. Предназначен для отображения обработанных событий, их агрегации/фильтрации, вывода статистики и т.д.

    Выглядит это всё вот так:



    События отображаются в таблице, в столбцах которой расположена информация о/об:
    • классификации алертов (Classification), содержащие поля с названием события, признаком его (не)успешного завершения, id-события (номер сигнатуры, номер уязвимости по CVE и т.п.), критичности события и т.д.
    • источнике/цели (Source/Target), содержащие поля с ip-адресом, mac-адресом (если он присутствовал в событии), исходном имени пользователя, процессе, файле и т.д.
    • анализаторе (Analyzer – источнике события), содержащие поля с ip-адресом, классе анализатора и т.д.

    Количество отображаемых IDMEF-полей зависит от типа события и правила его обработки. Некоторые поля могут быть индексируемые, т.е. содержать несколько значений. Например, может быть два поля userid.name, в одном из которых будет записано значение samaccountname, а во втором – SID этой же учетной записи. А, например, в случае события от системы проверки целостности файлов в информации об источнике и цели не будет отображено ни адреса, ни порта, ни протокола – эти поля будут заняты информацией об измененном файле, контрольных суммах и другой дополнительной информации.
    В любое событие можно «провалиться» для просмотра более подробной информации:



    4. Как забирать события с сенсоров?


    Перед подключением IPS к нашей системе в качестве источника, нужно понять, как из IPS можно достать, хранящиеся в нем алерты.
    Существует два метода передачи событий от сенсоров Cisco (и один полу-метод для IOS-IPS) во внешние системы:

    1) Через SNMP Trap, который отправляет сам сенсор по факту срабатывания сигнатуры или системного события.
    Отправляемые сенсором трапы имеют следующий вид:

    #012iso.3.6.1.2.1.1.3.0 15:1:47:08.58#011iso.3.6.1.6.3.1.1.4.1.0 iso.3.6.1.4.1.9.9.383.0.1#011iso.3.6.1.4.1.9.9.383.1.1.1.0 6822393729640#011iso.3.6.1.4.1.9.9.383.1.1.2.0 "07 DE 04 0A 0B 2C 0E 00 "#011iso.3.6.1.4.1.9.9.383.1.1.3.0 "07 DE 04 0A 07 2C 0E 00 "#011iso.3.6.1.4.1.9.9.383.1.1.4.0 "IPS-SENSOR-01"#011iso.3.6.1.4.1.9.9.383.1.2.2.0 2147516416#011iso.3.6.1.4.1.9.9.383.1.2.3.0 "Heartbleed"#011iso.3.6.1.4.1.9.9.383.1.2.4.0 "OpenSSL Information Disclosure"#011iso.3.6.1.4.1.9.9.383.1.2.5.0 4187#011iso.3.6.1.4.1.9.9.383.1.2.6.0 0#011iso.3.6.1.4.1.9.9.383.1.2.7.0 "S785"#011iso.3.6.1.4.1.9.9.383.1.2.13.0 0#011iso.3.6.1.4.1.9.9.383.1.2.14.0 "iBCRX+m57XRkOtzSnz0MSIw/CJWscqWUKqhEjadJYMWue6yLZAgTFpc8+LuL#012H/4o5rulPzbm1D9tQZ2tnoY/qfwSZ3H1VE2Wt2/rwUHcjVaKjGue9I0FdGZN#012JgpdbIcOOiBxB0T0JJ0qsqAzTMO37pf6GNOcByoHVgcgubBM2x148331MWSP#012O4hROt/p8Zpk8ZmNBIfUwy4yA0ByxPANY4e+ixHoPOe0aJGk1GUthnyAhKn8#012ztzv/kfCXHyPH5X7DBXTTXYZN+Xv6vnWYJV3tojoaOIpv6shRYLjeg84qeO5#012vY3P0uXwcYSCj1YY4rdgQpQvL8PkOxYDAgAEDgAAAA=="#011iso.3.6.1.4.1.9.9.383.1.2.15.0 "FgMCANwBAADYAwJTQ1uQnZtyC7wMvCuSqEiXz705BMwWCoUDkJ93BDPU3gAA#012ZsAUwArAIsAhADkAOACIAIfAD8AFADUAhMASwAjAHMAbABYAE8ANwAMACsAT#012wAnAH8AeADMAMgCaAJkARQBEwA7ABAAvAJYAQcARwAfADMACAAUABAAVABIA#012CQAUABEACAAGAAMA/wEAAEkACwAEAwABAgAKADQAMgAOAA0AGQALAAwAGAAJ#012AAoAFgAXAAgABgAHABQAFQAEAAUAEgATAAEAAgADAA8AEAARACMAAAAPAAEB#012GAMCAAMBQAAYAwIAAwFAAA=="#011iso.3.6.1.4.1.9.9.383.1.2.16.0 "192.168.1.1:51716"#011iso.3.6.1.4.1.9.9.383.1.2.17.0 "osIdSource=\"unknown\" osRelevance=\"relevant\" osType=\"unknown\" 10.10.10.1:443"#011iso.3.6.1.4.1.9.9.383.1.2.21.0 "InterfaceAttributes:  context=\"single_vf\" physical=\"Unknown\" backplane=\"PortChannel0/0\" ; "#011iso.3.6.1.4.1.9.9.383.1.2.25.0 70#011iso.3.6.1.4.1.9.9.383.1.2.26.0 5#011iso.3.6.1.4.1.9.9.383.1.2.27.0 6#011iso.3.6.1.4.1.9.9.383.1.2.42.0 70#011iso.3.6.1.4.1.9.9.383.1.2.49.0 "vs0"#011iso.3.6.1.4.1.9.9.383.1.3.1.0 "high"
    

    2) Через стандарт SDEE. В этом случае IPS-сенсор работает как Web-сервер, а внешние системы самостоятельно к нему подключаются и забирают новые алерты. Именно этот метод используется в продуктах CSM и IME. В Cisco в стандарте SDEE используются расширение CIDEE, описывающее дополнительные поля.
    Посмотреть SDEE-алерты в «чистом виде» можно через браузер, забив в адресной строке https://<sensor-ip-address>/cgi-bin/sdee-server (нужно будет пройти аутентификацию).
    Сами алерты выглядят так:

    <sd:evIdsAlert eventId="6821065810849" vendor="Cisco" severity="informational" cid:alarmTraits="2147483648">
     <sd:originator>
      <sd:hostId>IPS-SENSOR-01</sd:hostId>
      <cid:appName>sensorApp</cid:appName>
      <cid:appInstanceId>27106</cid:appInstanceId>
     </sd:originator>
     <sd:time offset="240" timeZone="GMT+04:00">1392668796044445000</sd:time>
     <sd:signature  description="TCP Drop - Segment out state order" id="1330" cid:version="S642" cid:type="anomaly" cid:created="20050304">
      <cid:subsigId>17</cid:subsigId>
      <cid:sigDetails>TCP segment is out of state order</cid:sigDetails>
     </sd:signature>
     <sd:interfaceGroup>vsx</sd:interfaceGroup>
     <sd:vlan>302</sd:vlan>
     <sd:participants>
      <sd:attacker>
       <sd:addr cid:locality="Inside">192.168.0.1</sd:addr>
       <sd:port>443</sd:port>
      </sd:attacker>
      <sd:target>
       <sd:addr cid:locality="AS_Inside">10.10.10.1</sd:addr>
       <sd:port>24479</sd:port>
       <cid:os idSource="learned" type="windows-nt-2k-xp" relevance="relevant" />
      </sd:target>
     </sd:participants>
     <sd:actions>
      <cid:snmpTrapRequested>true</cid:snmpTrapRequested>
     </sd:actions>
     <cid:riskRatingValue targetValueRating="medium" attackRelevanceRating="relevant">25</cid:riskRatingValue>
     <cid:threatRatingValue>25</cid:threatRatingValue>
     <cid:interface>ge0_3</cid:interface>
     <cid:protocol>tcp</cid:protocol>
    </sd:evIdsAlert>
    

    Немного забегая вперед, сразу стоит отметить, что использование SDEE имеет свои плюсы и минусы. Данные, получаемые через SDEE, содержат больше информации об алерте по сравнению с SNMP-трапом. Например здесь присутствует информация о предпринятых сенсором активных действиях. Но для экспорта данных через SDEE в SIEM, требуется специальный коннектор (в Prelude он есть только в коммерческой версии).

    3) Через syslog (только для IOS-IPS). Для полноты картины также стоит отметить и некоторые особенности IOS-IPS. Они так же поддерживают SDEE, но не умеют отправлять алерты через SNMP. В отличие от своих «старших» братьев, IOS-IPS умеет писать информацию об алертах в локальное syslog-хранилище роутера. Syslog роутера в свою очередь может быть передано на внешний сервер. Однако данные, которые пишутся в syslog, крайне скудны:

    Для IOS 12.x:
    Aug 20 14:21:35 MSK: %IPS-4-SIGNATURE: Sig:15002 Subsig:1 Sev:50  [192.168.1.1:1066 -> 10.10.10.1:5938] RiskRating:30
    

    Отсутствует даже название сигнатуры. Только её SingatureID и SubsibgnatureID.

    Для IOS 15.x:
    Mar  3 11:15:24 MSK: %IPS-4-SIGNATURE: Sig:11020 Subsig:0 Sev:25 BitTorrent Client Activity [192.168.1.1:62809 -> 10.10.10.1:6881] VRF:NONE RiskRating:25
    

    А вот через SDEE те же самые алерты будут представлены уже в «нормальном» виде, т.е. с подробной информацией:
    <sd:evIdsAlert eventId="139779925140" vendor="Cisco" severity="informational">
     <sd:originator>
      <sd:hostId>IOS-IPS-ROUTER</sd:hostId> 
     </sd:originator>
     <sd:time offset="0" timeZone="UTC">1397799251079951920</sd:time> 
     <sd:signature description="Jabber Activity" id="11204" version="S588">
      <cid:subsigId>0</cid:subsigId> 
      <cid:sigDetails>jabber:</cid:sigDetails> 
     </sd:signature>
     <cid:protocol>tcp</cid:protocol> 
     <cid:riskRatingValue>25</cid:riskRatingValue> 
     <sd:participants>
      <sd:attacker>
       <sd:addr>192.168.1.1</sd:addr> 
       <sd:port>61208</sd:port> 
      </sd:attacker>
      <sd:target>
       <sd:addr>10.10.10.1</sd:addr> 
       <sd:port>5222</sd:port> 
      </sd:target>
      <sd:vrf_name>NONE</sd:vrf_name> 
     </sd:participants>
     <sd:actions /> 
     <cid:interface>Fa0/1</cid:interface> 
     <cid:vrf_name>NONE</cid:vrf_name> 
    </sd:evIdsAlert>
    


    5. Настройка


    Для реализации задуманного на OSS версии подойдёт только вариант с SNMP-трапами.
    Схема подключения при этом будет выглядеть так:



    1. IPS ловит атаку и отсылает по этому поводу SNMP-Trap. (IOS-IPS сразу шлет лог на rsyslogd).
    2. Принимаем SNMP-Trap и передаем в syslog.
    3. rsyslogd пишет полученный трап в файл.
    4. LML разбирает лог, нормализует его, вытаскивает значения из интересующих нас полей и записывает их в соответствующие поля IDMEF (маппинг).
    5. Нормализованное событие передается в Manager, которое он записывает в базу данных. После этого событие становится доступным для просмотра через Prewikka.
    6. Поступающие события от IPS также можно отправлять на модуль корреляции (этот этап будет рассмотрен отдельно).


    5.1 Подготовка


    Предварительно необходимо установить и настроить сам Prelude. Как это делать, уже было описано здесь.
    Помимо Prewikka и prelude-manager нам потребуются prelude-lml и prelude-correlator.
    Также дополнительную информацию можно найти на официальном сайте Prelude.

    Чтобы обрабатывать snmp-трапы потребуется настроить демоны snmptrapd и rsyslogd (либо аналогичные).
    Основная задача – принимать snmp-трапы и писать их в файл.
    Сделать это можно, например так:

    snmptrapd.conf
    donotlogtraps  no
    printeventnumbers  yes
    ignoreauthfailure  yes
    authCommunity log,execute public
    traphandle default /usr/sbin/snmptthandler
    

    rsyslog.conf
    if $programname == 'snmptrapd' \
    then /var/log/snmptrapd
    & ~
    

    5.2 Настройка на стороне сенсора


    Следующим шагом необходимо заставить наш сенсор отправлять snmp-trap-ы каждый раз, когда происходит срабатывание сигнатур, а также в случае ошибок на самом сенсоре. Для этого нужно глобально включить SNMP-Trap-ы и указать целевой сервер и community, куда их отправлять:



    Помимо этого необходимо для всех диапазонов RiskRating-а (мы ведь не хотим ничего упускать из виду) назначить действие “Request SNMP Trap” через Event Action Override:



    После указанных настроек при срабатывании IPS в нашем логе /var/log/snmptrapd должны начать появляться события:

    Apr 18 16:01:59 prelude-server snmptrapd[11106]: 2014-04-18 16:01:59 10.0.0.1 [UDP: [10.0.0.1]:60457->[192.168.0.1]]:#012iso.3.6.1.2.1.1.3.0 24:12:04:52.86#011iso.3.6.1.6.3.1.1.4.1.0 iso.3.6.1.4.1.9.9.383.0.1#011iso.3.6.1.4.1.9.9.383.1.1.1.0 6822393753725#011iso.3.6.1.4.1.9.9.383.1.1.2.0 "07 DE 04 13 16 01 3B 00 "#011iso.3.6.1.4.1.9.9.383.1.1.3.0 "07 DE 04 13 12 01 3B 00 "#011iso.3.6.1.4.1.9.9.383.1.1.4.0 "IPS-SENSOR-01"#011iso.3.6.1.4.1.9.9.383.1.2.2.0 2147516416#011iso.3.6.1.4.1.9.9.383.1.2.3.0 "[ \\x26=?.]/etc/passwd[ \\x26=?]"#011iso.3.6.1.4.1.9.9.383.1.2.4.0 "Unix Password File Access Attempt"#011iso.3.6.1.4.1.9.9.383.1.2.5.0 3201#011iso.3.6.1.4.1.9.9.383.1.2.6.0 1#011iso.3.6.1.4.1.9.9.383.1.2.7.0 "S238"#011iso.3.6.1.4.1.9.9.383.1.2.13.0 0#011iso.3.6.1.4.1.9.9.383.1.2.15.0 "R0VUIC9uZXdzL2luZGV4LnBocD9FTEVNRU5UX0lEPS4uLy4uLy4uLy4uLy4u#012Ly4uLy4uLy4uLy4uL2V0Yy9wYXNzd2QgSFRUUC8xLjENCkhvc3Q6IA=="#011iso.3.6.1.4.1.9.9.383.1.2.16.0 "192.168.1.1:22238"#011iso.3.6.1.4.1.9.9.383.1.2.17.0 "osIdSource=\"unknown\" osRelevance=\"relevant\" osType=\"unknown\" 10.10.10.1:80"#011iso.3.6.1.4.1.9.9.383.1.2.21.0 "InterfaceAttributes:  context=\"single_vf\" physical=\"Unknown\" backplane=\"PortChannel0/0\" ; "#011iso.3.6.1.4.1.9.9.383.1.2.25.0 65#011iso.3.6.1.4.1.9.9.383.1.2.26.0 5#011iso.3.6.1.4.1.9.9.383.1.2.27.0 6#011iso.3.6.1.4.1.9.9.383.1.2.42.0 65#011iso.3.6.1.4.1.9.9.383.1.2.49.0 "vs0"#011iso.3.6.1.4.1.9.9.383.1.3.1.0 "medium"
    

    Здесь 10.0.0.1 – адрес сенсора IPS-SENSOR-01, 192.168.0.1 – адрес сервера prelude-server, где собственно установлены Prelude и snmptrapd.

    5.3 Настройка LML


    Теперь нужно настроить ту часть, где и происходит вся «магия» превращения полученного от сенсора SNMP-Trap-а в событие, которое будет удобно представить в графическом интерфейсе. Отвечает за это модуль prelude-lml. Он должен быть установлен на том же сервере, куда приходят SNMP-Trap-ы и зарегистрирован как агент в prelude-manager-е.
    Настройка его производится в несколько этапов.

    1) Определяем формат (и если необходимо – кодировку) исходного лога. Делается это в файле prelude-lml.conf:
    [format=Cisco-IPS]
    time-format = "%b %d %H:%M:%S"
    prefix-regex = "^(?P<timestamp>.{15}) (?P<hostname>\S+) (?:(?P<process>\S+?)(?:\[(?P<pid>[0-9]+)\])?: )?"
    file = /var/log/snmptrapd
    

    Этой настройкой мы заранее указываем, как выглядит формат времени у поступающих в лог событий, имя и адрес анализатора (в данном случае это адрес самого сервера), имя и номер процесса, принявшего лог.
    Позже, при непосредственном разборе события, все эти значения можно будет переопределить. Если же событие не может быть разобрано набором правил – значения определенные на данном этапе останутся.

    2) Указываем, к каким из поступающих событий какой набор правил разбора лога применить. Делается это в файле pcre.rules и выглядит для нашего примера вот так:
    regex=snmptrapd;                        include = cisco-ips.rules;
    

    3) Необходимо создать указанный набор правил: cisco-ips.rules. На самом деле данный пункт заслуживает того, чтобы посвятить ему отдельную статью. Чтобы не увеличивать объем статьи ещё в два раза, просто перечислю основные моменты:
    • набор правил состоит из последовательности регулярных выражений;
    • мы можем влиять на порядок их обработки, а также создавать «под-правила» различной вложенности;
    • в каждом правиле мы можем «вытаскивать» из лога нужное значение в виде переменной и заносить в соответствующее IDMEF-поле. Именно этот процесс называется mapping;
    • «под-правила» могут вызываться опционально, что позволяет менять значения в событиях зависимости от их состава.

    Пример: по умолчанию присваиваем всем событиям значение уровня “severity” равный “informational”. Далее, если в алерте, отправляемом сенсором, присутствует иное значение Attack Severity Rating – переписываем наш атрибут. Это позволяет привязаться в общем-то к любому параметру и записывать события в базу данных так, как нам будет угодно. Какой уровень критичности должен SIEM присваивать поступающим событиям (с учётом корректирующих действий или без них) — это уже больше методологический вопрос. С помощью правил можно реализовать любой удобный/понравившийся вариант.
    Опытным путем был разработан вот такой набор правил:
    cisco-ips.rules
    #####
    # Copyright (C) 2013 Vladimir Lapshin <vmlapshin at gmail dot com>
    # Copyright (C) 2013 lei_wulong
    #
    # This file is part of the Prelude-LML program.
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2, or (at your option)
    # any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; see the file COPYING.  If not, write to
    # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    #
    #####
    
    
    
    #<<ALERT<<
    #SIG POOL: 5000-5039
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.4(?:\.0)? "(.+)".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.5(?:\.0)?; \
     id=5000; \
     classification.text=$1; \
     assessment.impact.description=This event was generated by the Cisco IPS; \
     classification.reference(0).origin=vendor-specific; \
     classification.reference(0).meaning=ips_id; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.[23]\.1(?:\.0)? "(info|low|medium|high)(rmational)?"; \
     id=5001; \
     assessment.impact.severity=$1; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.(?:17(?:\.0)? "osIdSource=\\+?"(\S+?)\\+?" osRelevance=\\+?"(\S+?)\\+?" osType=\\+?"(\S+?)\\+?)?" (?:0\.0\.0\.0 \[)?([\w:]+?|\d+?\.\d+?\.\d+?\.\d+?)(?:\])?(?::([\d\,]+?))?"; \
     id=5002; \
     target(0).node.address(0).category=ipv4-addr; \
     target(0).node.address(0).address=$4; \
     target(0).service.port=$5; \
     target(0).service.portlist=$5; \
     additional_data(0).type=string; \
     additional_data(0).meaning=osIdSource:; \
     additional_data(0).data=$1; \
     additional_data(1).type=string; \
     additional_data(1).meaning=osRelevance:; \
     additional_data(1).data=$2; \
     additional_data(2).type=string; \
     additional_data(2).meaning=osType:; \
     additional_data(2).data=$3; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.5(?:\.0)? (\d+).011iso.3.6.1.4.1.9.9.383.1.2.6(?:\.0)? (\d+); \
     id=5003; \
     classification.reference(0).origin=vendor-specific; \
     classification.reference(0).meaning=ips_id; \
     classification.reference(0).name=$1.$2; \
     classification.reference(0).url=http://tools.cisco.com/security/center/viewIpsSignature.x?signatureId=$1&signatureSubId=$2; \
     additional_data(>>).type=string; \
     additional_data(-1).meaning=Cisco Signature Template:; \
     additional_data(-1).data=http://tools.cisco.com/security/center/viewIpsSignature.x?signatureId=$1&signatureSubId=$2; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.13(?:\.0)? (\d+); \
     id=5004; \
     target(0).node.address(0).vlan_name=$1; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.16(?:\.0)? "(?:0\.0\.0\.0 \[)?([\w:]+?|\d+?\.\d+?\.\d+?\.\d+?)(?:\])?(?::(\d+?))?"; \
     id=5005; \
     source(0).node.address(0).category=ipv4-addr; \
     source(0).node.address(0).address=$1; \
     source(0).service.port=$2; chained; silent;
    
    #ANOMALY DETECTION
    regex=011iso.3.6.1.4.1.9.9.383.1.2.16(?:\.0)? "[\d\.\:]+"\#011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.21(?:\.0)? ".\s+adExtraData: numDestIps=\d+\S currentThreshold=\d+\S protocol=\d+; \
     id=5006; \
     target(0).node.address(0).category=ipv4-addr; \
     target(0).node.address(0).address=0.0.0.0; \
     target(0).service.port=0; \
     target(0).service.portlist=0; \
     additional_data(0).type=string; \
     additional_data(0).meaning=osIdSource:; \
     additional_data(0).data=unknown; \
     additional_data(1).type=string; \
     additional_data(1).meaning=osRelevance:; \
     additional_data(1).data=unknown; \
     additional_data(2).type=string; \
     additional_data(2).meaning=osType:; \
     additional_data(2).data=unknown; chained; silent;
    
    regex=\[UDP: \[([^\]]+)\]:\d+->\[[^\]]+\]\]:.012iso\.3\.6\.1\.2\.1\.1\.3\.0 \d?\d?\d?:?\d\d:\d\d:\d\d\.\d\d.011iso\.3\.6\.1\.6\.3\.1\.1\.4\.1\.0 iso\.3\.6\.1\.4\.1\.9\.9\.383\.0\.1.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.1\.1 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.1\.2 "[\d\w\s]+".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.1\.3 "[\d\w\s]+".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.1\.4 "(\S+)".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.1 "(info|low|medium|high)(?:rmational)?".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.2 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.3 "([^"]+)"#011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.4 "([^"]+)".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.5 (\d+).011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.6 (\d+).011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.7 "[^"]+".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.12 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.13 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.16 "([^"]+)".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.21 "\.\s+adExtraData: numDestIps=(\d+). currentThreshold=(\d+). protocol=(\d+) . ".011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.25 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.26 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.27 \d+.011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.2\.42 \d+; \
      id=5030; \
      revision=1; \
      classification.text=$5; \
      classification.reference(0).origin=vendor-specific; \
      classification.reference(0).name=$6.$7; \
      classification.reference(0).meaning=ips_id; \
      classification.reference(0).url=http://tools.cisco.com/security/center/viewIpsSignature.x?signatureId=$6&signatureSubId=$7; \
      assessment.impact.severity=$3; \
      assessment.impact.type=other; \
      assessment.impact.description=$4; \
      source(0).node.address(0).category=ipv4-addr; \
      source(0).node.address(0).address=$8; \
      target(0).node.address(0).category=ipv4-addr; \
      target(0).node.address(0).address=0.0.0.0; \
      analyzer(0).node.address(0).address=$1; \
      analyzer(0).node.name=$2; \
      analyzer(0).manufacturer=Cisco; \
      analyzer(0).class=IPS; \
      analyzer(0).name=Cisco IPS; \
    last;
    
    #>>ALERT>>
    
    #<<ERROR<<
    #SIG POOL: 5040-5079
    
    regex=011iso.3.6.1.4.1.9.9.383.1.3.1 "(\w+)"; \
     id=5040; \
     classification.text=IPS $1 message; \
     classification.reference(0).origin=vendor-specific; \
     additional_data(0).type=string; \
     additional_data(0).meaning=$1:; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 1#; \
     id=5041; \
     classification.reference(0).name=errAuthenticationTokenExpired; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 2#; \
     id=5042; \
     classification.reference(0).name=errConfigCollision; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 3#; \
     id=5043; \
     classification.reference(0).name=errInUse; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 4#; \
     id=5044; \
     classification.reference(0).name=errInvalidDocument; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 5#; \
     id=5045; \
     classification.reference(0).name=errLimitExceeded; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 6#; \
     id=5046; \
     classification.reference(0).name=errNotAvailable; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 7#; \
     id=5047; \
     classification.reference(0).name=errNotFound; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 8#; \
     id=5048; \
     classification.reference(0).name=errNotSupported; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 9#; \
     id=5049; \
     classification.reference(0).name=errPermissionDenied; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 10#; \
     id=5050; \
     classification.reference(0).name=errSyslog; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 11#; \
     id=5051; \
     classification.reference(0).name=errSystemError; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 12#; \
     id=5052; \
     classification.reference(0).name=errTransport; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 13#; \
     id=5053; \
     classification.reference(0).name=errUnacceptableValue; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 14#; \
     id=5054; \
     classification.reference(0).name=errUnclassified; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.2 15#; \
     id=5055; \
     classification.reference(0).name=errWarning; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.3 "(A global correlation update failed: Receive HTTP response failed \[\S+\].012Messages, like this one, in the category - Reputation update failure - were logged \d+ times in the last \d+ seconds\.|No installable auto update package found on server|SNMP could not get statistical value\.|error getting config)"; \
     id=5070; \
     assessment.impact.severity=info; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.3 "(autoUpdate successfully selected a package \S+ from the cisco\.com locator service, however, package download failed: .+|AutoUpdate exception: Receive HTTP response failed \[\S+\])"; \
     id=5071; \
     assessment.impact.severity=low; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.3\.3 "(Target system does not have a valid license to process the config with the version \S+)"; \
     id=5072; \
     assessment.impact.severity=med; chained; silent;
    
    
    #>>ERROR>>
    
    #<<MESSAGE TYPE<<
    #SIG POOL: 5080-5089
    
    optgoto=5000-5006; regex=011iso\.3\.6\.1\.6\.3\.1\.1\.4\.1\.0 iso\.3\.6\.1\.4\.1\.9\.9\.383\.0\.1; \
     id=5080; \
     classification.text=IPS alert message; \
     assessment.impact.description=This event was generated by the Cisco IPS; \
     classification.reference(0).origin=vendor-specific; \
     classification.reference(0).meaning=ips_id; \
     assessment.impact.severity=high; chained; silent;
    
    optgoto=5040-5055; optgoto=5070-5072; regex=011iso\.3\.6\.1\.6\.3\.1\.1\.4\.1\.0 iso\.3\.6\.1\.4\.1\.9\.9\.383\.0\.2; \
     id=5081; \
     classification.text=IPS system message; \
     assessment.impact.description=This event was generated by the Cisco IPS; \
     classification.reference(0).origin=vendor-specific; \
     classification.reference(0).meaning=ips_id; \
     assessment.impact.severity=high; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.1\.1(?:\.0)? (\d+); \
     id=5082; chained; silent;
    
    regex=011iso\.3\.6\.1\.4\.1\.9\.9\.383\.1\.1\.4(?:\.0)? "([\w\d-]+)"; \
     id=5083; \
     analyzer(0).node.name=$1; \
     analyzer(0).name=Cisco IPS; \
     analyzer(0).manufacturer=Cisco; \
     analyzer(0).class=IPS; chained; silent;
    
    ### TURN OFF FLOOD ###
    regex=.012iso\.3\.6\.1\.2\.1\.1\.3\.0 (\S+).011iso\.3\.6\.1\.6\.3\.1\.1\.4\.1\.0 iso.3\.6\.1\.4\.1\.9\.9\.138\.2\.0\.1(?:\.0)?.011iso\.3\.6\.1\.4\.1\.9\.9\.138\.1\.3\.3\.1\.3(?:\.0)? (\d+).011iso\.3\.6\.1\.4\.1\.9\.9\.138\.1\.3\.3\.1\.4(?:\.0)? (\d+).011iso\.3\.6\.1\.4\.1\.9\.9\.138\.1\.3\.3\.1\.5(?:\.0)? (\d+).011iso\.3\.6\.1\.4\.1\.9\.9\.138\.1\.3\.3\.1\.6(?:\.0)? (\d+); silent; last;
    
    #>>MESSAGE TYPE>>
    
    #<<MAIN RULE<<
    #SIG POOL: 5090-5099
    optgoto=5080-5083; regex=snmptrapd\[\d+\]: \d+-\d+-\d+ \d+:\d+:\d+ \d+.\d+.\d+.\d+ \[UDP: \[(\d+\.\d+\.\d+\.\d+)]:\d+->\[(\d+.\d+.\d+.\d+)\]\]:; \
     classification.text=snmp unknown message; \
     classification.reference(0).origin=vendor-specific; \
     id=5090; \
     revision=1; \
     assessment.impact.severity=high; \
     assessment.impact.type=other; \
     assessment.impact.description=This event was generated by snmptrapd; \
     source(0).node.address(0).address=$1; \
     analyzer(0).node.address(0).address=$2; \
    last;
    #>>MAIN RULE>>
    #EOF
    


    В этом наборе правил заложен следующий принцип:
    • поступающий лог сначала попадает под общую сигнатуру события IPS: правило 5090;
    • опционально проверяется тип сообщения – ошибка/системное сообщение/алерт: правила с 5080 по 5089;
    • если полученное сообщение относится к ошибке – определяем её тип: правила с 5040 по 5079;
    • если полученное сообщение является срабатыванием сигнатуры – вытаскиваем всё, что нам интересно: правила с 5000 по 5039;

    Т.е. обработка лога по правилу идёт сверху вниз. Но часть правил с ключами chained; silent; в этой обработке не учавствуют, пока на них явно не будет дана ссылка из нижестоящего правила (ключом optgoto).

    Для IOS-IPS можно также перенаправить логи на наш сервер и аналогично применить вот такой набор правил:
    cisco-ios-ips.rules
    #
    # Copyright (C) 2013 lei_wulong
    #
    # This file is part of the Prelude-LML program.
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2, or (at your option)
    # any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; see the file COPYING.  If not, write to
    # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    #
    #####
    
    ##RULES FOR CISCO IOS-IPS###
    ## id pool = [580-599]
    
    regex=Subsig\:\d+\s+Sev\:25; \
     id=580; \
     assessment.impact.severity=info; \
     silent
    
    regex=Subsig\:\d+\s+Sev\:50; \
     id=581; \
     assessment.impact.severity=low; \
     silent
    
    regex=Subsig\:\d+\s+Sev\:75; \
     id=582; \
     assessment.impact.severity=medium; \
     silent
    
    regex=Subsig\:\d+\s+Sev\:100; \
     id=583; \
     assessment.impact.severity=high; \
     silent
    
    ### For IOS 12.4(11)###
    regex=(\d+\.\d+\.\d+\.\d+)\s+\d+\:\s+(.+?)\:.+?\%IPS-4-SIGNATURE\: Sig\:(\d+)\s+Subsig\:(\d+)\s+Sev\:(\d+)\s+\[([\d\.]+)\:(\d+)\s+\-\>\s+([\d\.]+)\:(\d+)\]\s+RiskRating\:(\d+); \
     classification.text=$3.$4; \
     classification.reference(0).origin=vendor-specific; \
     classification.reference(0).meaning=cisco_id; \
     classification.reference(0).name=$3.$4; \
     classification.reference(0).url=http://tools.cisco.com/security/center/viewIpsSignature.x?signatureId=$3&signatureSubId=$4; \
     id=584; \
     revision=2; \
     analyzer(0).name=Cisco IPS; \
     analyzer(0).manufacturer=Cisco; \
     analyzer(0).class=IPS; \
     analyzer(0).node.address(0).address=$1; \
     analyzer(0).node.name=$2; \
     assessment.impact.type=other; \
     source(0).node.address(0).category=ipv4-addr; \
     source(0).node.address(0).address=$6; \
     target(0).node.address(0).category=ipv4-addr; \
     target(0).node.address(0).address=$8; \
     source(0).service.port=$7; \
     target(0).service.port=$9; \
     additional_data(0).type=integer; \
     additional_data(0).meaning=Signature Severity; \
     additional_data(0).data=$5; \
     additional_data(1).type=integer; \
     additional_data(1).meaning=Risk Rating; \
     additional_data(1).data=$10; \
    
    ###FOR IOS 15.1 ###
    regex=(\d+\.\d+\.\d+\.\d+)\s+\d+\:\s+(.+?)\:.+?\%IPS-4-SIGNATURE\: Sig\:(\d+)\s+Subsig\:(\d+)\s+Sev\:(\d+)\s+(.+?)\s+\[([\d\.]+)\:(\d+)\s+\-\>\s+([\d\.]+)\:(\d+)\]\s+VRF\:(.+?)\s+RiskRating\:(\d+); \
     classification.text=$6; \
     classification.reference(0).origin=vendor-specific; \
     classification.reference(0).meaning=cisco_id; \
     classification.reference(0).name=$3.$4; \
     classification.reference(0).url=http://tools.cisco.com/security/center/viewIpsSignature.x?signatureId=$3&signatureSubId=$4; \
     id=585; \
     revision=2; \
     analyzer(0).name=Cisco IPS; \
     analyzer(0).manufacturer=Cisco; \
     analyzer(0).class=IPS; \
     analyzer(0).node.address(0).address=$1; \
     analyzer(0).node.name=$2; \
     assessment.impact.type=other; \
     source(0).node.address(0).category=ipv4-addr; \
     source(0).node.address(0).address=$7; \
     target(0).node.address(0).category=ipv4-addr; \
     target(0).node.address(0).address=$9; \
     source(0).service.port=$8; \
     target(0).service.port=$10; \
     additional_data(0).type=integer; \
     additional_data(0).meaning=Signature Severity; \
     additional_data(0).data=$5; \
     additional_data(1).type=integer; \
     additional_data(1).meaning=Risk Rating; \
     additional_data(1).data=$12; \
     additional_data(2).type=string; \
     additional_data(2).meaning=VRF; \
     additional_data(2).data=$11; \
    last;
    


    После всех вышеописанных манипуляций получаем вот такой результат:



    В консоли появляются срабатывания от всех IPS-сенсоров. На скриншоте выше выставлена группировка по source и destination адресам. Здесь присутствуют как события от IPS-модулей и апплаинсов, так и от роутеров с включенным IOS-IPS (на скриншоте это не видно из-за технологий «обфускации»). Группировать/фильтровать мы можем по всем значениям, которые были определены в ходе обработки нашим набором правил.
    Соответственно в любое событие можно «провалиться» и посмотреть подробности:



    6. Корреляция Heart bleed


    Последним штрихом в настройке будет та часть, которая отличает системы просмотра событий от SIEM: корреляция.
    Для примера настройки правила корреляции возьмем наболевшую в последние дни уязвимость в библиотеке OpenSSL – HeartBleed.

    У Cisco существует сигнатура, которая позволяет отлавливать попытку эксплуатации данной уязвимости: tools.cisco.com/security/center/viewIpsSignature.x?signatureId=4187&signatureSubId=0
    Номер сигнатуры — 4187.0, называется она “OpenSSL Information Disclosure”.
    Само по себе срабатывание данной сигнатуры ещё не будет означать, что уязвимость была проэксплуатирована, т.к. IPS не знает, уязвим атакуемый хост или нет. Но на этот вопрос вполне может ответить SIEM.
    Общий принцип правила корреляции следующий: если в SIEM поступает вышеуказанное событие от IPS, то SIEM сам проверяет наличие уязвимости HeartBleed на целевом хосте. В случае, если хост уязвим, то будет создано отдельное событие корреляции.
    Само правило выглядит следующим образом:

    #
    # Copyright (C) 2014 Vladimir Lapshin <vmlapshin at gmail dot com>
    # Copyright (C) 2014 lei_wulong
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2, or (at your option)
    # any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; see the file COPYING.  If not, write to
    # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    #
    
    import re
    from PreludeCorrelator.pluginmanager import Plugin
    from PreludeCorrelator.context import Context
    import time
    import subprocess
    
    localtime = time.localtime()
    timestamp = time.strftime('%d %b %H:%M:%S', localtime)
    
    print str(timestamp) + ' HeartBleed plugin  (correlator) INFO: Starting...'
    
    class heartbleed(Plugin):
        def run(self, idmef):
            if not idmef.match('alert.classification.text', re.compile('^OpenSSL Information Disclosure$|^Other security event$')):
                return
    
            addr = idmef.Get('alert.target(*).node.address(*).address')
            if not addr:
                return
    
            port = idmef.Get('alert.target(0).service.port')
            if not port:
                port='443'
    
            script = str('python2.6 /etc/prelude-correlator/heartbleed.py ') + str(addr).strip('[\'\']') + str(' -p ') + str(port)
            print script
            PIPE = subprocess.PIPE
            p = subprocess.Popen(script, shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, close_fds=True)
            while True:
                s = p.stdout.readline()
                if not s:
                    break
                if re.findall('server is vulnerable', s):
                    ctx = Context(("HEART_BLEED", addr), update=True, idmef=idmef)
                    ctx.Set("alert.classification.text", "HeartBleed vulnerability detected")
                    ctx.Set("alert.correlation_alert.name", "HeartBleed vulnerability detected")
                    ctx.Set("alert.assessment.impact.severity", "high")
                    ctx.Set("alert.classification.reference(0).origin", "vendor-specific")
                    ctx.Set("alert.classification.reference(0).name", "CVE-2014-0160")
                    ctx.alert()
                    ctx.destroy()
                    print 'Vulnerable!'
                    return
    

    В данном примере для проверки наличия уязвимости используется вот этот скрипт: gist.github.com/sh1n0b1/10100394. Он должен быть расположен в одной директории с плагином корреляции. Для приведенного выше примера этот путь /etc/prelude-correlator/heartbleed.py

    Также надо не забыть сделать исключение на IPS-сенсорах для сигнатур 4187.х и адреса-источника, где установлен Prelude, иначе получим рекурсию: атака -> правило корреляции, которое также обнаружится IPS-ом (мы ведь используем по сути тот же heartbleed) -> новый алерт IPS -> корреляции -> и т.д. Сделать это можно через Event Action Filter.
    Либо можно исключить рекурсию в самом правиле, добавив:
    if idmef.match("alert.source(0).node.address(0).address", re.compile("0\.0\.0\.0")) # <- Prelude-Correlator addr
        return
    

    Но если не настроить Event Action Filter, наш IPS будет реагировать на саму проверку, выполняемую Prelude. Если сенсор её (проверку) заблокирует – мы не сможем проверить наличие уязвимости.

    После установки правила, при срабатывании сигнатуры Cisco 4187.0 получим следующий результат:



    Фактически это означает, что был атакован хост, восприимчивый к этой атаке. Правило корреляции в примере ждёт событий, которые называются '^OpenSSL Information Disclosure$|^Other security event$'. Само собой, можно не ограничиваться одним событием от Cisco IPS. По такому же принципу можно осуществлять корреляцию по IPS любых других вендоров, подключенных к системе.
    Также можно привязаться к событию входа на web-сервер. Если он уязвим – значит учетная запись, использованная для входа, потенциально скомпрометирована.
    Описанное в этой статье правило – всего лишь пример частного случая применения для последних актуальных событий. Все прочие «хотелки» ограничены лишь воображением и python-ом (читай — не ограничены ничем). Например в предлагаемом скрипте можно обыграть различные сценарии: производить проверку только по своим ресурсам (только серые адреса/пул внешних адресов), менять ip и порт «жертвы», в случае если наш ресурс за NAT-ом и т.д.

    7. Эпилог


    В завершении также стоит отметить про возможность сбора событий через SDEE.
    Т.к. в этой статье была рассмотрена настройка для OSS-версии Prelude, то дружить IPS и Prelude пришлось через SNMP (для IPS-модулей/апплаинсов) и syslog (для IOS-IPS). Но, как уже упоминалось в 4-ом разделе, все эти устройства могут работать через SDEE. При этом появляется возможность получать события от IPS в единообразном виде с максимально полной информацией о каждом алерте. Для этого необходим SDEE-коннектор, который присутствует только в коммерческой версии Prelude.

    Из прочих отличий коммерческой версии PreludePro:
    • производительность;
    • возможность подключать подчиненные Manager-ы;
    • доп. функции в Prewikka (аутентификация через LDAP, возможность встраивать собственные команды в web-интерфейс и прочее);
    • дополнительные модули (log-management, система инвентаризации, и т.д.)

    Опять получилось объемно, старался «ужать» как мог.
    Надеюсь, было интересно и полезно.
    Всем удачи в выявлении инцидентов!
    _____
    Материалы, использованные в статье:
    CSM User Guide www.cisco.com/c/en/us/td/docs/security/security_management/cisco_security_manager/security_manager/4-6/user/guide/CSMUserGuide.html
    IME Notification Example: www.cisco.com/c/en/us/support/docs/security/ips-4200-series-sensors/111659-ips-email-ime-config.html
    IOS IPS events via IME: www.cisco.com/c/en/us/support/docs/security/intrusion-prevention-system/113576-ptn-113576.html
    Prelude OSS official page www.prelude-ids.org
    Обзор интерфейса Prewikka: is-systems.org/siem/interface
    Поделиться публикацией
    Комментарии 0

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

    Самое читаемое