DPI из подручных материалов

от автора

Всем привет!

Однажды, много лет назад, во времена эпидемии вируса Code Red, я работал сисадмином в одном вузе и невежливо ответил на электронное письмо из какого то‑банка с требованием немедленно прекратить атаку на их веб сервер, работающий под управлением Apache, через месяц пришло бумажное письмо от их службы безопасности, и завертелось. Так я познакомился с системой Snort, которая некоторое время защищала Интернет от наших студентов. Со временем, большая часть трафика стала https, и решение потеряло смысл, но, есть места, где он снова превращается в http, например после https прокси. Тут то мы и сможем его «подсмотреть», выявить атаки и заблокировать злоумышленника!

Что бы было интереснее, не будем рассматривать реальный кейс, а воспроизведем все «в домашних условиях». На единственной системе развернем https прокси, веб приложение за ним, и защитим от атак на основе анализа содержимого http запросов. Потребуется VirtualBox (или любой другой гипервизор) и дистрибутив Linux, например Ubuntu, там Snort имеется в виде пакета. Можно взять мой готовый ova образ:

https://val.bmstu.ru/unix/img/My%20Documents/ubuntu_24.04_01.ova

и выполнить 1-й шаг из этой статьи:

Шаг 2. Разворачиваем http приложение

Можно развернуть что-нибудь поинтереснее, но, сути это не меняет, поэтому обойдемся простым вариантом:

$ sudo -i # apt update # apt install docker.io # docker run --name http-app -d --restart=always httpd # docker inspect http-app -f {{.NetworkSettings.IPAddress}} # curl http://172.17.0.2

http приложение готово!

Шаг 2. Создаем сертификат для https прокси

Для «игрушечного» примера подойдет само подписанный сертификат c атрибутами «по умолчанию»

# openssl genrsa -out /etc/ssl/private/http-app.key 2048 # openssl req -new -x509 -days 3650 -key /etc/ssl/private/http-app.key -out /etc/ssl/certs/http-app.crt

На все «вопросы» последней команды достаточно нажать Enter (даже про Common Name, поскольку тестировать все будем по ip адресу)

Шаг 3. Разворачиваем https прокси

В качестве https прокси рассмотрим nginx (можно haproxy, суть не изменится). Поскольку тестировать все будем по ip адресу, настроим перенаправление любых запросов (server_name _) на 443 порт в наше http приложение. X-Forwarded-For в нашем случае нужен потому, что только в этом заголовке будет ip адрес клиента в трафике между https прокси и приложением.

# apt install nginx  # nano /etc/nginx/sites-available/http-app      server {         listen 443 ssl;         server_name  _;         ssl_certificate /etc/ssl/certs/http-app.crt;         ssl_certificate_key /etc/ssl/private/http-app.key;          location / {             proxy_pass http://172.17.0.2;             proxy_set_header X-Forwarded-For $remote_addr;         }     }  # ln -s /etc/nginx/sites-available/http-app /etc/nginx/sites-enabled/http-app  # systemctl restart nginx.service

Теперь наше http приложение должно быть доступно по # apt install snort

В вопросах инсталлятора про сетевые интерфейсы указываем docker0, в нашем случае именно через него идет трафик между https прокси и http приложением в контейнере. Остальные ответы «по умолчанию», результат работы инсталлятора записывается в файл:

# less /etc/snort/snort.debian.conf  ... DEBIAN_SNORT_INTERFACE="docker0" ...

В основном файле конфигурации отключаем проверку контрольной суммы пакетов, поскольку эта функциональность актуальна только для «входящего» трафика, а в нашем случае, http трафик будет «выходить» из интерфейса docker0, добавляем опцию анализа заголовка X‑Forwarded‑For в http трафике и настраиваем вывод сообщений об обнаруженных атаках в syslog с типом сообщений auth и уровнем важности alert:

# nano /etc/snort/snort.conf  ... # Configure IP / TCP checksum mode config checksum_mode: none ... preprocessor http_inspect_server: server default \ ...     enable_xff \     webroot no ... #################################################################### # Step #6: Configure output plugins ... output alert_syslog: LOG_AUTH LOG_ALERT ...  # systemctl restart snort.service

Для тестирования будем использовать тот самый злополучный Code Red, для которого, как раз, есть правило «из коробки»:

# less /etc/snort/rules/web-iis.rules  ... alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"WEB-IIS CodeRed v2 root.exe access"; flow:to_server,established; uricontent:"/root.exe"; nocase; reference:url,www.cert.org/advisories/CA-2001-19.html; classtype:web-application-attack; sid:1256; rev:8;) ...

Симулировать атаку можно обращаясь к нашему приложению по # tail -f /var/log/auth.log ... 2024-05-12T18:06:07.467018+00:00 ubuntu snort[6978]: [1:1256:8] WEB-IIS CodeRed v2 root.exe access [Classification: Web Application Attack] [Priority: 1] {TCP} 172.17.0.1:40890 -> 172.17.0.2:80 ...

Но, стоп, в них отсутствует адрес клиента, здесь только адрес прокси и самого приложения!

Оказывается, информация из заголовка X-Forwarded-For попадает в двоичный файл, для анализа которого авторы Snort добавили специальную утилиту:

# u2spewfoo /var/log/snort/snort.alert  ... priority: 1     ip source: 172.17.0.1   ip destination: 172.17.0.2 ... type: 1 datatype: 1     bloblength: 12  Original Client IP: 192.168.1.100 ...

Этот файл создается и непрерывно растет с момента запуска Snort, а утилита умеет выводить его только целиком. Для нашей следующей задачи будет удобнее, если полученная таким образом информация будет тоже последовательно писаться в журнал. Пришлось «сочинить» такого «крокодила» (ключи ‑с +1 команды tail из‑за двоичного формата файла, u2spewfoo не умеет читать из STDIN, stdbuf отключает буферизацию ввода и вывода, logger все пишет в syslog от имени приложения snort с типом сообщений auth и уровнем важности info):

# stdbuf -i0 -o0 u2spewfoo <(tail -c +1 -f /var/log/snort/snort.alert) | logger -t snort -p auth.info

В журнале теперь будут появляться такие сообщения (понадобится вторая консоль):

# tail -f /var/log/auth.log  ... 2024-05-12T18:16:25.965360+00:00 ubuntu snort: #011type: 1#011datatype: 1#011bloblength: 12#011Original Client IP: 192.168.1.100 ...

Можно оформить запуск «крокодила» через systemd

# nano /etc/systemd/system/snort-alert-unified2-syslog.service  [Unit] Description=Send snort alert_unified2 to syslog After=snort.service  [Service] ExecStart=/bin/bash -c '/usr/bin/stdbuf -i0 -o0 /usr/sbin/u2spewfoo <(/usr/bin/tail -c +1 -f /var/log/snort/snort.alert) | /usr/bin/logger -t snort -p auth.info'  [Install] WantedBy=multi-user.target  # systemctl enable snort-alert-unified2-syslog --now

Шаг 5. Превращаем IDS в IPS

Теперь в журнале поваляются адреса клиентов, сигнатуры пакетов которых попадают в правила Snort (с правилами все печально, Snort принадлежит Cisco, были платные подписки или бесплатно с месячной задержкой, теперь только Community rules, в составе пакета, ну, и, можно писать свои)

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

Вообще, он ставится командой:

# apt install fail2ban

но, на текущий момент (май 2024) в 24-й ubuntu он не работает (надеюсь, починят) и приходится устанавливать его так:

# wget https://launchpad.net/ubuntu/+source/fail2ban/1.1.0-1/+build/28291332/+files/fail2ban_1.1.0-1_all.deb # dpkg -i fail2ban_1.1.0-1_all.deb 

В любом случае, конфигурация выглядит так:

# nano /etc/fail2ban/filter.d/snort_filter.conf  [Definition] failregex = .*Original Client IP: <HOST>.*  # nano /etc/fail2ban/jail.d/snort_jail.conf  [snort] enabled     = true bantime     = 300 filter      = snort_filter maxretry    = 3 logpath     = /var/log/auth.log action      = iptables-allports  # systemctl restart fail2ban.service

Вот тут я «забанил» сам себя и потерял history команд при подготовке статьи, так что лучше продолжать «атаки» с другого домашнего устройства, например с телефона 🙂

https://ip_адрес_виртульной_машины/root.exe

В журнале можно наблюдать реакцию fail2ban на «атаки»:

# tail -f /var/log/fail2ban.log

А также снять блокировку:

# fail2ban-client status snort # fail2ban-client set snort unbanip <IP>

Спасибо что дочитали, надеюсь было интересно, буду рад ответить на вопросы!


ссылка на оригинал статьи https://habr.com/ru/articles/813799/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *