Как работает эта ваша суриката

Как работает эта ваша суриката — Cybersecurity | Versia.media

Всем привет!

Моя деятельность связана с анализом сетевого трафика и разработкой детектирующих правил для Suricata. Хочу поделиться с вами своим опытом работы с этим инструментом. В серии статей мы разберем тонкости функционирования данного IDS/IPS-решения, научимся писать сигнатурные правила и понимать, как их создавать для обнаружения нелегитимной активности.

Базовую информацию о Suricata (как она анализирует пакеты, чем превосходит Snort, какие модули захвата может использовать) вы без труда найдете в интернете самостоятельно. Также предполагается, что у вас есть начальные знания по сетям и вы умеете пользоваться Wireshark.

Теоретические аспекты я буду объяснять по ходу изложения — перейдем сразу к практике:

Однажды мне порекомендовали интересный и полезный инструмент для тестирования Suricata — Dalton. Можно было бы установить только Suricata и запускать ее через терминал. Dalton привлек меня наличием веб-интерфейса и удобством тестирования правил на pcap-файлах. Соответственно, хочу познакомить и вас с ним.

Установка Dalton

Dalton будем разворачивать на виртуальной машине с Ubuntu. Итак, устанавливаем Ubuntu и выделяем для нее два интерфейса (первый — с типом NAT, второй — с типом доступа «Сетевой мост»). Выделите для нее 4 ГБ оперативной памяти, 2 ядра и 50 ГБ постоянного дискового пространства.

После установки Ubuntu сразу установите гостевые дополнения, Wireshark и git, а затем следуйте инструкциям ниже: root@ sam-VirtualBox:/home/sam/Desktop/# git clone https://github.com/secureworks/dalton.git устанавливаем Docker: root@sam-VirtualBox:/home/sam/Desktop/dalton# apt install ca-certificates curl root@sam-VirtualBox:/home/sam/Desktop/dalton# install -m 0755 -d /etc/apt/keyrings root@sam-VirtualBox:/home/sam/Desktop/dalton# sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc root@sam-VirtualBox:/home/sam/Desktop/dalton# chmod a+r /etc/apt/keyrings/docker.asc root@sam-VirtualBox:/home/sam/Desktop/dalton# echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null root@sam-VirtualBox:/home/sam/Desktop/dalton# apt-get update root@sam-VirtualBox:/home/sam/Desktop# sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin Проверяем, что Docker установился корректно: root@sam-VirtualBox:/home/sam/Desktop# sudo docker run hello-world root@sam-VirtualBox:/home/sam# curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/docker-compose root@sam-VirtualBox:/home/sam# chmod +x /usr/bin/docker-compose root@sam-VirtualBox:/home/sam# docker-compose –version

Далее переходим в файл root@sam-VirtualBox:/home/sam/Desktop/dalton# nano docker-compose.yml и комментируем строки, относящиеся к установке Snort (так как Snort из РФ недоступен для загрузки).

Затем выполняем скрипт согласно инструкции репозитория Dalton: root@sam-VirtualBox:/home/sam/Desktop#./start-dalton.sh в конце результат будет таким:

Помните, что у нас два интерфейса на виртуальной машине? На том интерфейсе, который имеет тип «Сетевой мост», установите статический IP-адрес из вашей локальной сети компьютера. Таким образом, вы сможете заходить в утилиту Dalton, просто введя адрес http://192.168.1.150/dalton/ в браузере вашей хост-машины. А виртуальную машину можно просто свернуть (при необходимости — мы ее используем).

Также на этом этапе не забудьте сделать снимок состояния машины. Потому что Docker впоследствии может занять много места, и если не получится нормально его очистить, можно будет просто вернуться к исходному состоянию. Знаю, возникает вопрос: зачем тогда ставить десктопную версию Ubuntu, можно было бы использовать серверную CLI и работать с локального хоста — ну, я решил так. В любом случае, гайд есть, и аналогично можно сделать с версией Ubuntu Server.

На момент написания статьи была установлена Suricata версии 8.0.1

Итог успешной установки:

Что делать с Dalton

Давайте проведем небольшой экскурс по Dalton. Зайдя на главную страницу, перейдем в Suricata через кнопку «Go»:

Итак, мы видим: есть возможность выбрать файл с pcap для загрузки и тестирования. Можно выбрать несколько pcap-файлов. Версию Suricata оставим 8. «Use a defined ruleset» — отключим. Для тестирования собственных правил необходимо установить галочку на «Use custom rules» — откроется окно, куда мы и будем вписывать правила. Другие настройки не трогаем. При запуске Suricata нам нужно будет выбрать pcap, написать правило и нажать кнопку «Submit». А во вкладке «Config Files» можно найти конфигурационный файл Suricata:

Все обучение будет ссылаться на документацию.

Наш путь изучения Suricata мы начнем с пункта 8, подпункта 1 указанной выше документации.

Формат правила

Красным цветом выделено действие, которое Suricata должна предпринять в случае совпадения фрагмента трафика с условиями правила. Действия бывают следующими: alert — генерирует оповещение. pass — останавливает дальнейший разбор сессии/пакета. drop — отбрасывает пакеты и генерирует оповещение. reject — отправляет RST/ICMP-ошибку недоступности получателю, на пакет которого произошло срабатывание. rejectsrc — то же, что и reject. rejectdst — отправляет RST/ICMP-ошибку недоступности отправителю, на пакет которого произошло срабатывание. rejectboth — отправляет RST/ICMP-ошибку недоступности обоим участникам сетевого взаимодействия.

Хочу обратить ваше внимание, что если Suricata НЕ настроена на работу в режиме IPS, то будут работать только alert и pass. В рамках моего обучения будет затронута в основном функция alert.

Далее разберем выделенное зеленым цветом «http $HOME_NET any → $EXTERNAL_NET any». Сначала указывается протокол (не буду здесь перечислять все возможные протоколы, которые может определять Suricata — посмотрите в документации), а затем указывается информация об участниках соединения. Схема следующая: адрес_источника порт_источника → адрес_получателя порт_получателя. Адреса и порты можно указывать как по отдельности, так и перечислять через переменные. Примеры: $HOME_NET any → $EXTERNAL_NET 123 !1.1.1.1 any → 2.2.2.2 $ORACLE_PORTS [1.1.1.1, 1.1.1.2] any -> $EXTERNAL_NET [80, 81, 82]

Переменные задаются в конфигурационном файле:

Вы можете сами создавать свои переменные и вносить в них IP-адреса, подсети, порты.

А теперь важный символ — направление «→». На этом остановимся подробнее и поговорим о направлении соединения. В сети у нас всегда есть инициатор и получатель.

Так вот, знак направления "->" задает совпадение сигнатуры по направлению потока пакетов. Важно уметь различать понятия: «пакеты» и «сессия» — и понимать разницу:

Сессия — это определение установленного соединения между двумя узлами сети. В основном касается протокола TCP, который гарантирует доставку данных.

Сессия — это определение установленного соединения между двумя узлами сети. В основном касается протокола TCP, который гарантирует доставку данных.

Пакеты — это некий структурированный блок данных, на который разбивается информация для передачи по сети.

Пакеты — это некий структурированный блок данных, на который разбивается информация для передачи по сети.

В данном случае мы говорим о направлении потока пакетов. Соответственно, если мы зададим условие в правиле 1.2.3.4 -> 5.6.7.8, то сигнатура будет определять совпадения по пакетам, идущим только от клиента 1.2.3.4 к серверу 5.6.7.8.

Также нужно понимать, что в рамках сессии между двумя участниками сети пакеты могут идти в обоих направлениях. Поясним это, снова обратившись к схеме выше, где клиент 1.2.3.4 инициирует соединение с сервером 5.6.7.8. Если мы рассматриваем соединение по протоколу UDP, то пакеты в рамках одного соединения будут идти только от клиента к серверу. Если же клиент инициирует соединение с сервером по протоколу TCP, то между ними устанавливается TCP-сессия. В рамках установленной TCP-сессии хосты отправляют друг другу пакеты для подтверждения данных. Соответственно, при инициировании соединения клиента с сервером по TCP, направление пакетов может быть как от клиента к серверу, так и от сервера к клиенту в рамках их TCP-сессии. Направление пакета определяется по его заголовкам, где указываются отправитель и получатель. Отправителем и получателем может быть любой участник сетевого взаимодействия, будь то клиент или сервер в рамках TCP-сессии. В дальнейшем на практике мы закрепим эти знания.

Важное замечание: обратного обозначения направления "<-" Suricata не поддерживает. Возможные варианты: source -> destination — будут совпадать пакеты с таким направлением. source => destination — относительно новая функция на момент написания статьи. Работает так же, как и указанная выше, но может работать и с двунаправленным соединением. source <> destination — будут совпадения в обоих направлениях.

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

Давайте посмотрим, как пишутся правила, как правильно задавать получателя и источника сетевого взаимодействия, как ставить направление и так далее. Разберемся с базовыми понятиями. Переходим сюда и скачиваем http.cap. Откройте его в Wireshark, зайдите в Dalton в раздел Suricata, выберите этот pcap через кнопку «Выбрать файл».

Внимательно просмотрите pcap:

У нас два участника сети: 145.254.160[.]237 и 65.208.228[.]223. Давайте напишем правило для HTTP-запроса:

alert tcp 145.254.160.237 any -> 65.208.228.223 80 (msg:"Test Http request"; content:"GET"; content:"download.html"; sid:1;)

Кратко о работе правила: сигнатура генерирует оповещение на TCP-соединение от 145.254.160.237 к 65.208.228.223 по 80 порту. Как нам известно, транспортный протокол 4-го уровня модели OSI используется для гарантированной передачи данных от отправителя к получателю. Соответственно, в TCP-пакетах в полезной нагрузке передаются HTTP-запросы (как в нашем примере). А мы через модификатор content ищем "GET" и "download.html" в полезной нагрузке. Тем самым просим Suricata сгенерировать оповещение при обнаружении последовательности символов GET и “download.html” в полезной нагрузке с хоста 145.254.160[.]237 на хост 65.208.228[.]223 по 80 порту.

Давайте запустим правило и посмотрим срабатывания. Копируем указанное выше правило и вставляем в окно под фразой "Use custom rules". Не забудьте поставить галочку. Нажимаем "Submit".

У нас одно оповещение:

Перейдем во вкладку «Alert Debug». Там мы можем увидеть распарсенные логи и посмотреть срабатывания.

Здесь доступно много полезной информации. Опишу ключевые поля:

PCAP PKT NUM — номер пакета в pcap, на который сработала сигнатура. Это значение доступно, когда Suricata запускается при проверке pcap-файла с трафиком, чтобы выполнять поиск в дампе трафика в Wireshark. По крайней мере, так написано в документации, но если мы посмотрим на 7-й фрейм в Wireshark, то увидим, что в нем нет полезной нагрузки с HTTP-запросом. Однако 7-й фрейм (пакет) относится к TCP-сессии, в рамках которой выполнялся HTTP-запрос, и есть фрагмент срабатывания по нашей сигнатуре. Номер сработавшего пакета подскажет нам ID сессии, которую впоследствии можно полностью изучить; SRC IP, DST IP — IP-адрес источника и получателя пакета соответственно; SRC PORT, DST PORT — порт источника и получателя пакета соответственно; TCP SEQ, TCP ACK — TCP sequence и acknowledgement number соответственно в пакете, на который сработала сигнатура; FLOW — поле, содержащее информацию о направлении пакета: от сервера к клиенту или от клиента к серверу. В нашем случае — от клиента к серверу (to_server: TRUE); ALERT CNT — количество оповещений или сработавших правил на пакет/сессию; ALERT SID — SID сработавшего правила; ALERT MSG — наименование сработавшего правила; PACKET — здесь представлен пакет в ASCII, как если бы вы смотрели в Wireshark область побайтового представления пакета; STREAM DATA — здесь представлена часть TCP-потока, на которую было вызвано срабатывание. Как ее посмотреть? Откройте Wireshark, нажмите на 7-й фрейм правой кнопкой мыши и выберите «Отслеживать» -> «TCP-поток». На картинке ниже выделено, какая часть STREAM (потока) представлена в выводе Dalton.

Таким образом, наше правило Suricata “alert tcp 145.254.160.237 any -> 65.208.228.223 80 (msg:"Test Http request"; content:"GET"; content:"download.html"; sid:1;)”, обнаружило в дампе трафика HTTP-запрос, который использует метод GET и содержит в запросе URI “download.html”. В выводе Dalton это подтверждается соответствующими значениями в указанных полях.

Кроме того, хочу отметить, что Suricata умеет работать с правилами для прикладных протоколов. У самой Suricata есть внутренние механизмы, которые по заголовкам пакетов определяют протоколы. В Wireshark, например, есть диссекторы, позволяющие анализировать заголовки пакетов. Эти диссекторы могут использоваться и другими ПО для анализа трафика. В Suricata можно добавлять код диссектора для своих кастомных протоколов. Так вот, если у вас будет сетевое взаимодействие по протоколу HTTP, но не по 80 порту, а по порту 3380, Suricata также его определит. Можем дополнить указанное правило и конкретизировать его следующим образом:

alert http 145.254.160.237 any -> 65.208.228.223 80 (msg:"Test Http request"; flow:established,to_server; content:"GET"; content:"download.html"; sid:1;)

Можете

← Cybersecurity