Olá pessoal, hoje falaremos sobre um renomado sistema de IDS(Intrusion Detection System) o Snort e também de alguns programas que podem trabalhar em paralelo com ele como o Oinkmaster, BASE e o Snort2PF onde entraremos em detalhes no decorrer do artigo; por fim teremos uma verdadeira ferramenta para análise de pacotes e gerenciamento de rede.
Nesse artigo estarei utilizando uma máquina com o OpenBSD-4.3 instalado e a rede devidamente configurada, ao final do artigo terá os links para uma leitura mais completa dos assuntos abordados aqui.
Instalação e Configuração
PostgreSQL
Primeiro instalamos o PostgreSQL depois erguemos o serviço para que consigamos criar um usuário e uma base de dados, necessitamos de uma inicialização automática para isso adicionamos as linhas no rc.local e no rc.shutdown. Irá ser criado também um campo no login.conf assim tiramos as limitações que o campo “daemon” tem sobre o nosso serviço. Uma conta “mestre” e uma conta “snortuser” são feitas, por fim criamos o base de dados “snort” e setamos o usuário “snortuser” como o dono da base “snort”.
# export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/snapshots/packages/i386/
# pkg_add -i postgresql-server
# su -l _postgresql -c "nohup /usr/local/bin/pg_ctl start -D /var/postgresql/data -l /var/postgresql/logfile \
-o '-D /var/postgresql/data' >/dev/null"
/etc/rc.local:
if [ -x /usr/local/bin/pg_ctl ]; then
echo -n ' postgresql'
su -l _postgresql -c "nohup /usr/local/bin/pg_ctl start \
-D /var/postgresql/data -l /var/postgresql/logfile \
-o '-D /var/postgresql/data' >/dev/null"
fi
/etc/rc.shutdown:
if [ -f /var/postgresql/data/postmaster.pid ]; then
su -l _postgresql -c "/usr/local/bin/pg_ctl stop -m fast \
-D /var/postgresql/data"
rm -f /var/postgresql/data/postmaster.pid
fi
/etc/login.conf:
postgresql:\
:openfiles-cur=768:\
:tc=daemon:
# cap_mkdb /etc/login.conf
# su - _postgresql
$ mkdir /var/postgresql/data
$ initdb -D /var/postgresql/data -U mestre -A md5 -W
$ createuser -U mestre -P snortuser
Enter password for new role:
Enter it again:
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create database? (y/n) n
Shall the new role be allowed to create a more new roles? (y/n) y
Password:
CREATE ROLE
$ creatdb -U mestre snort -O snortuser
Password:
CREATE DATABASE
Observação: Leiam mais sobre semáforos e a sua importância para o banco de dados.
PHP
Agora vamos instalar o PHP e seus respectivos módulos: GD, pgsql, odbc.
GD: Manipulação de imagens
pgsql: comunicação com o banco de dados PostgreSQL
odbc: suporte a funções para o acesso ao banco de dados odbc
# pkg_add -i php5-core
# ln -s /var/www/conf/modules.sample/php5.conf /var/www/conf/modules
# mkdir /var/www/tmp
# chmod 1777 /var/www/tmp/
# pkg_add -i php5-gd
# ln -fs /var/www/conf/php5.sample/gd.ini /var/www/conf/php5/gd.ini
# pkg_add -i php5-pgsql
# ln -fs /var/www/conf/php5.sample/pgsql.ini /var/www/conf/php5/pgsql.ini
# pkg_add -i php5-odbc
# ln -fs /var/www/conf/php5.sample/odbc.ini /var/www/conf/php5/odbc.ini
Snort
Instalamos o Snort com suporte ao flexresp e postgresql:
# cd /usr/ports/net/snort/
# env FLAVOR="postgresql flexresp" make install
Observação: Enquanto compila o snort entre no site https://www.snort.org/pub-bin/register.cgi e se registre, isso será essencial para que consigamos ter regras atualizadas do snort e consequentemente realizar a função do Oinkmaster.
Adicione as linhas para inicialização automática do serviço:
/etc/rc.conf.local:
snort=YES
/etc/rc.local:
if [ X"${snort}" == X"YES" -a -x /usr/local/bin/snort ]; then
echo -n "Iniciando Snort"; /usr/local/bin/snort -D -d -c /etc/snort/snort.conf -u _snort -g _snort -t /var/snort -l /var/snort/log
fi
Configurando
A príncipio o arquivo de configuração do Snort que se localiza em /etc/snort parece ser embaraçoso, mais praticamente você não precisará alterar nada no arquivo somente algumas variáveis e incluir as rules no final. Você pode melhorar o desempenho do Snort na configuração de pré-processadores, mais como nesse artigo estou usando uma máquina dedicada ao Snort não vejo problema em deixar o padrão mesmo.
Vamos editar o HOME_NET e o outdatabase, no primeiro eu vou colocar o ip da minha rede que no caso é 192.168.0.0/24 e no segundo eu irei colocar as informações do banco de dados para que sejão gravadas as saidas de logs e os alert's, no final do arquivo irá conter vários includes $RULE_PATH retire-os ou simplesmente comente as linhas que tenham o prefixo: include $RULE_PATH/ veja abaixo como ficaria.
# Step #1: Set the network variables:
#
# You must change the following variables to reflect your local network. The
# variable is currently setup for an RFC 1918 address space.
#
# You can specify it explicitly as:
#
# var HOME_NET 10.1.1.0/24
#
# or use global variable $_ADDRESS which will be always
# initialized to IP address and netmask of the network interface which you run
# snort at. Under Windows, this must be specified as
# $(_ADDRESS), such as:
# $(\Device\Packet_{12345678-90AB-CDEF-1234567890AB}_ADDRESS)
#
# var HOME_NET $eth0_ADDRESS
#
# You can specify lists of IP addresses for HOME_NET
# by separating the IPs with commas like this:
#
# var HOME_NET [10.1.1.0/24,192.168.1.0/24]
#
# MAKE SURE YOU DON'T PLACE ANY SPACES IN YOUR LIST!
#
# or you can specify the variable to be any IP address
# like this:
var HOME_NET 192.168.0.0/24 # MINHA REDE
...
# database: log to a variety of databases
# ---------------------------------------
# See the README.database file for more information about configuring
# and using this plugin.
#
output database: log, postgresql, user=snortuser password=teste dbname=snort host=127.0.0.1
output database: alert, postgresql, user=snortuser password=teste dbname=snort host=127.0.0.1
# output database: log, odbc, user=snort dbname=snort
# output database: log, mssql, dbname=snort user=snort password=test
# output database: log, oracle, dbname=snort user=snort password=test
...
#include $RULE_PATH/local.rules
#include $RULE_PATH/bad-traffic.rules
...
Vamos adicionar ao banco de dados as tabelas para que o Snort consiga enviar os logs e os alert's:
# su - _postgresql
$ psql snort snortuser
Password for user snortuser:
snort=> \i /usr/ports/net/snort/w-snort-2.8.0.1-postgresql-flexresp/snort-2.8.0.1/schemas/create_postgresql
snort=> \q
Oinkmaster
O Oinkmaster irá ser usado para puxar nossas regras e também deixá-las atualizadas. Ele possui várias opções sugiro que você leia o man para conseguir otimizar o máximo possível esse processo; opções utéis que eu ecnontrei nele é que você pode puxar as regras via scp, pode ainda indicar pelo SID qual regra você quer que ele não atualize e tem também uma opção para backup das regras antigas. Você lembra da segunda ?Observação? logo abaixo da instalação do Snort é agora que colocamos ela em prática, logue-se no site do Snort, no menu esquerdo irá ter um link chamado RULES clique nele abrirá outro site e no canto direito irá ter outro link com o nome Download Rules clique nele, vá até a parte onde usuários registrados podem puxar as regras e faça o download para o seu tipo de versão do Snort voltamos á pagina inicial de seu login logo abaixo irá ter um botão Get Code clique nele e copie o código gerado, é através dele que o Oinkmaster irá se identificar. Talvez tenha ficado um pouco complicado essa parte, mas leia atentamente que você irá conseguir.
Instalaremos o Oinkmaster:
# cd /usr/ports/net/oinkmaster/
# make install clean
Foi criado o arquivo de configuração dele no /etc vamos simplesmente editar o oinkmaster.conf e adicionar na variável url a sintaxe para que ele consiga puxar as regras:
...
# URL examples follows. Replace with the code you get on the
# Snort site in your registered user profile.
# A minha sintaxe irá ficar assim veja que eu uso a versão 2.8 do Snort:
url = http://www.snort.org/pub-bin/oinkmaster.cgi/CÓDIGO_QUE_FOI_COPIADO/snortrules-snapshot-2.8.tar.gz
....
Bom pessoal já estamos na metade, algo que me surpreendeu também no Oinkmaster é que você pode usar uma flag -c que simplesmente verifica se à atualizações nas suas rules, podemos otimizar isso fazendo um pequeno script e agendando no crontab, no caso o script abaixo ele só verifica se á atualizações se houver ele envia por e-mail relatando.
Abaixo tem o comando para descompactar as regras e adicioná-las ao arquivo de configuração:
# tar -xvzf snortrules-snapshot-2.8.tar.gz -C /etc/snort/
# ls -1 /etc/snort/rules/*.rules | \
awk '{print "include "$1}' >> /etc/snort/snort.conf
Copie o código do script abaixo e personalize para as suas necessidades. Eu ativei no crontab para verificar todo dia as 6:10, não esqueça de alterar o destinatário do e-mail:
#!/bin/sh
# Pequeno script para verificar atualização nas regras
TMP=`mktemp /tmp/oinkmaster.20080802` &&
(oinkmaster -o /etc/snort/rules/ -q -c > $TMP 2>&1;
if [ -s $TMP ]; then mail -s "Atualizações das Regras SNORT" seuemail@email.com.br < $TMP; fi; rm $TMP)
# crontab -e
10 6 * * * /usr/bin/updaterules.sh
Para verificar se as configurações até o momento estão funcionais, execute o comando:
# snort -c /etc/snort/snort.conf -u _snort -g _snort -t /var/snort -l /var/snort/log
BASE
Instalaremos o BASE (Basic Analysis and Security Engine) e suas respectivas dependências, ele é um belo visualizador dos logs e gerado pelo Snort ele possui uma interface via web de fácil compreensão, gera relatórios através de gráficos, desenvolvido em php e veja no Fórum como instalar novos Themas. No site tem umas Screens confiram.
# cd /var/www/htdocs/
# wget http://downloads.sourceforge.net/adodb/adodb505.tgz?modtime=1215766049&big_mirror=0
# tar -xvzf adodb505.tgz
# pkg_add -i pear
# pear install Image_Color
# pear install Log
# pear install Numbers_Roman
# pear install http://download.pear.php.net/package/Numbers_Words-0.15.0.tgz
# pear install http://download.pear.php.net/package/Image_Canvas-0.3.1.tgz
# pear install http://download.pear.php.net/package/Image_Graph-0.7.2.tgz
# wget http://downloads.sourceforge.net/secureideas/base-1.4.0.tar.gz?modtime=1209150368&big_mirror=0
# tar -xvzf base-1.4.0.tar.gz
# mv base-1.4.0 base
# cd base
# cp base_conf.php.dist base_conf.php
# vi base_conf.phpi
Altere umas variáveis no arquivo de configuração do BASE:
...
/*
Set the base_urlpath to the url location that is the root of your BASE install.
This must be set for BASE to function! Do not include a trailing slash!
But also put the preceding slash. e.g. Your URL is http://127.0.0.1/base
set this to /base
*/
$BASE_urlpath = '/base'; /* Caminho no navegador para acesso ao BASE */
...
/* Path to the DB abstraction library
* (Note: DO NOT include a trailing backslash after the directory)
* e.g. $foo = '/tmp' [OK]
* $foo = '/tmp/' [OK]
* $foo = 'c:\tmp' [OK]
* $foo = 'c:\tmp\' [WRONG]
*/
$DBlib_path = '../adodb5'; /* Caminho do AdoDB5 */
/* The type of underlying alert database
*
* MySQL : 'mysql'
* PostgresSQL : 'postgres'
* MS SQL Server : 'mssql'
* Oracle : 'oci8'
*/
$DBtype = 'postgres'; /* Altere o banco para suporte ao postgres */
/* Alert DB connection parameters
* - $alert_dbname : MySQL database name of Snort alert DB
* - $alert_host : host on which the DB is stored
* - $alert_port : port on which to access the DB
* - $alert_user : login to the database with this user
* - $alert_password : password of the DB user
*
* This information can be gleaned from the Snort database
* output plugin configuration.
*/
$alert_dbname = 'snort'; /* Nome do Banco de Dados */
$alert_host = '127.0.0.1'; /* Host para conexão do banco */
$alert_port = '5432'; /* Porta de escuta do PostgreSQL */
$alert_user = 'snortuser'; /* Usuário para conectar-se ao banco */
$alert_password = 'teste'; /* Senha para acesso ao banco */
....
Salve o arquivo, inicie o servidor de web e abra o BASE, quando você abrir pela primeira vez o ele mostra-rá uma menssagem The database version is valid, but the BASE DB structure (table: acid_ag)is not present. Use the Setup page to configure and optimize the DB. clique em Setup Page para ele construir a estrutura da base de dados, depois clique em Create BASE AG. Leia sobre ele no site do projeto http://base.secureideas.net, por fim vamos copiar as assinaturas do Snort para a pasta do BASE:
# cp -rf /etc/snort/doc/signatures /var/www/htdocs/base/
Snort2PF
Bom pessoal chegamos praticamente ao fim do artigo, uma alternativa ao SnortSam que eu encontrei é o Snort2PF, ele é mais simples que o SnortSam, consequentemente não possui tantas opções que o SnortSam nos oferece, por exemplo não tem suporte a ipv6, não envia e-mail falando sobre os bloqueios e como o nome já diz é somente para o PF, agora você está se perguntando porque usar Snort2PF, bom ele é um daemon muito simples feito em PERL não necessita aplicar um patch no código do snort, não necessita de uma versão específica para que ele funcione e se precisar de alguma alteração no código é de fácil compreensão e possui uma licença BSD ;-).
Vamos puxar e instalá-lo:
# wget http://downloads.sourceforge.net/snort2pf/snort2pf-4.3.tar.gz?modtime=1196384491&big_mirror=0
# tar -xvzf snort2pf-4.3.tar.gz
# cd snort2pf-4.3
# ./install.sh
>>> Installing files...
>>> Creating symlinks...
Don't forget to add the following line to you pf.conf(5):
"anchor snort2pf"
Você pode usar âncoras no PF ou tables, eu prefiro usar tables para manipulação da mesma, bom vou inserir nas minhas regras do firewall um simples bloqueio a table snort2pf, logo em seguida iriei iniciar o PF e ativar as novas regras vou também editar o /etc/rc.conf para o meu PF iniciar automaticamente.:
/etc/pf.conf:
table persist
block in quick from
# pfctl -e
# pfctl -f /etc/pf.conf
# vi /etc/rc.conf
...
pf=YES # Packet filter / NAT
...
O Snort2PF irá ler os logs /var/snort/log/alerts e quando Snort der um alerta automáticamente o Snort2PF joga o ip na tabela snort2pf logo esse ip ficará bloqueado por um tempo determinado por você, veja que eu usei uma regra de bloqueio; sugiro que leia sobre o PF use sua criatividade. Vou agora iniciar o Snort2PF para bloquear um host durante 1(um) minuto, o Snort2PF tem também um suporte a whitelist ali você defini os ip's que não serão bloqueados por ele, a príncipio ele só suporta um ip por linha, mais calma calma basta instalar a CPAN Net-Patricia, para ter suporte a subnets mãos a obra:
# wget http://search.cpan.org/CPAN/authors/id/P/PL/PLONKA/Net-Patricia-1.014.tar.gz
# tar -xvzf Net-Patricia-1.014.tar.gz
# cd Net-Patricia-1.014
# perl Makefile.PL
# make
# make test
# make install
Como eu quero só adicionar o ip do servidor na minha whitelist para fins de teste, digitei o comando abaixo:
# echo 192.168.0.4 >> /etc/whitelist
Pronto vamos rodar o Snort2PF a opção -t é para que ele leia a table snort2pf ao invés das âncoras, -s indica o tempo em segundos, -f mostro o caminho do arquivo que contêm os logs's do Snort, por default ele lê em /var/log/snort/alert e indico com -w onde se encontra o arquivo que contêm o ip da minha whitelist; resumindo:
# /usr/local/sbin/snort2pf -f /var/snort/log/alert -s 60 -t -w /etc/whitelist &
# ps aux | grep snort2pf
... 0:00.14 perl: snort2pf 4.3 :: blocking 0 hosts (perl)
Teste
Para não dizer que seu trabalho foi todo em vão lendo esse pequeno artigo vamos fazer um teste, criaremos uma regra no Snort para gerar um alerta de qualquer conexão tcp na porta 11110, após criada a regra reinicie o Snort:
# cd /etc/snort/rules/
# touch local.rules
# echo "alert tcp any any -> 192.168.0.4 11110 (msg:"BINGO !!! log 11110/tcp"; sid:1111110;)" >> local.rules
# echo "include /etc/snort/rules/local.rules" >> /etc/snort/snort.conf
Agora vamos ao teste, pegue uma máquina que não esteja na sua whitelist e digite o comando a seguir, ele tentará se conectar no servidor e acionará a regra que criamos, logo enseguiga darei um ping não irá obter nenhuma resposta do servidor, como eu ativei o tempo para um minuto espero passar esse tempo até que meu ip estejá liberado e tento novamente pingar se conseguir resposta do servidor deu tudo certo :-):
# telnet 192.168.0.4 11110
Trying 192.168.0.4...
telnet: connect to address 192.168.0.4: Connection refused
#ping 192.168.0.4
PING 192.168.0.4 (192.168.0.4): 56 data bytes
--- 192.168.0.4 ping statistics ---
14 packets transmitted, 0 packets received, 100.0% packet loss
Como podem ver só enviei pacote não recebi nenhum do servidor, após 1 minuto:
# ping -c 2 192.168.0.4
PING 192.168.0.4 (192.168.0.4): 56 data bytes
64 bytes from 192.168.0.4: icmp_seq=0 ttl=255 time=0.253 ms
64 bytes from 192.168.0.4: icmp_seq=1 ttl=255 time=0.208 ms
--- 192.168.0.4 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.208/0.230/0.253/0.027 ms
Se você ainda tem dúvida que seu ip esteja bloqueado você pode visualizar os ips contidos na tabela snort2pf:
# pfctl -t snort2pf -T show
Bom é isso pessoal espero que vocês tenham gostado do artigo, abaixo irá ter os links dos meus sugiros dúvidas entre em contato comigo:
Murilo Ijanc
mijanc@openbsd-br.org