Archivi tag: nids

CentOS 6: realizzare un network intrusion detection system open source – Parte 3

Dopo aver installato e configurato snort, barnyard2, pulledpork e MySQL (vedi qui e qui), ora vedremo come installare l’interfaccia Web del nostro sistema NIDS, ovvero Snorby.

Poichè tale interfaccia si basa su Ruby, è necessario predisporre il nostro sistema per il supporto del linguaggio di scripting in questione.

snorby-dashboard

Preparazione della macchina

Per prima cosa installiamo i software prerequisiti, mediante i comandi:

yum -y groupinstall "Development Tools"

yum install -y openssl-devel readline-devel libxml2-devel libxslt-devel mysql mysql-devel mysql-libs mysql-server urw-fonts libX11-devel libXext-devel qconf fontconfig-devel libXrender-devel unzip

yum -y install xz urw-fonts libXext openssl-devel libXrender

Successivamente, scarichiamo ed installiamo ImageMagick , per la creazione di immagini bitmap, e wkhtmltopdf, per la conversione delle pagine HTML in PDF (funzionalità indispensabile durante la generazione dei report):

cd /usr/local/src

wget ftp://ftp.fifi.org/pub/ImageMagick/ImageMagick-6.8.9-6.tar.gz

tar -xvf ImageMagick-6.8.9-6.tar.gz

cd ImageMagick-6.8.9-6

./configure

make

make install

ldconfig 

cd ..

wget http://sourceforge.net/projects/wkhtmltopdf/files/0.12.1/wkhtmltox-0.12.1_linux-centos6-amd64.rpm/download

rpm -Uvh wkhtmltox-0.12.1_linux-centos6-amd64.rpm

Adesso scarichiamo rvm, attraverso il quale sarà possibile installare la versione di Ruby compatibile con Snorby (ovvero la 1.9.3, che, purtroppo, è ormai obsoleta e non più mantenuta):

curl -L get.rvm.io | bash -s stable

Installiamo dunque Ruby e facciamo in modo che il sistema utilizzi la versione 1.9.3 come default:

rvm install 1.9.3

rvm use --default 1.9.3

Ora, utilizzando il packet manager di Ruby (ovvero gem), procediamo con l’installazione di Rails (il framework) e di passenger (necessario per integrare Snorby e Apache):

gem install rails

gem install passenger

passenger-install-apache2-module

Installiamo alcuni pacchetti prerequisiti:

gem install devise_cas_authenticatable -v '1.1.0'

e

gem install bundler

In particolare, quest’ultimo si occupa di gestire le dipendenze tra i gem (ed è il software responsabile della creazione dei file Gemfile e Gemfile.lock).

Installazione e configurazione di Snorby

Creiamo la directory nella quale ospitare Snorby:

mkdir -p /var/www/html/snorby

e scarichiamo l’applicazione vera e propria:

cd /var/www/html/snorby

wget -O snorby.zip --no-check-certificate https://github.com/Snorby/snorby/archive/master.zip

Scompattiamo l’archivio, posizioniamoci nella directory snorby-master e spostiamone il contenuto all’interno di /var/www/html/snorby:

unzip snorby.zip

cd snorby-master/

mv * ../

Modifichiamo ora il contenuto del file Gemfile, sostituendo le direttive di default per rake, json e devise_cas_authenticatable con le seguenti:

gem 'rake', '0.9.2.2'
gem 'json', '~> 1.8.3'
gem 'thin'

gem 'devise_cas_authenticatable',  '~> 1.1.0'

Inoltre, è necessario inserire la direttiva gem ‘thin’ subito dopo gem ‘json’, commentando quella dopo gem “letter_open”:

gem 'json', '~> 1.8.3'
gem 'thin'

group(:development) do
     gem "letter_opener"
   # gem 'thin'

Discorso simile vale per il file Gemfile.lock, in cui bisogna modificare le direttive rake e json nel seguente modo:

rake (0.9.2.2)

json (1.8.3)

Lanciamo il comando bundle install in modo da installare i pacchetti gem (con le relative dipendenze) definiti all’interno del Gemfile precedentemente editato:

bundle install

Eliminiamo la dir snorby-master (ormai vuota) e passiamo alla configurazione di Snorby:

rm -rf snorby-master/

cd config

cp snorby_config.yml.example snorby_config.yml

nano snorby_config.yml

definendo la giusta timezone:

time_zone: Europe/Rome

A questo punto possiamo configurare la connessione al database, editando il file config/database.yml:

cd ..

cp config/database.yml.example config/database.yml

nano config/database.yml

il cui contenuto sarà simile al seguente:

# Snorby Database Configuration
#
# Please set your database password/user below
# NOTE: Indentation is important.
#
snorby: &snorby
  adapter: mysql
  username: vostrouser
  password: "vostrapassword" # Example: password: "s3cr3tsauce"
  host: localhost

development:
  database: snorby
  <<: *snorby

test:
  database: snorby
  <<: *snorby

production:
  database: snorby

Avviamo l’applicazione (con finalità di test), mediante i comandi:

rake snorby:setup

rails server thin -e production

da lanciare all’interno della dir /var/www/html/snorby ed il cui output dovrebbe essere simile al seguente:

=> Booting Thin
=> Rails 3.1.12 application starting in production on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on 0.0.0.0:3000, CTRL+C to stop

http://ip:3000/users/login

Provando ora a connetterci (con il nostro browser) a http://ip:3000/users/login dovremmo riuscire a visualizzare l’interfaccia di Snorby (con il relativo form per il login, dove l’email di default è snorby@example.com e la password è semplicemente snorby).

Integrazione tra Snorby e Apache

Come già affermato in precedenza, il modulo di Apache che consente al nostro server Web di interfacciarsi con le applicazioni scritte in Ruby prende il nome di passenger.

Per prima cosa occorre dunque configurare il suddetto modulo:

nano /etc/httpd/conf.d/mod_passenger.conf

il cui contenuto dovrà essere:

LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.3-p551/gems/passenger-5.0.16/buildout/apache2/mod_passenger.so

PassengerRoot /usr/local/rvm/gems/ruby-1.9.3-p551/gems/passenger-5.0.16
PassengerDefaultRuby /usr/local/rvm/gems/ruby-1.9.3-p551/wrappers/ruby

Infine, modifichiamo il file di configurazione di Apache (/etc/httpd/conf/httpd.conf), creando un virtual host opportuno (in ascolto sulla porta TCP 82):

Listen 82

<VirtualHost *:82>
     Servername vostroserver.vostrodominio.com
     DocumentRoot /var/www/html/snorby/public
     <Directory /var/www/html/snorby/public>
        Order deny,allow
        Allow from all
        Options -MultiViews
        AuthName "Snorby Access"
        AuthType Basic
        AuthUserFile /etc/snorby/passwd
        Require valid-user
    </Directory>
</VirtualHost>

Tale virtual host richiede l’autentica HTTP, ergo occorre creare il file in cui verranno salvate le coppie username/password da utilizzare:

mkdir -p /etc/snorby

htpasswd -c /etc/snorby/passwd vostroutente

Infine, riavviamo Apache:

service httpd reload

ed abbiamo finito.

Alla prossima.

CentOS 6: realizzare un network intrusion detection system open source – Parte 2

In questo post ho mostrato come configurare il software che funge da sensore, ovvero snort. Adesso vedremo come installare e configurare pulledpork (che si occuperà dell’aggiornamento delle firme) e barnyard2 (per il salvataggio degli allarmi all’interno di un DB).

Barnyard2Installazione e configurazione di pulledpork

Per prima cosa occorre installare i prerequisiti, ovvero perl-libwww-perl perl-Crypt-SSLeay e perl-Archive-Tar:

yum -y install perl-libwww-perl perl-Crypt-SSLeay perl-Archive-Tar

Posizioniamoci nella dir /usr/local/src  e scarichiamo l’applicativo in questione (scritto in Perl):

wget https://pulledpork.googlecode.com/files/pulledpork-0.7.0.tar.gz

per poi scompattare l’archivio, rendere lo scrip eseguibile e copiarlo all’interno di /usr/sbin (assegnandogli i giusti privilegi):

tar -xvf pulledpork-0.7.0.tar.gz
cd pulledpork-0.7.0
chmod +x pulledpork.pl
cp pulledpork.pl /usr/sbin
chmod 755 /usr/sbin/pulledpork.pl

A questo punto possiamo copiare i file *.conf (presenti nella directory etc) all’interno di /etc/snort, con il successivo editing dei permessi:

cd etc
cp * /etc/snort
chown -R snort:snort /etc/snort

Ora modifichiamo il contenuto del file /etc/snort/pulledpork.conf, apportando le seguenti modifiche:

snort_path=/usr/sbin/snort
config_path=/etc/snort/snort.conf
distro=Centos-5-4
rule_path=/etc/snort/rules/snort.rules
out_path=/etc/snort/rules/
sid_msg=/etc/snort/sid-msg.map
black_list=/etc/snort/rules/black_list.rules
#IPRVersion=/usr/local/etc/snort/rules/iplists
enablesid=/etc/snort/enablesid.conf
dropsid=/etc/snort/dropsid.conf
disablesid=/etc/snort/disablesid.conf
modifysid=/etc/snort/modifysid.conf

rule_url=https://www.snort.org/reg-rules/|snortrules-snapshot-2975.tar.gz|<vostro oinkcode>
rule_url=https://s3.amazonaws.com/snort-org/www/rules/community/|community-rules.tar.gz|Community
rule_url=http://labs.snort.org/feeds/ip-filter.blf|IPBLACKLIST|open
rule_url=https://www.snort.org/reg-rules/|opensource.gz|<vostro oinkcode>

Da notare che ho commentato la direttiva IPRVersion ed ho scelto un nome specifico per le blacklist (ovvero black_list.rules), in quando devono essere differenziate da quelle utilizzate da snort (reputation preprocessor). Per la precisione, il file black_list.rules non è altro che una lista piatta di indirizzi IP, a differenza del file blacklist.rules che possiede il tipico formato delle regole di snort (ad esempio alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS).

Testiamo adesso la configurazione di pulledpork mediante il comando:

pulledpork.pl -vv -c /etc/snort/pulledpork.conf -T -l

e se il relativo output contiene la stringa:

Fly Piggy Fly!

vuol dire che il suddetto applicativo sta funzionando correttamente. Creaiamo un task su crontab per eseguire l’update delle firme ogni notte:

nano /etc/crontab

il cui contenuto dovrà essere:

00 04 * * * root /usr/sbin/pulledpork.pl -c /etc/snort/pulledpork.conf && /sbin/service snortd restart

e passiamo alla configurazione di barnyard2.

Installazione e configurazione di barnyard2

Prima di cominciare occorre fare una premessa: il file di configurazione che daremo in pasto a barnyard2 può riferirsi ad una sola interfaccia. Ciò significa che dovremo creare un file di configurazione specifico per ciascuna interfaccia su cui i sensori (le istanze di snort) sono in ascolto, in modo tale che il loro output possa essere parsato (in modo indipendente) dalle due istanze distinte di barnyard2.

Come al solito, il primo step consiste nell’installazione del software necessario per la compilazione del suddetto applicativo:

yum install libtool

e successivamente, dopo esserci posizionati nella directory /usr/local/src, possiamo scaricare i sorgenti:

cd /usr/local/src
git clone git://github.com/firnsy/barnyard2.git

Compiliamo ed installiamo:

cd barnyard2
./autogen.sh
./configure --with-mysql --with-mysql-libraries=/usr/lib64/mysql/
make
make install

copiamo il file di configurazione di barnyard2 all’interno della directory /etc/snort

cp etc/barnyard2.conf /etc/snort

e modifichiamolo in base alle nostre esigenze:

config logdir: /var/log/snort
config interface:  eth0
config daemon
input unified2
output alert_full
config waldo_file: /var/log/snort/eth0/barnyard2-log.waldo
output log_tcpdump: tcpdump.log
output database: log, mysql, user=<vostrouser> password=<vostrapassword> dbname=snorby host=localhost

copiamo il suddetto file in barnyard2-eth0.conf ed in barnyard2-eth1.conf:

cp /etc/snort/barnyard2.conf /etc/snort/barnyard2-eth0.conf

cp /etc/snort/barnyard2.conf /etc/snort/barnyard2-eth1.conf

Modifichiamo quest’ultimo sostituendo le diciture:

config interface:  eth0

config waldo_file: /var/log/snort/eth0/barnyard2-log.waldo

con:

config interface:  eth1

config waldo_file: /var/log/snort/eth1/barnyard2-log.wald

Inoltre, per fare in modo che le due istanze di barnyard2 vengano avviate come “demone”, ho modificato il file di startup presente nella dir rpm, dopo averlo copiato in /etc/init.d ed averlo reso eseguibile:

cp rpm/barnyard2 /etc/init.d
chmod +x /etc/init.d/barnyard2

Di seguito riporto il contenuto del suddetto file, in cui sono presenti le modifiche da me effettuate:

#!/bin/sh
#
# Init file for Barnyard2
#
#
# chkconfig: 2345 60 60
# description:  Barnyard2 is an output processor for snort.
#
# processname: barnyard2
# config: /etc/sysconfig/barnyard2
# config: /etc/snort/barnyard.conf
# pidfile: /var/lock/subsys/barnyard2.pid

source /etc/rc.d/init.d/functions
source /etc/sysconfig/network

### Check that networking is up.
[ "${NETWORKING}" == "no" ] && exit 0

[ -x /usr/sbin/snort ] || exit 1
[ -r /etc/snort/snort.conf ] || exit 1

### Default variables
SYSCONFIG="/etc/sysconfig/barnyard2"

### Read configuration
[ -r "$SYSCONFIG" ] && source "$SYSCONFIG"

RETVAL=0
prog="barnyard2"
desc="Snort Output Processor"

start() {
        echo -n $"Starting $desc ($prog): "
        for INT in $INTERFACES; do
                echo " "
                echo "binding over $INT..."
                ARCHIVEDIR="$SNORTDIR/$INT/archive"
                WALDO_FILE="$SNORTDIR/$INT/barnyard2.waldo"
                if [ $INT == 'eth0' ];then
                BARNYARD_OPTS="-D -c $CONF1 -d $SNORTDIR/${INT} -w $WALDO_FILE -l $SNORTDIR/${INT} -a $ARCHIVEDIR -f $LOG_FILE $EXTRA_ARGS"
                elif [ $INT == 'eth1' ];then
                BARNYARD_OPTS="-D -c $CONF2 -d $SNORTDIR/${INT} -w $WALDO_FILE -l $SNORTDIR/${INT} -a $ARCHIVEDIR -f $LOG_FILE $EXTRA_ARGS"
                fi
                daemon $prog $BARNYARD_OPTS
        done
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
        return $RETVAL
}

stop() {
        echo -n $"Shutting down $desc ($prog): "
        killproc $prog
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f /var/run/barnyard2*
        return $RETVAL
}

restart() {
        stop
        start
}

reload() {
        echo -n $"Reloading $desc ($prog): "
        killproc $prog -HUP
        RETVAL=$?
        echo
        return $RETVAL
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  reload)
        reload
        ;;
  condrestart)
        [ -e /var/lock/subsys/$prog ] && restart
        RETVAL=$?
        ;;
  status)
        status $prog
        RETVAL=$?
        ;;
  dump)
        dump
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|reload|condrestart|status|dump}"
        RETVAL=1
esac

exit $RETVAL

Il contenuto del file /etc/sysconfig/barnyard2 (in cui sono contenute le opzioni di avvio del demone) è, invece, il seguente:

LOG_FILE="snort.log"
SNORTDIR="/var/log/snort"
INTERFACES="eth0 eth1"
PIDPATH="/var/run"
CONF1=/etc/snort/barnyard2-eth0.conf
CONF2=/etc/snort/barnyard2-eth1.conf
EXTRA_ARGS="--pid-path /var/run"

Creiamo i file con estenzione *.waldo:

touch /var/log/snort/eth0/barnyard2-log.waldo

touch /var/log/snort/eth1/barnyard2-log.waldo

e facciamo in modo che il suddetto demone venga avviato in modo automatico dopo ogni riavvio della macchina:

chkconfig --add barnyard2

chkconfig barnyard2 on

Creaiamo ora il DB snorby (in cui barnyard2 dovrà salvare gli allarmi generati da snort) attraverso l’interfaccia a linea di comando di MySQL. I comandi da lanciare sono i seguenti:

create schema snorby;
grant all on snorby.* to vostrouser@localhost;
set password for vostrouser@localhost=password('vostrapassword');
use snorby;
source /usr/local/src/barnyard2/schemas/create_mysql
flush privileges;
exit

Prima di avviare il suddetto demone, occorre verificare che la sua priorità di avvio minore rispetto a quella di MySQL (valori bassi corrispondono a priorità alte). Infatti, in caso contrario, barnyard2 tenterà di parlare (via file mysql.sock) con il DBMS in questione, cosa impossibile nel caso in cui MySQL non sia ancora avviato (restituendoci, molto banalmente, l’errore file not found). In particolare, all’interno del codice associato al demone barnyard2 (da me modificato), è presente una priorità di avvio pari a 60 (definita tramite la direttiva chkconfig), mentre, a titolo di cronaca, la priorità di avvio relativa al demone mysqld è pari a 49.

Verifichiamo che tutto funzioni correttamente mediante i comandi:

barnyard2 -c /etc/snort/barnyard2-eth0.conf -d /var/log/snort/eth0 -f snort.log -w /var/log/snort/barnyard2-log.waldo -D

e

barnyard2 -c /etc/snort/barnyard2-eth1.conf -d /var/log/snort/eth1 -f snort.log -w /var/log/snort/barnyard2-log.waldo -D

per poi avviare il demone vero e proprio:

service barnyard2 start

A demone avviato, come ulteriore verifica, possiamo collegarci al DB snorby e lanciare la query:

select count(*) from events;

e se il valore restituito è > 0 vuol dire che barnyard2 e snort stanno operando correttamente.

Per ora è tutto. Nel prossimo post vedremo come installare e configurare Snorby (la Web GUI).

CentOS 6: realizzare un network intrusion detection system open source – Parte 1

Premessa

A differenza delle numerose guide cooked e dei vari howto che si possono trovare in rete, questo post (primo di una serie di 3), ha come scopo quello di illustrare in modo esaustivo i vari passi necessari per la realizzazione di una sistema NIDS.

Un po’ di teoria

Esistono diverse metodologie per difendere l’infrastruttura IT dai cyber attacchi, e, tutto sommato, le si può riassumere in 2 macro categorie, ovvero quelle attive e quelli passive. Per strategia difensiva attiva basti pensare ad un firewall, ad un antivirus oppure ad un IPS (Intrusion Preventetion System). Per contro, un tipico esempio di strategia difensiva di tipo passivo è rappresentato dai sistemi IDS (Intrusion Detection System), i quali possono agire localmente sulla macchina interessata (in tal caso parliamo di HIDS, ovvero Host IDS), oppure a livello di rete (in questo caso parliamo di NIDS, ovvero Network IDS).

I sistemi NIDS (detti anche sonde o sensori), non fanno altro che analizzare il traffico del segmento di rete a cui sono collegati (DMZ, LAN, Outside), alla ricerca di eventuali tentativi di attacco.

Solitamente, essi non vengono posizionati inline (come invece avviene per i sistemi IPS), ma sono collegati ad una porta dello switch configurata in mirror (monitor/span), sulla quale viene inoltrata una replica esatta di tutto il traffico passante per lo switch in questione. In questo modo un eventuale sovraccarico del sensore non comporterà automaticamente un rallentamento della rete in termini di throughput.

Topoligia

Poichè la rete sulla quale ho configurato il sistema NIDS è dotata di un firewall *nix che filtra tutto il traffico in ingresso ed in uscita, per questioni di budget e di praticità, ho ritenuto opportuno installare la sonda sulla macchina in questione. Va da se che l’analisi preventiva del carico computazionale a cui era soggetto il firewall ha restituito valori di overhead davvero irrisori, dunque l’installazione della sonda non ha comportato grossi cambiamenti in termini prestazionali.

NIDS

Ingredienti

Il software che fungerà da sensore prende il nome di snort. Inoltre, per aggiornare in modo automatico le signature/pattern degli attacchi verrà utilizzato pulledpork (a tutti gli effetti il successore di oinkmaster), mentre per convertire in formato SQL e salvare gli alert generati da snort all’interno di un DB (MySQL) verrà utilizzato barnyard2. Infine, verrà installata sulla macchina ospite un’interfaccia Web (GUI) scritta in Ruby ed accessibile tramite Apache, dalla quale poter estrapolare gli allarmi con le relative statistiche,  il cui nome è snorby (SNORt ruBY).

Occorre precisare che MySQL (DBMS) ed Apache (server Web) sono già installati sulla macchina ospite.

Installazione e configurazione di snort

Tale attività si divide in 3 step:

1) l’installazione dei software prerequisiti;

2) l’installazione delle librerie daq;

3) l’installazione e la configurazione di snort.

I software prerequisiti sono bison, flex, libpcap e libdnet e li si può installare utilizzando il packet manager di casa CentOS/Red Hat, ovvero yum:

yum install bison flex libpcap libpcap-devel libdnet libdnet-devel

Posizioniamoci nella directory /usr/local/src per poi scaricare, compilare ed installare le librerie daq (le quali servono a reindirizzare il network I/O ai software di “cattura” veri e propri, quali, ad esempio, PCAP, AFPACKET e simili):

wget https://www.snort.org/downloads/snort/daq-2.0.6.tar.gz
tar -xvf daq-2.0.6.tar.gz
cd daq-2.0.6
./configure
make
make install
ldconfig
cd ..

A questo punto possiamo scaricare ed installare snort:

wget https://www.snort.org/downloads/snort/snort-2.9.7.5.tar.gz
tar -xvf snort-2.9.7.5.tar.gz
cd snort-2.9.7.5
./configure
make
make install

Ad installazione completata creiamo utente e gruppo per il suddetto applicativo:

groupadd snort
useradd snort -g snort -s /sbin/nologin

per poi creare la directory su cui salvare i file di configurazione e le regole per la rilevazione delle intrusioni:

mkdir -p /etc/snort
mkdir -p /etc/snort/rules
cd etc
cp -R * /etc/snort
cd ..

Inoltre, scarichiamo le regole vere e proprie e salviamole all’interno della dir /etc/snort/rules:

wget https://www.snort.org/downloads/community/community-rules.tar.gz
tar -xvf community-rules.tar.gz
cd community-rules
cp * /etc/snort/rules
wget https://www.snort.org/downloads/registered/snortrules-snapshot-2975.tar.gz?oinkcode=<vostro oinkcode ricavabile dalla pagina Web di snort, previa registrazione>
tar -xvf nortrules-snapshot-2975.tar.gz
cd snortrules-snapshot-2975
cp -R preproc_rules/ /etc/snort/rules
cp -R so_rules/ /etc/snort/rules
cd rules
cp * /etc/snort/rules

Assegniamo il giusto owner alla directory /etc/snort:

chown snort:snort -R /etc/snort

e concentriamoci sulle dynamic rules (con relative librerie):

mkdir -p /usr/local/lib/snort_dynamicrules
chown -R snort:snort /usr/local/lib/snort_dynamicrules
cp /usr/local/src/so_rules/precompiled/RHEL-6-0/x86-64/2.9.7.5 /usr/local/lib/snort_dynamicrules
chmod -R 700 /usr/local/lib/snort_dynamicrules

Ora passiamo alla configurazione di snort:

nano /etc/snort/snort.conf

nella quale occorre definire le reti locali (HOME_NET), le reti esterne (EXTERNAL_NET), il pathname delle regole utilizzate da snort e quello delle whitelist/blacklist (basate sulla reputazione). Inoltre, bisogna definire il tipo di output generato da snort (il quale dovrà essere interpretabile da barnyard2).

Ecco uno stralcio delle modifiche apportate al file di configurazione di snort:

ipvar HOME_NET [192.168.1.0,192.168.12.0]
ipvar EXTERNAL_NET !$HOME_NET

var RULE_PATH /etc/snort/rules
var SO_RULE_PATH /etc/snort/rules/so_rules
var PREPROC_RULE_PATH /etc/snort/rules/preproc_rules

var WHITE_LIST_PATH /etc/snort/rules
var BLACK_LIST_PATH /etc/snort/rules

# Reputation preprocessor. For more information see README.reputation
preprocessor reputation: \
   memcap 500, \
   priority whitelist, \
   nested_ip inner, \
#   whitelist $WHITE_LIST_PATH/white_list.rules, \
   blacklist $BLACK_LIST_PATH/black_list.rules

output unified2: filename snort.log, limit 128

Creiamo la directory in cui snort dovrà salvare i log e gli allarmi, assegnandole il giusto owner:

mkdir -p /var/log/snort/
chown snort:snort /var/log/snort/

Infine, testiamo la configurazione di snort, lanciando il comando:

snort -T -i <interface-name> -u snort -g snort -c /etc/snort/snort.conf

il cui output (se non vi sono errori) dovrà contenere la seguente stringa:

Snort successfully validated the configuration!

Eseguire snort come demone

Per fare in modo che snort venga eseguito sulla macchina ospite come demone, occorre, prima di tutto, configurare le opzioni di avvio (definendole all’interno del file /etc/sysconfig/snort):

nano /etc/sysconfig/snort

il cui contenuto dovrà essere simile al seguente:

# /etc/sysconfig/snort
# $Id$

# All of these options with the exception of -c, which tells Snort where
# the configuration file is, may be specified in that configuration file as
# well as the command line. Both the command line and config file options
# are listed here for reference.

#### General Configuration

# What interface should snort listen on?  [Pick only 1 of the next 3!]
# This is -i {interface} on the command line
# This is the snort.conf config interface: {interface} directive
#INTERFACE=eth0
#
# The following two options are not directly supported on the command line
# or in the conf file and assume the same Snort configuration for all
# instances
#
# To listen on all interfaces use this:
INTERFACE=ALL
#
# To listen only on given interfaces use this:
#INTERFACE="eth1 eth2 eth3 eth4 eth5"

# Where is Snort's configuration file?
# -c {/path/to/snort.conf}
CONF=/etc/snort/snort.conf

# What user and group should Snort drop to after starting? This user and
# group should have very few privileges.
# -u {user} -g {group}
# config set_uid: user
# config set_gid: group
USER=snort
GROUP=snort

# Should Snort change the order in which the rules are applied to packets.
# Instead of being applied in the standard Alert->Pass->Log order, this will
# apply them in Pass->Alert->Log order.
# -o
# config order: {actions in order}
# e.g. config order: log alert pass activation dynamic suspicious redalert
PASS_FIRST=0

#### Logging & Alerting

# NOTE: NO_PACKET_LOG and BINARY_LOG, ALERTMODE, etc. are mutually
# exclusive. Use either NO_PACKET_LOG or any/all of the other logging
# options. But the more logging options use you, the slower Snort will run.

# Where should Snort log?
#
#-l {/path/to/logdir}
# config logdir: {/path/to/logdir}
LOGDIR=/var/log/snort

# config basename:
BASENAME=snort.log

# How should Snort alert? Valid alert modes include fast, full, none, and
# unsock.  Fast writes alerts to the default "alert" file in a single-line,
# syslog style alert message.  Full writes the alert to the "alert" file
# with the full decoded header as well as the alert message.  None turns off
# alerting. Unsock is an experimental mode that sends the alert information
# out over a UNIX socket to another process that attaches to that socket.
# -A {alert-mode}
# output alert_{type}: {options}
#ALERTMODE=full

# Should Snort dump the application layer data when displaying packets in
# verbose or packet logging mode.
# -d
# config dump_payload
DUMP_APP=1

# Should Snort keep binary (AKA pcap, AKA tcpdump) logs also? This is
# recommended as it provides very useful information for investigations.
# -b
# output log_tcpdump: {log name}
#BINARY_LOG=1

# Should Snort turn off packet logging?  The program still generates
# alerts normally.
# -N
# config nolog
NO_PACKET_LOG=0

# Print out the receiving interface name in alerts.
# -I
# config alert_with_interface_name
PRINT_INTERFACE=0

# When dumping the stats, what log file should we look in
SYSLOG=/var/log/messages

# When dumping the stats, how long to wait to make sure that syslog can
# flush data to disk
SECS=5

# To add a BPF filter to the command line uncomment the following variable
# syntax corresponds to tcpdump(8)
#BPF="not host 192.168.1.1"

# To use an external BPF filter file uncomment the following variable
# syntax corresponds to tcpdump(8)
# -F {/path/to/bpf_file}
# config bpf_file: /path/to/bpf_file
#BPFFILE=/etc/snort/bpf_file

a tal proposito, occorre precisare che è necessario commentare le direttive ALERTMODE e BINARY_LOG, altrimenti barnyard2 non sarà in grado di inserire gli allarmi all’interno del database.

Inoltre, poichè il sensore è posizionato inline, esso si trova in ascolto su tutte le interfacce della macchina (INTERFACE=ALL).

Di seguito riporto lo script che consente di demonizzare l’applicativo in questione:

#!/bin/sh
# $Id$
#
# snortd         Start/Stop the snort IDS daemon.
#
# chkconfig: 2345 40 60
# description:  snort is a lightweight network intrusion detection tool that \
#                currently detects more than 1100 host and network \
#                vulnerabilities, portscans, backdoors, and more.
#

# Source function library.
. /etc/rc.d/init.d/functions

# Source the local configuration file
. /etc/sysconfig/snort

#PID file location
PID=/var/run/snort

# Convert the /etc/sysconfig/snort settings to something snort can
# use on the startup line.
if [ "$ALERTMODE"X = "X" ]; then
   ALERTMODE=""
else
   ALERTMODE="-A $ALERTMODE"
fi

if [ "$USER"X = "X" ]; then
   USER="snort"
fi

if [ "$GROUP"X = "X" ]; then
   GROUP="snort"
fi

if [ "$BINARY_LOG"X = "1X" ]; then
   BINARY_LOG="-b"
else
   BINARY_LOG=""
fi

if [ "$CONF"X = "X" ]; then
   CONF="-c /etc/snort/snort.conf"
else
   CONF="-c $CONF"
fi

if [ "$INTERFACE"X = "X" ]; then
   INTERFACE="-i eth0"
else
   INTERFACE="-i $INTERFACE"
fi

if [ "$DUMP_APP"X = "1X" ]; then
   DUMP_APP="-d"
else
   DUMP_APP=""
fi

if [ "$NO_PACKET_LOG"X = "1X" ]; then
   NO_PACKET_LOG="-N"
else
   NO_PACKET_LOG=""
fi

if [ "$PRINT_INTERFACE"X = "1X" ]; then
   PRINT_INTERFACE="-I"
else
   PRINT_INTERFACE=""
fi

if [ "$PASS_FIRST"X = "1X" ]; then
   PASS_FIRST="-o"
else
   PASS_FIRST=""
fi

if [ "$LOGDIR"X = "X" ]; then
   LOGDIR=/var/log/snort
fi

# These are used by the 'stats' option
if [ "$SYSLOG"X = "X" ]; then
   SYSLOG=/var/log/messages
fi

if [ "$SECS"X = "X" ]; then
   SECS=5
fi

if [ ! "$BPFFILE"X = "X" ]; then
   BPFFILE="-F $BPFFILE"
fi

######################################
# Now to the real heart of the matter:

# See how we were called.
case "$1" in
  start)
        echo -n "Starting snort: "
        cd $LOGDIR
        if [ "$INTERFACE" = "-i ALL" ]; then
           for i in `cat /proc/net/dev|grep eth|awk -F ":" '{ print $1; }'`
           do
                mkdir -p "$LOGDIR/$i"
                chown -R $USER:$GROUP $LOGDIR
                daemon /usr/sbin/snort $ALERTMODE $BINARY_LOG $NO_PACKET_LOG $DUMP_APP -D $PRINT_INTERFACE -i $i -u $USER -g $GROUP $CONF -l $LOGDIR/$i 

$PASS_FIRST $BPFFILE $BPF
           done
        else
           # check if more than one interface is given
           if [ `echo $INTERFACE|wc -w` -gt 2 ]; then
              for i in `echo $INTERFACE | sed s/"-i "//`
                do
                  mkdir -p "$LOGDIR/$i"
                  chown -R $USER:$GROUP $LOGDIR
                  daemon /usr/sbin/snort $ALERTMODE $BINARY_LOG $NO_PACKET_LOG $DUMP_APP -D $PRINT_INTERFACE -i $i -u $USER -g $GROUP $CONF -l $LOGDIR/$i 

$PASS_FIRST $BPFFILE $BPF
             done
           else
              # Run with a single interface (default)
              daemon /usr/sbin/snort $ALERTMODE $BINARY_LOG $NO_PACKET_LOG $DUMP_APP -D $PRINT_INTERFACE $INTERFACE -u $USER -g $GROUP $CONF -l $LOGDIR 

$PASS_FIRST $BPFFILE $BPF --pid-path $PID
           fi
        fi
        touch /var/lock/subsys/snort
        echo
        ;;
  stop)
        echo -n "Stopping snort: "
        killproc snort
        rm -f /var/lock/subsys/snort
        echo
        ;;
  reload)
        echo "Sorry, not implemented yet"
        ;;
  restart)
        $0 stop
        $0 start
        ;;
  condrestart)
        [ -e /var/lock/subsys/snort ] && $0 restart
        ;;
  status)
        status snort
        ;;
  stats)
        TC=125                          # Trailing context to grep
        SNORTNAME='snort'               # Process name to look for

        if [ ! -x "/sbin/pidof" ]; then
           echo "/sbin/pidof not present, sorry, I cannot go on like this!"
           exit 1
        fi

        #Grab Snort's PID
        PID=`pidof -o $$ -o $PPID -o %PPID -x ${SNORTNAME}`

        if [ ! -n "$PID" ]; then        # if we got no PID then:
           echo "No PID found: ${SNORTNAME} must not running."
           exit 2
        fi

        echo ""
        echo "*******"
        echo "WARNING:  This feature is EXPERIMENTAL - please report errors!"
        echo "*******"
        echo ""
        echo "You can also run: $0 stats [long | opt]"
        echo ""
        echo "Dumping ${SNORTNAME}'s ($PID) statistics"
        echo "please wait..."

        # Get the date and tell Snort to dump stats as close together in
        # time as possible--not 100%, but it seems to work.
        startdate=`date '+%b %e %H:%M:%S'`

        # This causes the stats to be dumped to syslog
        kill -USR1 $PID

        # Sleep for $SECS secs to give syslog a chance to catch up
        # May need to be adjusted for slow/busy systems
        sleep $SECS

        if [ "$2" = "long" ]; then              # Long format
            egrep -B 3 -A $TC "^$startdate .* snort.*: ={79}" $SYSLOG | \
                grep snort.*:
        elif [ "$2" = "opt" ]; then             # OPTimize format
           # Just show stuff useful for optimizing Snort
            egrep -B 3 -A $TC "^$startdate .* snort.*: ={79}" $SYSLOG | \
                egrep "snort.*: Snort analyzed |snort.*: dropping|emory .aults:"
        else                                    # Default format
            egrep -B 3 -A $TC "^$startdate .* snort.*: ={79}" $SYSLOG | \
                grep snort.*: | cut -d: -f4-
        fi
        ;;
  *)
        echo "Usage: $0 {start|stop|reload|restart|condrestart|status|stats (long|opt)}"
        exit 2
esac

exit 0

Copiamo il binario di snort nella dir /usr/sbin:

cp /usr/local/bin/snort /usr/sbin/

e rendiamo il suddetto scrip eseguibile, per poi avviarlo e fare in modo che venga eseguito automaticamente dopo ogni riavvio della macchina:

chmod +x /etc/init.d/snortd
chkconfig --add snortd
chkconfig snortd on

Per ora abbiamo finito. Nel prossimo post vedremo come installare e configurare pulledpork e barnyard2.

A presto.

snort2mail: script per ricevere gli alert di snort direttamente sulla nostra casella di posta elettronica

Gli alert generati da snort sono di indubbia utilità, in quanto da un’attenta analisi degli stessi è possibile individuare possibili tentativi di intrusione sulla nostra rete. Poichè sono un po’ pigro e la lettura dei log è sicuramente una delle fasi più tediose del mio lavoro, ho pensato di creare il seguente scrip, in grando di inviare al mio indirizzo email gli alert in questione man mano che vengono generati.

snort, mail, snort2mail, alert, IDS, NIDS

Ecco lo scrip:

#!/bin/bash

logfile=/var/log/snort2sms.log

destinatario=vostro.indirizzo@email.it

ROOT_UID=0

if [ "$UID" -ne "$ROOT_UID" ];then

        ERRORE1="Errore 1: Devi essere root per eseguire lo script"
        echo $ERRORE1
        echo "$(date) $ERRORE1" >> $logfile
        exit 1

fi

cd /var/log/snort

if [ -f alert ];then

        if [ -f alert_backup ];then
                #confronto i due file e salvo le differenza all'interno di mail
                diff alert alert_backup > mail

        else

                touch alert_backup
                cp alert alert_backup
        fi

else

        ERRORE2="Errore 2: Il file alert non esiste. Sei sicuro di aver installato snort?"
        echo $ERRORE2
        echo "$(date) $ERRORE2" >> $logfile

fi

if [ -s mail  ];then

        cp alert alert_backup

        cat mail | mail -iv -s "HOME: snort alert" $destinatario;
fi

rm mail

Non vi resta che schedulare l’esecuzione dello script mediante cron e creare il file di log snort2mail.log nella directory /var/log.

Enjoy.

Installare e configurare Snort 2.8.4 su Kubuntu 9.04

Recentemente ho notato (con mio sommo dispiacere) che l’unica versione di Snort installabile su Kubuntu 9.04 mediante repository è la 2.7.x. Peccato però che tale versione non sia più supportata; ecco allora che ho pensato bene di rimuoverla dal mio sistema ed installare, previa compilazione, la versione 2.8.4.

snort1sm.jpg

Per prima cosa occorre scaricare la tarball in cui sono contenuti i sorgenti di Snort (seguite questo link). Fatto ciò controllate, prima di partire con la compilazione vera a propria, che tutte le dipendenze (librerie e compagnia bella) necessarie al software in questione siano soddisfatte. A tal proposito bisogna posizionarsi nella cartella in cui abbiamo precedentemente salvato la tarball e lanciare il comando:

tar -xzvf /home/nightfly/snort-2.8.1.tar.gz

Una volta estratti i file accediamo alla directory appena creata

cd /home/nightfly/snort-2.8.1

Bene, adesso lanciamo il comando ./configure che servirà proprio a verificare che tutte le dipendenze siano soddisfatte. Solitamente le librerie che Snort richiede sono libpcap0.8-dev e libpcre3-dev. Entrambe possono essere installate digitando:

sudo apt-get install libpcap0.8-dev

sudo apt-get install libpcre3-dev

Se la procedura di configurazione avviata in precedenza va a buon fine, possiamo usare il comando:

make

per compilare i sorgenti e successivamente

make install

per effettuare l’installazione vera e propria di Snort.

Creiamo la directory in cui andrà inserito il file di configurazione relativo a Snort, le regole di rilevamento delle intrusioni (rules) ed altri file necessari al corretto funzionamento dell’applicativo in questione:

sudo mkdir /etc/snort

sudo mkdir /etc/snort/rules

Andiamo a creare, inoltre, la directory in cui Snort salverà i log delle intrusioni

sudo mkdir /var/log/snort

Sempre dalla cartella in cui abbiamo estratto la tarball lanciamo il comando

rm Makefile Makefile.in Makefile.am

e successivamente

sudo cp etc /etc/snort

Passiamo adesso alla configurazione di Snort, la quale può essere effettuata mediante la modifica ad hoc del file snort.conf posizionato nella dir /etc/snort.

sudo nano /etc/snort/snort.conf

Impostiamo il valore della variabile HOME_NET con la classe di indirizzi IP utilizzata nell’ambito della nostra LAN, mentre nella variabile EXTERNAL_NET andreamo a sostituire any con !$HOME_NET. In questo modo stiamo dicendo a Snort di considerare come indirizzi esterni alla nostra LAN (e quindi sorgenti di potenziali attacchi) tutti quelli che non rientrano nella classe associata ad HOME_NET. Modifichiamo inoltre la variabile RULE_PATH assegnandogli il valore /etc/snort/rules.

Questa piccola modifica del file di configurazione ci consente di fare in modo che Snort inizi ad effettuare il monitoraggio della nostra rete in modo corretto. E’ possibile comunque adattare ulteriormente Snort alle nostre esigenze andando a modificare la sezione relativa ai cosiddetti “preprocessori”, quali, ad esempio, http_inspect (per l’individuazione di attacchi basati sul protocollo HTTP) oppure sfportscan (per la rilevazione dei portscan).

Passiamo adesso al download delle rules, necessario affinche Snort ci segnali eventuali tentativi di intrusione. Tale operazione può essere eseguita utilizzando un semplice programmino a linea di comando, ovvero oinkmaster. Non perdiamo tempo ed installiamolo:

sudo apt-get install oinkmaster

Per poter installare le rules è necessario dapprima registrarsi sul sito snort.org e successivamente procedere con la generazione di un oinkcode (ovvero di un digest MD5) che ci identifica univocamente. In particolare, sarà possibile fare ciò andando qui (previo login) e cliccando sul pulsante Generate code.

Fatto ciò passiamo alla modifica del *.conf ad esso associato.

sudo nano /etc/oinkmaster.conf

e inseriamo la seguente stringa:

url = http://www.snort.org/pub-bin/oinkmaster.cgi/<nostro_oinkcode>/snortrules-snapshot-2.8.tar.gz

Una volta completati download ed installazione delle rules, possiamo avviare Snort in modalità “test” per verificarne il corretto funzionamento. Digitiamo quindi:

sudo snort - T -c /etc/snort/snort.conf

e se ricevete la seguente stringa in output

 Snort sucessfully loaded all rules and checked all rule chains!
 Snort exiting

avete la prova che Snort sta funzionando correttamente. Un altro test che potrebbe tornare utile è quello che ci permette di visualizzare in tempo reale i pacchetti sniffati da snort:

sudo snort -c /etc/snort/snort.conf -v

Ora non ci resta che eseguire automaticamente Snort ad ogni avvio del sistema, possibilmente in modalità demone, ovvero in background. Per fare ciò andiamo ad editare il file rc.local presente nella directory /etc:

sudo nano /etc/rc.local

e successivamente inseriamo la stringa

sudo snort -c /etc/snort/snort.conf -i eth1 -l /var/log/snort -D

dove la flag -D specifica proprio l’esecuzione in background.

Infine, se ad esempio volessimo effettuare il download e l’aggiornamento delle rules ogni ora, possiamo procedere con la creazione di una regola per cron, mediante l’editing del file crontab:

sudo nano /etc/crontab

e digitiamo

0  *    * * *   root    oinkmaster -o /etc/snort/rules/

Bene, adesso Snort è configurato e pronto per l’uso. A presto.

PS: ho realizzato un piccolo programmino che invia, mediante SMS, gli alert generati da Snort. Per ulteriori informazioni non esitate a contattarmi.

PPS: è possibile effettuare download dal sito Snort.org solo ad intervalli (minimi) di quindici minuti, ergo non impostate regole di cron che agiscano troppo frequentemente.