Snort - Sieciowy System Wykrywania Włamań

Snort to bardzo silny sieciowy system wykrywania ataków (ang. Network Intrusion Detection System, NIDS), który daje szeroki zakres mechanizmów detekcji, mogących w czasie rzeczywistym dokonywać analizy ruchu i rejestrowania pakietów w sieciach opartych na protokołach IP/TCP/UDP/ICMP. Potrafi przeprowadzać analizę strumieni pakietów, wyszukiwać i dopasowywać podejrzane treści, a także wykrywać wiele ataków i anomalii, takich jak przepełnienia bufora, skanowanie portów typu stealth, ataki na usługi WWW, SMB, próby wykrywania systemu operacyjnego i wiele innych.

Wymagania

Przed instalacją Snorta warto zaopatrzyć się w bazę danych (w opisie wykorzystano MySQL) i serwer Apache z obsługą PHP. W bazie będą składowane logi, a za wygodny interfejs do przeglądania alarmów posłuży ACID (ang. Analysis Console for Intrusion Databases).

Instalacja Snorta i ACID

Gdy mamy już bazę danych i serwer WWW z PHP, instalujemy następujące pakiety.

poldek> install snort acid

Przed konfiguracja środowiska NIDS zakładamy dwie bazy, dla Snorta i dla archiwum alarmów.

# mysql -u mysql -p
Enter password:
mysql> create database snort_log;
Query OK, 1 row affected (0.01 sec)
mysql> create database snort_archive;
Query OK, 1 row affected (0.01 sec)
mysql> quit

Dodajemy tabele w taki sam sposób dla obu baz.

# gzip -d /usr/share/doc/snort-{wersja}/create_mysql.gz
# mysql -D snort_log -u mysql -p < /usr/share/doc/snort-{wersja}/create_mysql
# gzip -d /usr/share/doc/acid-{wersja}/create_acid_tbls_mysql.sql.gz
# mysql -D snort_log -u mysql -p < /usr/share/doc/acid-{wersja}/create_acid_tbls_mysql.sql

# mysql -D snort_archive -u mysql -p < /usr/share/doc/snort-{wersja}/create_mysql
# mysql -D snort_archive -u mysql -p < /usr/share/doc/acid-{wersja}/create_acid_tbls_mysql.sql

Następnie (najprościej przy użyciu popularnego narzędzia phpMyAdmin) tworzymy użytkownika i nadajemy mu prawa dla stworzonych baz.

Przechodzimy do edycji pliku /etc/acid_conf.php, w którym dodajemy parametry dla połączenia się z bazami.

[...]
/* Alert DB connection parameters */
[...]
$alert_dbname   = "snort_log";
$alert_host     = "localhost";
$alert_port     = "3306";
$alert_user     = "login";
$alert_password = "haslo";

/* Archive DB connection parameters */
$archive_dbname   = "snort_archive";
$archive_host     = "localhost";
$archive_port     = "3306";
$archive_user     = "login”;
$archive_password = "haslo";
[...]

Teraz strona z interfejsem jest dostępna pod adresem http://twoje_ip/acid. Oczywiście dla bezpieczeństwa zalecane jest zastosowanie protokołu SSL do komunikacji z zasobem i autoryzacji poprzez pakiet apache-mod_auth.

Snort zależnie od środowiska w jakim działa może generować dużą ilość zbędnych alertów, te bardziej istotne można przenosić do drugiej bazy za pomocą ACID, dla przejrzystości ogółu.

Konfiguracja Snorta

Do działania jako sieciowy system wykrywania włamań, Snort potrzebuję sprecyzowania zasad funkcjonowania całości w głównym pliku konfiguracyjnym snort.conf. W starszych wersjach systemu, wszystkie opcje, łącznie z regułami ataków znajdowały się w jednym pliku. Ciągła rozbudowa Snorta, rosnąca liczba sygnatur i ogólna funkcjonalność, wymusiła rozdzielenie niektórych części konfiguracyjnych, w tym reguł ataków. Przejrzystość i spójność snort.conf została przywrócona przy użyciu polecenia include, którym dołącza się odpowiednie zestawy sygnatur i inne części konfiguracyjne, np.:

include: ścieżka_do_pliku/nazwa

Bazy reguł charakteryzują się nazwą pliku z końcówką .rules, pierwszy człon nazwy zawiera rodzaj usługi lub typ ataku, którego dotyczy dany zestaw. Pozostałymi plikami konfiguracyjnymi są:

Pozostałymi plikami konfiguracyjnymi są:

Główny plik konfiguracyjny można podzielić na cztery sekcje. Pierwsza, odpowiedzialna jest za ustalanie zmiennych var, wykorzystywanych w składni reguł ataków.

Przyjmijmy że docelowo Snort ma monitorować dwie podsieci o adresach 192.168.1.0/24 i 192.168.2.0/24, jego pliki konfiguracyjne znajdują się bezpośrednio w katalogu /etc/snort, a regułki w /etc/snort/rules.

# Adres sieci lokalnej
var HOME_NET [192.168.1.0/24,192.168.2.0/24]
# Adres sieci zewnetrznej
var EXTERNAL_NET !$HOME_NET
# Lista adresow serwerow znajdujacych sie w strefie chronionej
var DNS_SERVERS $HOME_NET
var SMTP_SERVERS $HOME_NET
var HTTP_SERVERS $HOME_NET
var SQL_SERVERS $HOME_NET
var TELNET_SERVERS $HOME_NET
var SNMP_SERVERS $HOME_NET
# Lista portow
var HTTP_PORTS 80
var SHELLCODE_PORTS !80
var ORACLE_PORTS 1521
# Lista serwerow czat, komunikatorow
var AIM_SERVERS [64.12.24.0/24,64.12.25.0/24,64.12.26.14/24,64.12.28.0/24,]
# Scieszka do katalogu z regulami atakow
var RULE_PATH /etc/snort/rules

W tej samej sekcji znajduje się zestaw parametrów uruchomieniowych, zaczynających się od wyrażenia config (pełna ich lista znajduję się w dokumentacji):

# wybor interfejsu do nasłuchu (jeden demon Snorta moze obslugiwac tylko jeden
# interfejs sieciowy)
config interface: eth0

Druga część głównego pliku konfiguracyjnego, zawiera ustawienia preprocesorów. Parametry domyślne nie będą przedstawione w poniższym opisie. Kompletną listę opcji, można znaleźć w dokumentacji Snorta.
Oto przykłady ustawień preprocesorów:

Frag2:

# detect_state_problems – zwraca alarm przy pokrywaniu sie fragmentow.
preprocessor frag2: detect_state_problems

Stream4, Stream4_reassemble:

# disable_evasion_alerts – brak alarmow przy nakladaniu sie pakietow TCP,
# detect_scans – detektor prob cichego skanowania,
# detect_state_problems – detektor nienaturalnego zachowania pakietow.
preprocessor stream4: disable_evasion_alerts detect_scans detect_state_problems
# both – skladanie sesji TCP w obu kierunkach pomiedzy klientem i serwerem,
# ports – lista portow, na ktorych ma dzialac reasemblacja.
preprocessor stream4_reassemble: both ports [ 21 25 80 143 110 ]

Http_inspect:

# iis_unicode_map – wskazuje plik z kodowaniem unicode i wybiera standardowe.
preprocessor http_inspect: global is_unicode_map unicode.map 1252
# profile – wybor profilu ustawien dla serwerow typu iis, apacze i all.
preprocessor http_inspect_server: server adres_IP_serwera_MS_IIS \
    profile iis \
    ports { 80 }
preprocessor http_inspect_server: server adres_IP_serwera_Apache \
    profile apache \
    ports { 80 }

Powyższy przykład przedstawia możliwość profilowania ustawień dla poszczególnych serwerów, które podlegają ochronie. Serwery IIS i Apache, pracują w odmienny sposób, a zarazem posiadają inne słabe punkty wykorzystywane podczas ataków. Operacja dostosowania ustawień skupia mechanizmy ochronne na odpowiednich metodach ataków dla danego typu serwera bądź ich grupy w danej sieci objętej ochroną.

RPC_decode, Back Orfice, Telnet_decode, Arpspoof, Performance Monito:

# alert_fragments – wlacza alarm, przy fragmentowaniu pakietow RPC,
# Domyślne porty: 111 i 32771.
preprocessor rpc_decode: 111 32771 alert_fragments
preprocessor bo
preprocessor telnet_decode
preprocessor arpspoof
preprocessor arpspoof_detect_host: adresy_IP przypisane_do_nich_adresy_MAC
# console – wyswietlanie statystyk na ekranie,
# flow i events – statystyki badanego ruchu i ilosci dopasowanych regul,
# time – aktualizacja danych co 10s.
preprocessor perfmonitor: console flow events time 10

Flow i Flow-portscan:

# stats_interval – zapisywanie statystyk, 0 – wylaczone,
# hash – wybor metody mieszania.
preprocessor flow: stats_interval 0 hash 2
# server-watchnet – adresy IP, na ktorych flow bedzie prowadzic badania,
# server-learning-time – czas utrzymania punktow dla danego adresu IP,
# server-scanner-limit – ilosc zapytan decydujacych o przyznaniu statusu
#                        skanowania z danego adresu,
# src-ignore-net, dst-ignore-net – lista ignorowanych adresow docelowych
#                                  i zrodlowych.
preprocessor flow-portscan: \
        server-watchnet [xxx.xxx.xxx.xxx/xx] \
        server-learning-time 14400 \
        server-scanner-limit 10 \
        src-ignore-net [xxx.xxx.xxx.xxx/xx, xxx.xxx.xxx.xxx/xx] \
        dst-ignore-net [xxx.xxx.xxx.xxx/xx]

Trzecia sekcja snort.conf, zawiera metody konfiguracji modułów wyjściowych, czyli różnych sposobów logowania wyników i tzw. akcji reguł. Na potrzeby tego opisu wymieniony będzie tylko przykład logowania do bazy MySQL.

output database: alert, mysql, user=login password=haslo \ 
dbname=snort_log host=127.0.0.1

Za pomocą reguł akcji można tworzyć własne rodzaje reakcji na wykryte zdarzenie, np.:

ruletype czerwony_alarm
 {
     type log
     # zapis do demona syslogd, lokalnie
     output alert_syslog: LOG_ALER
 }
# Przykladowa regula:
czerwony_alarm $HOME_NET any -> $HOME_NET 6667 (msg:"Internal IRC Server";)

Czwarta, ostatnia część, głównego pliku konfiguracyjnego, zawiera odniesienia do zestawów reguł i wcześniej już opisanych plików, classification.config, reference.config, threshold.conf (przykład poniżej).

include classification.config
include reference.config

include $RULE_PATH/bad-traffic.rules
include $RULE_PATH/exploit.rules
include $RULE_PATH/telnet.rules
include $RULE_PATH/rpc.rules
include $RULE_PATH/dos.rules
(...)
# dodatkowy zestaw regul Bleeding Snort - http://www.bleedingsnort.com
include $RULE_PATH/bleeding.rules
include threshold.conf

Dostosowanie Snorta do swoich potrzeb obejmuje, obok konfiguracji preprocesorów przede wszystkim decyzje, jakie zbiory reguł mają być brane pod uwagę (czyli jakie pliki z regułami mają być dołączane za pomocą polecenia include). W środowisku, w którym wszystkie serwery WWW to Apache, reguły chroniące serwer IIS będą generowały zupełnie niepotrzebne alarmy. Jeśli nie udostępniamy FTP, reguły opisujące ataki na tę usługę będą tylko spowalniały pracę całego systemu. To sprawy oczywiste, jednak właściwe dostosowanie NIDS do swoich potrzeb wymaga wiele pracy. Dobranie odpowiednich dla danego środowiska reguł jest kluczowe dla działania całego systemu, duża ilość fałszywych alarmów nie tylko zużywa zasoby (każda z reguł musi być przecież przeanalizowana), ale może również bardzo skutecznie "zaciemnić" obraz, sprawiając, że prawdziwy atak może przejść niezauważony w zalewie informacji mało istotnych. Obecna baza sygnatur liczy sobie około 2500 reguł i jest praktycznie każdego dnia wzbogacana o nowe opisy ataków. Dla przybliżenia występujących w bazie kategorii sygnatur, opiszę jakiego rodzaju ataki wykrywają:

Aktualizacja reguł

Do aktualizacji sygnatur posłuży nam perlowy skrypt Oinkmaster. Ma on duże możliwości które pozwalają w prosty sposób zarządzać regułami Snorta. Wymagane pakiety do uruchomienia to: perl, perl-base, perl-modules i vixie-cron albo hc-cron .

Instalacja Oinkmaster

Ściągamy archiwum tar, rozpakowujemy, skrypt wgrywamy do katalogu /usr/local/bin, a konfig do /etc:

# wget --passive-ftp \
ftp://ftp.it.su.se/pub/users/andreas/oinkmaster/oinkmaster-1.0.tar.gz
# tar -zxvpf oinkmaster-1.0.tar.gz
# cp oinkmaster-1.0/oinkmaster.pl /usr/local/bin/
# cp oinkmaster-1.0/oinkmaster.conf /etc/

Operacja aktualizacji odbywa się po następującej sekwencji komend:

# /usr/local/bin/oinkmaster.pl -o /etc/snort/rules/

Dodanie innego źróła reguł:

# /usr/local/bin/oinkmaster.pl -o /etc/snort/rules/ -q -u \
http://www.bleedingsnort.com/bleeding.rules.tar.gz

Aby aktualizacja odbywała się automatycznie, w katalogu /etc/cron.daily tworzymy plik uprules.

# touch /etc/cron.daily/uprules
# chmod 700 /etc/cron.daily/uprules

I dodajemy do niego następującą zawartość, podając adres e-mail na który ma zostać wysłany raport z codziennej aktualizacji jeśli pojawia się coś nowego:

TMP=`mktemp /tmp/oinkmaster.XXXXXXXX` &&
(/usr/local/bin/oinkmaster.pl -o /etc/snort/rules/ -q > $TMP 2>&1;
if [ -s $TMP ]; then mail -s "Update Snort Rules" root@twoja_domena < $TMP; fi;
rm $TMP)

# dodatkowy zestaw regul Bleeding Snort - http://www.bleedingsnort.com
TMP=`mktemp /tmp/oinkmaster.XXXXXXXX` &&
(/usr/local/bin/oinkmaster.pl -o /etc/snort/rules/ -q -u \
http://www.bleedingsnort.com/bleeding.rules.tar.gz > $TMP 2>&1;
if [ -s $TMP ]; then mail -s "Update Bleeding Rules" root@twoja_domena < \
$TMP; fi; rm $TMP)

/etc/rc.d/init.d/snort restart

Warto przyjżeć się bliżej ciekawym funkcjonalnościom oinkmastera. W pliku konfiguracyjnym mamy możliwość wyłączania poszczególnych regułek po nr sid, dodawania do nich własnych modyfikacji itp. Wtedy jest pewność że po aktualizacji, nasze zmiany w plikach reguł nie będą nadpisywane.

Trochę teorii - Architektura Snorta

Snort jest logicznie podzielony na kilka komponentów, które współpracują ze sobą by wykrywać ataki i generować wyniki w odpowiednim formacie. Głównymi składnikami systemu są: dekoder pakietów (sniffer), preprocesory, silnik detekcji i moduł wyjściowy.

W swej najprostszej formie Snort może działać jako sniffer. Przechwytuje pakiety z warstwy łącza danych za pomocą biblioteki pcap. Rozpoznaje różne protokoły modelu OSI - Ethernet, 802.11, Token Ring oraz wiele protokołów działających w wyższych warstwach jak: IP, TCP, UDP i ICMP.
Surowe pakiety z warstwy łącza danych (np. ramki Ethernetowe) po zdekodowaniu wądrują do preprocesorów (warstwa transportowa), gdzie są testowane i w razie konieczności obrabiane na potrzeby silnika detekcji (warstwa sesji). Tam dokonywana jest analiza pakietów pod kątem zbioru zadanych reguł. Nastąpnie po wykryciu próby ataku bądź anomalii sieciowych, system przekazuje odpowiednie dane do modułu wyjściowego, który to decyduje o zapisaniu wyniku wykrycia w logach lub wszczęciu alarmu.

Tryby pracy

Snort umożliwia dużą swobodę konfiguracji, za pomocą wielu parametrów, które pozwalają kontrolować trzy podstawowe tryby pracy programu: sniffer, packet logger i network intrusion detection.

Preprocesory

Preprocesory zostały wprowadzone do Snorta w wersji 1.5. Pozwalają użytkownikom i programistom w prosty sposób na rozbudowę funkcjonalności całego systemu poprzez pisanie dodatkowych modułów (ang. plugins).

Preprocesory analizują pakiety przed wykorzystaniem ich przez silnik detekcji. W ten sposób zwiększają możliwości całego procesu wykrywania ataków sieciowych, wzbogacając go o zdolność składania (reasemblacji) pakietów, wykonywania specyficznych dla poszczególnych protokołów operacji (np. konwersja na ASCII znaków z URI zakodowanych szesnastkowo, usuwanie ciągów binarnych z sesji FTP czy Telnet, normalizacja żądań RPC), jak i wykrywania niezgodności z tymi protokołami.

Poniżej pozwolę sobie pokrótce opisać standardowy zestaw preprocesorów wchodzących w skład darmowej dystrybucji Snorta w wersji 2.1.3.

Zarówno preprocesory, jak i mechanizm detekcji mogą zareagować w określony sposób. Po wychwyceniu pakietów, spełniających warunki nadane konfiguracją preprocesorów lub regułami, podejmowane jest odpowiednie działanie (np. zapisanie pakietów bądź alarm).

Moduł sygnatur

Gółwny mechanizm systemu detekcji zagrożeń polega na dopasowaniu przetworzonych pakietów i ich zrekonstruowanych strumieni z bazą sygnatur. System detekcji porównuje cechy pakietu ze zbiorem reguł. Po dopasowaniu, zostaje podjęta odpowiednia akcja. Do porównywalnych cech należą atrybuty gółwne - adresy, porty źródłowe i docelowe oraz opcje pomocnicze: flagi TCP identyfikujące np. żądania związane z WWW, różne typy pakietów ICMP, opcje IP czy wreszcie sama treść pakietu. Na razie w gółwnej części reguł możliwe jest śledzenie protokołów IP, ICMP, TCP i UDP. Autorzy przewidują rozszerzenie Snorta o następne protokoły sieciowe, m.in. IPX, GRE, czy protokoły wymiany informacji między routerami - RIP, OSPF oraz IGRP.

Reguły identyfikowania ataku pozwalają na podjęcie pięciu rodzajów akcji: przepuszczenia pakietu (pass), zapisania informacji do dziennika (log), ogłoszenia alarmu (alert), alarmowania i podjęcia do działania innej dynamicznej reguły (activate) i pozostanie w spoczynku do czasu aktywowania przez regułę activate, po czym działanie jako reguła log (dynamic).

Sygnatury Snorta zazwyczaj składają się z dwóch głównych sekcji - nagłówka i ciała (treści). Nagłówek określa m.in., jaką akcję należy podjąć po przypasowaniu reguły, informacje o wykorzystanym protokole, adresy bądź porty źródłowe i docelowe. Ciało reguły pozwala rozwinąć informacje zawarte w nagłówku, tu także podaje sią treść wzbudzanych alarmów i różnego rodzaju informacje dodatkowe (np. odniesienia do bazy z opisami danego naruszenia, tzw. referencje - Bugtraq, CERT czy CVE).

Najprostsze sygnatury obejmują wskazanie akcji, protokołu, kierunku, adresów i portów będących przedmiotem obserwacji, jak np. poniższa reguła, stanowiąca reakcję na próbę skorzystania z usługi pop3 (port 110):

log tcp any any -> 192.168.1.0/24 110

W sygnaturach można umieszczać zmienne zdefiniowane jako adresy sieci (wg CIDR) lub porty zapisane w pliku konfiguracyjnym snort.conf:

log tcp $EXTERNAL_NET -> $HOME_NET 110

W podanych powyżej regułach wykorzystany był jednokierunkowy operator "->". Język sygnatur umożliwia zadeklarowanie reguły, który dopasuje pakiety poruszające się w obu stronach operatorem dwukierunkowym "<>", np.:

alert tcp any any <> $HOME_NET 23

Do zasadniczej części reguły można dodać ograniczone okrągłymi nawiasami pole opcjonalne (tzw. ciało), zawierające definicję bardziej złożonych i wyrafinowanych działań związanych z przejęciem danego pakietu. Użytkownik może także sformułować własny komunikat, np.:

log tcp $EXTERNAL_NET -> $HOME_NET 110 ("msg: Proba polaczenia z pop3";)

Podjęte działania nie muszą być ograniczone do pojedynczej czynności. Średnik separuje deklaracje poszczególnych działań, jak w poniższym przykładzie, w którym opcją content testowana jest treść przesyłanego strumienia TCP, a w razie odnotowania podejrzanego ciągu znaków generowany jest odpowiedni komunikat:

alert tcp any any -> 192.168.1.0/24 80 (content: "/cgi-bin/phf"; msg: "PHF probe!";)

Opcji content można użyć nawet kilka razy w jednej regule. Pozwala to na wyszukiwanie wielu różnych ciągów znaków w obrębie przesyłanych treści.

Warto nadmienić, iż do przeszukania treści pakietów i reasemblowanych strumieni używany jest obecnie najbardziej efektywny algorytm - Boyera-Moore'a, którego wydajność rośnie wraz z długością poszukiwanych ciągów. Możliwość rekonstrukcji całych strumieni transmisji TCP, wglądu w warstwę aplikacyjną i efektywne wyszukiwanie treści pozwala na walkę przy użyciu Snorta również z zainfekowanymi załącznikami elektronicznych listów. Oprócz przeszukiwania treści pakietów możemy badać pod różnymi kątami ich nagłówki, m.in. pola i kody ICMP, pole TTL, rozmiary fragmentacji czy numery sekwencji.

Bardzo silną konstrukcją w regułach Snorta jest możliwość aktywowania kolejnych reguł po pierwszym dopasowaniu. Konstrukcja ta nosi nazwę activate/dynamic rules i wygląda w następujący sposób:

activate tcp any any -> $HOME_NET 143 (flags: PA; content: "|E8C0FFFFFF|bin|;activates: 1; msg: "IMAP buffer overflow!";)
dynamic tcp any any -> $HOME_NET 143 (activated_by: 1; count: 50;)

Opcje activates i activated_by wiążą reguły activate i dynamic. W powyższym przykładzie wykrycie ataku typu buffer overflow na serwer IMAP powoduje uruchomienie kolejnej, dynamicznej reguły, która zbiera treść następnych 50 pakietów (opcja count) w celu późniejszej analizy. Druga opcja w reguły dynamicznej jest obligatoryjna - reguła zawierająca wyłącznie opcję dowiązania do innej, macierzystej konstrukcji jest bezużyteczna.

Następne godne uwagi parametry, to resp i react wspierają mechanizm elastycznego reagowania na atak. Opcja resp może doprowadzić do zerwania połączenia, np. poprzez wysłanie do atakującego komunikatu ICMP o niedostępności trasy do zaatakowanego komputera, natomiast react służy do blokowania dostępu do usług związanych z WWW.

Ciekawe projekty

uho(at)xhost.one.pl