Documente Academic
Documente Profesional
Documente Cultură
Introdução
O que é o Snort?
O Snort é um famoso IDS (Intrusion Detection System) - Sistema de Detecção de Intrusão. Ele é um programa que fica o tempo todo,
enquanto está funcionando, vigiando a entrada que a rede tem à máquina para nos informar caso haja alguma tentativa de ataque. O
Snort é como um guarda desarmado, mas com uma máquina fotográfica à mão. Essa foi a explicação mais simples. Vamos então saber
melhor o que é o Snort.
O Snort é basicamente um farejador de rede com capacidade de reconhecer padrões de cabeçalho e de conteúdos de pacotes. A parte
interessante é que essa capacidade é altamente configurável.
Um farejador de rede é um programa que escuta em uma dada interface de rede os pacotes que por ela passam. Tipicamente, os únicos
pacotes que por ela passam e também são lidos por inteiro são aqueles que se destinam à máquina à qual pertence a interface.
Um farejador, no entanto, pode, se quiser, capturar não somente os pacotes destinados a sua máquina, mas também todos os pacotes
que por ela passarem independetemente de sua origem ou destino. Isso é mais eficaz, é claro, quanto mais máquinas estiverem
enviando pacotes em broadcast na mesma seção de rede que o farejador. Uma interface de rede é dita estar em estado promíscuo
quando permite um farejador escutar quaisquer pacotes. O Snort pode funcionar e funciona por padrão sobre interfaces em modo
promíscuo.
Ao longo deste curso pode ser bastante útil que consultem o manual on-line na página do Snort, que é muito detalhado e organizado.
Assim que o Snort captura os pacotes ele os analiza segundo assinaturas de reconhecimento de ataques, que nada mais são do que
padrões de conteúdos dos pacotes que são comparados aos dos pacotes reais que entram em nossa máquina para tentar reconhecer
sua função.
Aqueles conjuntos de pacotes que forem reconhecidos como maliciosos fazem o Snort logar uma tentativa de ataque em seu log de
alertas. Para tanto o Snort consulta regras que decidem o que deve ou não ser logado, e como o deve. Uma regra pega o diagnóstico
dado a um pacotes e decide o que como irá logá-lo. Um log é simplismente um aviso informativo de alguma coisa que veio a acontecer.
Esse aviso fica tipicamente armazenado em arquivos no disco da máquina, ainda que possa ser redirecionado para outra máquina na
rede ou mesmo enviado por e-mail. No caso do Snort, os mesmos logs podem ser enviados em tempo real para a saída padrão, o
console.
Esse log, por sua vez, pode ser escrito tanto em texto plano em formato legível quanto em outros formatos otimizados que tem de ser
interpretados por um programa e que podem ser manipulados até mesmo em tempo real para o visualizarmos melhor, caso utilizemos
algum plugin especial.
O Snort é capaz de reconhecer vários tipos de pacotes maliciosos. Alguns exemplos são pacotes de varreduras discretas de portas,
ataques de CGI, ataques de estouro de buffer e outros esforços que possam servir a futuros ataques, como reconhecimento de sistema
operacional, por exemplo.
Como é o Snort?
O Snort é manipulado pela linha de comando. Podemos inicializá-lo, interrompê-lo, acompanhar o que escuta em tempo real e
configurar suas regras tudo com o console.
O Snort, por ser um programa compilado, tem seu arquivo binário. Além deste, o Snort é composto de um arquivo de configuração e
alguns scripts, que ficam na mesma pasta, e de uma pasta de logs, separada.
O diretório de configuração do Snort é o /etc/snort. Nele existem dois diretórios que nos interessa conhecer:
/etc/snort/rules - Contém as regras que decidem o que logar, como e onde.
Outro diretório que nos cabe conhecer é a sua pasta de logs, que fica no diretório /var:
/var/snort
Além dos diretórios, existe o próprio arquivo de configuração do Snort, sobre o qual vamos nos debruçar neste breve curso, o
/etc/snort/snort.conf
O arquivo de configuração do Snort guarda variáveis de valores da rede e da máquina relevantes ao seu funcionamento. As variáveis
nos interessam especialmente para a configuração das regras, e para tanto as variáveis devem estar setadas adequadamente. Além
disso, o snort.conf lista os preprocessadores utilizados na análise de um pacote, o que vamos entender um pouco melhor mais tarde, e
também a indicação dos plugins utilizados para dar suporte ao uso do Snort, como aqueles apresentados a cima. No final do arquivo,
por fim, são listadas as regras de logging do Snort.
Existem ferramentas que facilitam a manipulação dos logs do Snort, como o programa BASE, uma que otimiza sua função, se
comprometendo a logar e deixando o Snort livre para detecção de pacotes, o Barnyard, e até outra que gerencia as regras do Snort, o
Oinkmaster.
Neste curso, porém, vamos nos concetrar para entender o Snort por ele mesmo, para que aqueles que quiserem experimentar
posteriormente outras ferramentas tenham um bom conhecimento do Snort.
Como sabemos, o Snort captura os pacotes que passam por uma dada interface de rede. Para descobrir se está ou não havendo uma
tentativa de intrusão, o Snort atravessa os dados dos pacotes por uma série de módulos de análise e de diagnóstico. O decodificador
recebe os pacotes e os analisa no nível dos protocolos e dos cabeçalhos, descobrindo os IP envolvidos, as portas, o tamanho do pacote e
sua integridade, tudo antes mesmo deles serem remontados para uma aplicação.
O preprocessador identifica comportamentos suspeitos de pacotes e os encaminha para uma análise de conteúdo para o módulo
seguinte. Já o processador de pacotes compara o conteúdo e natureza do pacote com assinaturas de ataques conhecidos, armazenadas
no diretório /etc/snort/doc e indicadas pelas regras carregadas pelo Snort (lidas no arquivo de configuração). As mesmas regras que
enviam a informação sobre os pacotes para serem processadas encaminham o diagnóstico para ser logado e/ou impresso no console.
O Snort pode ser configurado por quem quiser para funcionar sob o controle do init.d, como é padrão para quem o instalou por um
gerenciador de pacotes como o apt no Debian, o que faria com que o controlássemos com /etc/init.d/snort start/stop/restart/status...
Aqui, porém vamos manipulá-lo por conta própria, inicializando-o quando quisermos (e não automaticamente com o boot).
Instalação
Instalando - 1
Atualmente, no momento em que este texto foi escrito, o Snort se encontra na versão 2.6.0. É importante que acompanhem o curso
com a versão mais recente disponível, mesmo que ela não seja mais a 2.6.
O comando a seguir, o wget, baixa da internet o pacote no endereço indicado. O mesmo vale para todos wgets. Estes comandos se
tornam naturalmente desnecessários se visitarem os sites e baixarem os pacotes diretamente deles.
$ wget http://www.tcpdump.org/release/libpcap-<versão.mais.nova>.tar.gz
<PRE< a>>$ wget http://surfnet.dl.sourceforge.net/sourceforge/pcre/pcre-<versão.mais.nova>.tar.gz
<BR< a>/>Bom, adquira um shell root e crie uma pasta /etc/snort:
$ mkdir /etc/snort
Copie os códigos compactados que baixou até a pasta criada e entre nela:
Descompacte os arquivos:
$ cd pcre-<versão>
$ ./configure
$ make
$ make install
Entre na pasta do libpcap e repita os comandos:
$ cd ../libpcap-<versão>
$ ./configure
$ make
$ make install
Agora entre na pasta do codigo descompactado do Snort e vamos instalar o Snort ele mesmo:
$ cd ../snort-<versão>
$ ./configure --enable-dynamicplugin
Habilite o uso do banco de dados mysql para uso futuros testes e experimentos adicionando, se quiser:
--with-mysql
$ make
$ su
$ make install
$ cd /etc/snort
$ rm snort-<número da versão>.tar.gz
$ rm pcre-<número da versão>.tar.gz
$ rm libpcap-<número da versão>.tar.gz
Por fim, copie os seguintes arquivos da pasta de regras para a pasta pai:
$ cd /etc/snort
$ cp rules/unicode.map .
$ cp rules/classification.config .
$ cp rules/reference.config .
Instalando - 2
Vamos, ao mesmo tempo em que conhecemos um pouco dos arquivos e diretórios utilizados pelo snort, preparar o sistema para o seu
uso. Quem instalou com apt-get não terá de fazer adaptações.
Antes de mais nada, ganhe um shell como root. Precisamos de uma pasta para guardar as regras de análise do snort (vamos entender
isso posteriormente). Para tanto, crie, caso já não tenha sido criada, a pasta rules dentro do diretório do snort:
Agora crie outra pasta fundamental, a pasta snort em que ficarão os logs do snort, dentro do diretório /var/log:
$ mkdir /var/log/snort
Copie o arquivo de configuração do snort para a pasta base do snort que criamos, só para ficar mais à mão:
$ cp /etc/snort/snort-<número da versão>/etc/snort.conf /etc/snort
Agora vamos criar um usuário e um grupo para utilizar o snort e altere o proprietário da pasta de logs do snort para o novo usuário
snort:
$ groupadd snort
$ useradd -g snort snort
$ chown snort /var/log/snort
"http://www.snort.org/pub-bin/downloads.cgi"
No final da página tem uma sessão especial para não cadastrados. E uma sessão de regras feitas pela comunidade (e não pela equipe
do Snort).
$ wget http://www.snort.org/pub-bin/downloads.cgi/Download/vrt_pr/snortrules-pr-2.4.tar.gz
Esse comando baixa as regras do Snort 2.4 feita para os não cadastrados. Para se cadastrar não é preciso pagar nada, mas para se
inscrever sim, e esses últimos que recebem as regras mais novas e readequadas.
Descompacte o arquivo:
E por fim mova as duas pastas criadas (doc e rules) para a pasta do Snort:
Por fim, copie os seguintes arquivos da pasta de regras para a pasta pai:
$ cd /etc/snort
$ cp rules/unicode.map .
$ cp rules/classification.config .
$ cp rules/reference.config .
Montando um snort.conf
###################################################
# This file contains a sample snort configuration.
# You can take the following steps to create your own custom configuration:
#
# 1) Set the variables for your network
# 2) Configure dynamic loaded libraries
# 3) Configure preprocessors
# 4) Configure output plugins
# 5) Add any runtime config directives
# 6) Customize your rule set
#
###################################################
Como informado no início do snort.conf, a configuração padrão é somente um exemplo de como um snort.conf pode ser. E são indicados
quatro passos para montar o seu próprio arquivo. Como a configuração padrão funciona bem, podemos simplismente adaptá-la às
nossas condições. Para customizar nosso arquivo sem ter nem de programar nem de embalar o Snort com outros programas,
precisamos conhecer e adaptar especialmente (senão somente) as variáveis e as regras do Snort.
Como os scripts de bash, os comentários no snort.conf são identificados pelo caractere ' # '. Observem como a maior parte do arquivo
de configuração é comentada. Boa parte desses trechos não são somente comentários, mas também código que pode ser
eventualmente descomentado para ser habilitado. Para podermos ter uma boa visão da parte operante do arquivo e assim modificá-la,
vamos criar um novo arquivo de configuração com todas e somente as linhas descomentadas do snort.conf padrão. O meu arquivo
padrão tem exatamente 864 linhas. Só de código comentado, são 693 linhas! Obviamente, não queremos perder esse código. Para não
perdermos esse código, e também por segurança, vamos manter o arquivo original intacto. Digitemos, portanto, os seguintes
comandos:
$ cd /etc/snort
$ mv snort.conf snort.conf.original
$ head -n 20 snort.conf.original > original.sem.comentarios
$ cat snort.conf.original | grep -v ^# >> original.sem.comentarios
$ uniq original.sem.comentarios snort.conf
Para quem não entendeu o que foi feito, entramos na pasta do Snort para no segundo comando renomear o snort.conf para
snort.conf.original. Esse é o arquivo como veio. No terceiro comando capturamos as primeiras vinte linhas do arquivo original para
manter o mesmo cabeçalho no arquivo que criamos. No quarto comando removemos todas as linhas comentadas, chamando o arquivo
resultante de original.sem.comentarios. Esse vai ser um segundo arquivo reserva. No último comando retiramos as linhas repetidas, no
caso somente as linhas em branco, para que ficasse mais legível, e nomeamos o arquivo resultante de snort.conf - o arquivo que vamos
utilizar.
Antes de conhecermos a estrutura e a sintaxe de uma regra ou de montarmos a nossa própria, vamos nos preocupar em manter nosso
arquivo de configuração consistente com as regras de que dispomos. Para tanto, abra o snort.conf em um editor de textos, vá até seu
final, onde estão as linhas "include" e abra um gerenciador de arquivos qualquer para visualizar o conteúdo da pasta /etc/snort/rules.
include $RULE_PATH/bad-traffic.rules
include $RULE_PATH/exploit.rules
include $RULE_PATH/scan.rules
include $RULE_PATH/finger.rules
include $RULE_PATH/ftp.rules
include $RULE_PATH/telnet.rules
include $RULE_PATH/rpc.rules
include $RULE_PATH/rservices.rules
Como em um código de uma linguagem de programação, estas linhas apontam cada uma delas para um conteúdo que está em outro
arquivo. Estes arquivos, por sua vez, estão, como indicam as linhas, na pasta indicada pela variável $RULE_PATH. Lembrem que
atribuímos a essa variável o endereço da pasta /etc/snort/rules. Essas linhas apontam, pois, para arquivos contidos na nossa pasta de
regras.
Como o Snort lê o arquivo snort.conf para rodar e segue os caminhos apontados para os arquivos de regras, ocorreriam erros caso
houvesse 'includes' que apontassem para arquivos de regras que não existem. Portanto, é importante, antes de acionar o Snort, conferir
se as linhas de 'includes' apontam para arquivos de regras existentes. No caso de eles não existirem suas linhas devem ser comentadas
no snort.conf. Para tanto podemos comparar as linhas do snort.conf com os arquivos que vemos no diretório /etc/snort/rules/.
Fiz, para este curso, entretanto, um script que automatiza essa tarefa comentando as linhas do snort.conf que apontam para arquivos
inexistentes. No entanto, pode ser do seu interesse não comentar as linhas inadequadas do snort.conf, mas sim incluir no snort.conf
linhas que apontem para todos e somente para os arquivos de regras existentes. Outro script está disponível para esta função. Neste
caso, o Snort faria uso de todos os arquivos de regras disponíveis, e pode ser uma boa opção para quem precisa de um IDS completo.
Quem atualiza com frequência os arquivos de regras também podem fazer um bom uso desse script.
Os scripts podem ser encontrados na página principal do curso de Snort e também nas próximas páginas ainda nesta lição. As páginas
deste curso que contêm os códigos explicam como executá-los caso tenha dificuldades. Note que os scripts estão preparados para
procurar o snort.conf na pasta do snort /etc/snort e o diretório de regras em /etc/snort/rules. Caso sua configuração seja diferente,
altere o valor das variáveis no início do código.
Este script comenta automaticamente as linhas do snort.conf que apontam para arquivos de regras que não existem.
Copie seu conteúdo para um arquivo de nome, por exemplo, "comentador.sh" e, para utilizá-lo, digite como root:
$ chmod +x comentador.sh
$ ./comentador.sh
----------------------INICIO DO CODIGO-------------------------
#!/bin/bash
#Comenta as linhas do snort.conf que apontam para arquivos de regras no diretório rules/ que não existem.
ARQ_CONF="/etc/snort/snort.conf"
RULES_DIR="/etc/snort/rules"
ARQ_LISTA1="lista_de_includes_pura"
ARQ_LISTA2="lista_de_includes_gerada"
TEMPORARIO="snort.conf-temporario"
cat $ARQ_CONF | grep "include \$RULE_PATH" | awk -F'/' '{print $2}' > $ARQ_LISTA1
for i in $(cat $ARQ_LISTA1 )
do
if [ -e $RULES_DIR/$i ]
then
echo "include \$RULE_PATH/$i" >> $ARQ_LISTA2
else
echo "#include \$RULE_PATH/$i" >> $ARQ_LISTA2
fi
done
cat $ARQ_CONF | grep -v "include \$RULE_PATH" > $TEMPORARIO
cat $TEMPORARIO > $ARQ_CONF
echo '' >> $ARQ_CONF
cat $ARQ_LISTA2 >> $ARQ_CONF
--------------------------FINAL DO COGIDO----------------------------
Este script escreve no snort.conf uma linha de include para cada arquivo de regras existente no diretório de regras padrão. Copie seu
conteúdo para um arquivo de nome, por exemplo, "inclusor.sh" e, para utilizá-lo, digite como root:
$ chmod +x inclusor.sh
./inclusor.sh
----------------------------INICIO DO CODIGO---------------------------
#!/bin/bash
#Inclui no snort.conf uma chamada para cada arquivo de regras existente em rules/
ARQ_CONF="/etc/snort/snort.conf"
RULES_DIR="/etc/snort/rules"
ARQ_LISTA1="lista_de_regras_pura"
ARQ_LISTA2="lista_de_regras_gerada"
TEMPORARIO="snort.conf-temporario"
---------------------------FINAL DO CODIGO--------------------------------
snort.conf resultante
#--------------------------------------------------
# http://www.snort.org Snort 2.6.0 config file
# Contact: snort-sigs@lists.sourceforge.net
#--------------------------------------------------
# $Id$
#
###################################################
# This file contains a sample snort configuration.
# You can take the following steps to create your own custom configuration:
#
# 1) Set the variables for your network
# 2) Configure dynamic loaded libraries
# 3) Configure preprocessors
# 4) Configure output plugins
# 5) Add any runtime config directives
# 6) Customize your rule set
#
###################################################
# Step #1: Set the network variables:
#
var HTTP_PORTS 80
var AIM_SERVERS
[64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.18
8.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24]
var RULE_PATH rules
dynamicpreprocessor directory /usr/local/lib/snort_dynamicpreprocessor/
dynamicengine /usr/local/lib/snort_dynamicengine/libsf_engine.so
preprocessor flow: stats_interval 0 hash 2
preprocessor stream4_reassemble
preprocessor bo
preprocessor smtp: \
ports { 25 } \
inspection_type stateful \
normalize cmds \
normalize_cmds { EXPN VRFY RCPT } \
alt_max_command_line_len 260 { MAIL } \
alt_max_command_line_len 300 { RCPT } \
alt_max_command_line_len 500 { HELP HELO ETRN } \
alt_max_command_line_len 255 { EXPN VRFY }
include classification.config
include reference.config
include $RULE_PATH/local.rules
include $RULE_PATH/bad-traffic.rules
include $RULE_PATH/exploit.rules
include $RULE_PATH/scan.rules
include $RULE_PATH/finger.rules
include $RULE_PATH/ftp.rules
include $RULE_PATH/telnet.rules
include $RULE_PATH/rpc.rules
include $RULE_PATH/rservices.rules
include $RULE_PATH/dos.rules
include $RULE_PATH/ddos.rules
include $RULE_PATH/dns.rules
include $RULE_PATH/tftp.rules
include $RULE_PATH/web-cgi.rules
include $RULE_PATH/web-coldfusion.rules
include $RULE_PATH/web-iis.rules
include $RULE_PATH/web-frontpage.rules
include $RULE_PATH/web-misc.rules
include $RULE_PATH/web-client.rules
include $RULE_PATH/web-php.rules
include $RULE_PATH/sql.rules
include $RULE_PATH/x11.rules
include $RULE_PATH/icmp.rules
include $RULE_PATH/netbios.rules
include $RULE_PATH/misc.rules
include $RULE_PATH/attack-responses.rules
include $RULE_PATH/oracle.rules
include $RULE_PATH/mysql.rules
include $RULE_PATH/snmp.rules
include $RULE_PATH/smtp.rules
include $RULE_PATH/imap.rules
include $RULE_PATH/pop2.rules
include $RULE_PATH/pop3.rules
include $RULE_PATH/nntp.rules
include $RULE_PATH/other-ids.rules
include $RULE_PATH/virus.rules
include $RULE_PATH/experimental.rules
Variáveis
Conhecendo as variáveis
Bom, antes de mais nada, abram seus reespectivos snort.conf, que devem estar em /etc/snort, com qualquer editor de texto de sua
preferência (eu recomendo o vim para qualquer coisa e sempre!). Na medida em que eu for descrevendo as variáveis, vamos
adequando o snort.conf aos nossos usos particulares.
As variáveis básicas
Vamos primeiramente dar uma olhada nas variáveis do snort.conf de que falávamos. Entre em /etc/snort e abra o nosso arquivo
snort.conf com qualquer editor de textos.
As variável que Snort reconhece, como podemos esperar, são predefinidas. As variáveis que vemos acima são importantes para o
funcionamento do Snort, ainda que a boa configuração de três delas seja mais vital na medida em que são variáveis-chave. Elas são:
HOME_NET
EXTERNAL_NET
RULE_PATH
HOME_NET
Quando o valor declarado é any, significa que qualquer valor de tipo compatível com o da a variável será considerado um valor da
variável. Se HOME_NET, pois, vale "any" e a HOME_NET é a variável relativa à seção da rede a estar no escopo interno do Snort, então
qualquer interface de rede que for encontrada será analisada pelo Snort. Neste caso um pacote que sai de nossa máquina para um IP de
fora também é considerado interno ao Snort.
Talvez não queiramos incluir no escopo interno da vistoria do Snort quaisquer interfaces. Se quisermos incluir todas interfaces da rede
interna, temos de substituir "any" pelo endereço da rede interna. Alguns exemplos são:
var HONE_NET 192.168.0.0
var HOME_NET 192.168.1.0
var HOME_NET 10.0.0.0
var HOME_NET 172.16.0.0
Provavelmente, porém, também não queremos incluir toda uma rede interna no escopo da HOME_NET, e nesse caso, vamos querer
restringir sua seção. Para tanto, precisamos expecificar sub-redes com o padrão CIDR. Para saber mais, dê uma olhada nesta página
sobre o padão CIDR na wikipedia.
Uma definição como aquelas acima, que incluem toda rede interna, é o mesmo que os exemplos abaixo, utilizando CIDR:
var HONE_NET 192.168.0.0/32
var HOME_NET 192.168.1.0/32
var HOME_NET 10.0.0.0/32
var HOME_NET 172.16.0.0/32
Podemos definir sub-redes como:
var HOME_NET 192.168.0.0/16
var HONE_NET 192.168.0.0/24
var HOME_NET 192.168.0.0/26
var HOME_NET 192.168.0.0/28
Para determinar como HOME_NET somente a nossa própria máquina, porém, definimos, mais que naturalmente, o nosso próprio IP,
como por exemplo:
Note que, neste caso, o Snort não precisa trabalhar em modo promíscuo (ainda que ele o faça por padrão)!
Caso queiramos, o que é razoável, incluir mais de uma máquina, definimos uma lista separada por vírgula, sem espaços e entre
colchetes, como por exemplo:
var HOME_NET [192.168.0.2,192.168.0.3]
Analogamente, se queremos definir duas sub-redes distintas, ou mesmo uma máquina e uma sub-rede, fazemos, por exemplo:
var HOME_NET [10.0.0.1/24,192.168.0.0/24]
ou
var HOME_NET [10.0.0.1/24,192.168.0.2]
EXTERNAL_NET
A variável EXTERNAL_NET é reservada para a definição de que endereços serão reconhecidos como externos para o Snort. Podemos,
seguindo as mesmas regras sintáticas da definição da HOME_NET, definí-la seccionando a rede ou mesmo mantendo-a como "any". O
ideal, no entanto, talvez fosse simplismente definir EXTERNAL_NET como tudo aquilo que não é considerado interno pelo Snort, ou seja,
tudo aquilo que não for HOME_NET. Note, entretanto, que neste caso estará ignorando pacotes internos, correndo o risco de perder
detecções de ataques de dentro da própria rede. Para definir a rede externa como a negação do que seja a interna, enfim, podemos
utilizar o símbolo ' ! ' (exclamação), que significa a negação do valor que o segue. Para definir EXTERNAL_NET como sendo aquilo que
não é HOME_NET, basta definí-la como:
Tome somente o cuidado de não definir a EXTERNAL_NET como !$HOME_NET se antes definiu a HOME_NET como "any", pois neste caso
estaria informando que a rede externa é tudo que não é qualquer coisa, o que não é possível, visto que a sua rede externa tem de ser
alguma coisa. Caso queira fazer o Snort experimentar a vertigem de um paradoxo, faça-o e depois me conte o resultado. Provavelmente
um erro simples.
Como de se esperar, temos de utilizar o símbolo do cifrão ' $ ' antes de HOME_NET para estarmos referindo a variável HOME_NET, e não
à palavra HOME_NET.
RULE_PATH
A variável RULE_PATH não depende da sua rede nem do que queremos fazer com ela. Esta variável indica o caminho do diretório no seu
sistema de arquivos em que se encontram as regras que o Snort poderá utilizar. Dentre essas, indicaremos algumas ao final do arquivo
de configuração e adequaremos e faremos outras. Mas todos arquivos de regras indicados no final do snort.conf devem estar no mesmo
diretório. O caminho desse diretório deve ser o valor da variável RULE_PATH. Na instalação que sugeri, o diretório de regras fica em
/etc/snort, e seu caminho absotulo é /etc/snort/rules. A definição de RULE_PATH para essa instalação pode ser, portanto:
ou até mesmo
As outras variáveis
As outras variáveis dizem respeito aos servidores da sua rede e a algumas portas relevantes. Cada tipo de serviço possui uma variável
particular que deve apontar para o IP da máquina que o realiza. Se sua própria máquina que serve o Snort realiza um serviço, a
definição pode ser:
Regras
Introduzindo
Introdução às regras
Bom, tudo o que preparamos até então dentro do arquivo snort.conf, que foi adequar as variáveis às nossas condições, tem uma única e
exclusiva finalidade: a de permitir o funcionamento das regras comuns, como as três básicas e as que dizem respeito a serviços e
portas. Afinal, são essas regras que vão se utilizar das variáveis que definimos. Essas regras têm a função de decidir que processamento
um pacote vai sofrer e que caminho o dignóstico vai tomar, para que essas decisões sejam tomadas, as informações que colocamos nas
variáveis são fundamentais. Essas regras decidem, pois, sobre o valor que as variáveis a elas relevantes possuem. Note que qinda que a
maioria delas faça referência às variáveis HOME_NET e EXTERNAL_NET, somente algumas fazem referência às variáveis do endereço de
serviços específicos. Definir bem todas as variáveis permite que o Snort faça uma análise mais inteligente tendo em vista o destino dos
pacotes intrusivos, ao mesmo tempo que economiza seu processamento evitando que ele procure exploits para Web direcionados para o
servidor exclusivo de DNS.
Entendendo as regras
Assim como essas linhas de 'includes' estão apontando para outros arquivos, poderíamos perfeitamente simplismente colar em seus
lugares o conteúdo dos arquivos aos quais apontam. Utilizar arquivos distintos que são referenciados pelo snort.conf é, pois, uma
maneira de manter um arquivo de configuração mais organizado e regras mais fáceis de se manter e de atualizar. Fica claro porque
utilizar linhas que apontam para arquivos separados e não simplimente deixar todos códigos no mesmo arquivo se abrirmos um
arquivos de regra qualquer.
Abra, por exemplo, o arquivo de regras porn.rules. O caminho do arquivo, como sabemos, é /etc/snort/rules/porn.rules. Como podem
imaginar, as regras desse arquivos se destinam a reconhecer conteúdos de pacotes que vêm de sites pornográficos. Esse arquivo de
regras, apesar de engraçado e até constrangedor, revela de forma simples como as regras, em geral, operam. Sua função pode servir
muito bem a instituições decididas a retardar a difusão da pedofilia impedindo o acesso a sites pornográficos de dentro das redes, ou
mesmo pode servir a pais que querem saber se seus filhos vêem pornografia na internet. O exemplo é interessante pois é uma arquivo
de regras que busca por strings no payload dos pacotes, tendo um funcionamento intuitivo, portanto.
Com o porn.rules aberto, observe que a partir da linha 9 há uma regra por linha. A frente segue uma regra do arquivo recortada:
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"PORN erotica"; content:"erotic"; nocase; flow:to_client,established;
classtype:kickass-porn; sid:1798; rev:1;)
As informações escritas até os parênteses são parte do que chamamos de cabeçalho da regra, e o que vem dentro deles são as opções
da regra.
Aquilo que vem dentro dos parênteses e antes dos 'dois pontos' é chamado de palavra-chave.
• Com alert, esta regra diz ao Snort para gerar um alerta e logar;
• $var1 $var2 -> $var3 $var4 informa que os pacotes que interessam a esta regra são aqueles que vêm da rede de fora (no
caso, $var1) pelas portas que servem o protocolo http (no caso, $var2) e entram ( -> ) na rede interna (no caso, $var3) por
qualquer porta (any);
• msg é a palavra-chave que leva o alert do Snort a imprimir uma mensagem no alerta e nos logs. No caso, a mensagem é
"PORN erotica";
• content informa ao Snort que string será procurada dentro do payload do pacote.
• flow:to_client,established indica, no caso, que o pacote vai em direção ao cliente da conexão e que o estado desta é
estabelecido;
• Sid e Rev respectivamente se referem ao número de identificação da regra e ao número de sua revisão.
Montando regras
Vamos tentar montar uma regra para Snort extremamente simples, mas funcional, para tentarmos ganhar alguma familiaridade com o
desenvolvimento de regras. Aquelas pessoas que gostam de programar, entendem de protocolos de rede e que gostam do Snort,
podem, quem sabe, partir daqui para uma pesquisa aprofundada de como se desenvolve regras especais para o Snort.
Bom, vamos dizer que gostaríamos de saber quantas vezes em nossa rede parece o nome do atual presidente do Brasil, Lula, e de que
ips vêm os pacotes em que ele aparece. Digamos, por exemplo, que quiséssemos essa informação para uma pesquisa.
Abra, portanto, o seu snort.conf com qualquer editor de textos e vá até o seu final. Para conseguir o que queremos precisamos gerar
um alerta, que é uma das ações que uma regra pode realizar. A, em geral, mais interessante e certamente a mais comum. Nossa regra
começa, portanto, com a ação alert.
alert
Note que até a última versão do Snort todas as regras tinham que ser escritas em uma única linha, mas que agora podemos continuá-
las na linha seguinte se 'escaparmos' o salto de linha com o caractere ' \ ' ao final de cada linha.
Depois de alert informamos que tipo de protocolo constitui a conexão dos pacotes em que estamos interessados(as). Como vamos
procurar por pacotes relativos a conexões web, a um site, então o protocolo dos nossos pacotes será o tcp regular.
alert tcp
Em seguida, como já vimos em nosso exemplo de regra, vem os ips e portas de origem e de destino dos pacotes. Em nosso caso,
queremos encontrar pacotes que saiam de nossa rede, portanto podemos informar o ip de origem como qualquer um que venha de
nossa rede, a definida em $HOME_NET e o ip de destino como qualquer um que saia de nossa rede, a definida em $EXTERNAL_NET. A
porta de destino é a 80, e a de saída podemos definir como qualquer uma, any. Veja como está a nossa regra até então:
O que acabamos de escrever foi o cabeçalho de nossa regra. Agora precisamos abrir parenteses e escrever as opçoes da regra, que são
sempre iniciadas por palavras-chave. Estamos interessados(as) no uso de duas palavras-chave em particular: a content e a msg. Com
'content' definiremos que string procurar, e com 'msg' definiremos que mensagem aparecerá no alerta que será gerado para nos.
Como procuramos por aparições da string Lula, podemos informar a palavra-chave content com a string Lula. A mensagem que
queremos que apareça pode ser algo como "La vem 'Lula' pelo cabo de rede!". Adapte esta frase caso esteja em uma rede wireless!
Nossa regra fica:
alert tcp $HOME_NET any -> $EXTERNAL_NET 80 (content: "Lula"; msg: "La vem 'Lula' pelo cabo de rede!";)
Nossa regra pode ser considerada pronta. Como vimos, podemos adicionar um indicador do tipo de alerta em que os alvos dessa regra
devem se encaixar, podemos dar um valor de identificação para a regra e setar a sua prioridade frente às outras. Este tipo de
informação tem de ser previa e adequadamente configurada dentro do arquivo classification.config. As pessoas interessadas realmente
deviam dar uma olhada na documentação oficial.
Mais tarde neste curso vamos ter a oportunidade testar nossa regra.
Comentador de snort-rules.sh
#!/bin/bash
#Comenta as linhas do snort.conf que apontam para arquivos de regras no diretório rules/ que não existem.
ARQ_CONF="/etc/snort/snort.conf"
RULES_DIR="/etc/snort/rules"
ARQ_LISTA1="lista_de_includes_pura"
ARQ_LISTA2="lista_de_includes_gerada"
TEMPORARIO="snort.conf-temporario"
cat $ARQ_CONF | grep "include \$RULE_PATH" | awk -F'/' '{print $2}' > $ARQ_LISTA1
for i in $(cat $ARQ_LISTA1 )
do
if [ -e $RULES_DIR/$i ]
then
echo "include \$RULE_PATH/$i" >> $ARQ_LISTA2
else
echo "#include \$RULE_PATH/$i" >> $ARQ_LISTA2
fi
done
cat $ARQ_CONF | grep -v "include \$RULE_PATH" > $TEMPORARIO
cat $TEMPORARIO > $ARQ_CONF
echo '' >> $ARQ_CONF
cat $ARQ_LISTA2 >> $ARQ_CONF
inclusor de includes.sh
#!/bin/bash
#Inclui no snort.conf uma chamada para cada arquivo de regras existente em rules/
ARQ_CONF="/etc/snort/snort.conf"
RULES_DIR="/etc/snort/rules"
ARQ_LISTA1="lista_de_regras_pura"
ARQ_LISTA2="lista_de_regras_gerada"
TEMPORARIO="snort.conf-temporario"
Rodando o Snort
Os logs
Uma última configuração que vai nos interessar por hora é o destino dos diagnósticos, os logs. Os logs, além de poderem ser enviados
para o console em tempo real, podem ser tanto armazenado em arquivos quanto escritos em tabelas de um banco de dados. O arquivo
pode ser escrito tanto em alertas quanto em formato tcpdump. Este formato não é legível sem uma ferramenta como o ethereal ou o
próprio Snort.
Existem outras formas de gerar outputs com o Snort, dêem uma olhada nesta página da documentação on-line. Aqueles já
familiarizados com o syslog podem se interessar em utilizar o syslog como gerenciador dos logs do Snort. A documentação é bastante
completa.
#Para logar os alertas no arquivo de alerta regular, descomente ou escreva a linha a seguir e substitua os valores:
output alert_unified: filename <arquivo>, limit <tamanho máximo do arquivo, em MB>
#Para o snort colocar os resultados em um banco de dados mysql, descomente a seguinte linha e substitua os valores:
Os modos de funcionamento
Existem pelo menos quatro modos de funcionamento do Snort. Segundo a própria documentação oficial, eles são:
• Modo sniffer (Sniffer mode): neste modo o Snort simplesmente lê interpreta os pacotes capturados da rede e os apresenta no
console em tempo real.
• Modo de logger de pacotes (Packet Logger mode): neste modo o Snort loga os pacotes lidos no disco, de acordo com o método
de output anteriormente selecionado.
• Modo detector de intrusão (Network Intrusion Detection System (NIDS) mode): neste modo o Snort não somente captura e lê
pacotes, seja para apresentá-los no console ou para logá-los em disco, rodando neste modo o Snort analisa e interpreta os
pacotes segundo as assinaturas e toma as decisões de acordo com as regras definidas. Este é modo completo do Snort, em que
ele realiza aquilo que o temos preparado para realizar.
• Modo Inline (Inline Mode): neste modo o Snort não utiliza a biblioteca de captura de pacotes libpcap diretamente, mas lê os
pacotes capturados pelo Iptables, o que permite a automatização de decisões de IDS ativas, como descartar ou autorizar
pacotes. Para tanto existem regras especiais inline. O uso deste modo não vai ser explicado neste curso.
Enfim, rodando
Vamos experimentar alguns comandos que fazem o Snort rodar naqueles três primeiros modos apresentados. Vamos conhecer alguns
de seus parâmetros para adequar o Snort aos nossos interesses. Abra um terminal como root e vamos lá.
Testando o Snort
Com este comando simples o snort carrega o snort.conf, confere as linhas ativas, a referência dos includes interpreta as variáveis e
relata se houve algum erro no carregamente. Este parâmetro solicita ao Snort que teste sua própria configuração.
Entre outras informações, as linhas impressas durante o carregamento do Snort revelam a interface sendo utilizada e a versão do Snort.
Conhecendo os parâmetros
Possivelmente o somando simples 'snort' vá mostrar uma lista de parâmetros para uso. Caso não mostre, podemos ver a lista com o
comando:
snort --help
Vendo a versão
Para saber a versão instalada do Snort basta, porém, utilizar o parâmetro -V:
$ snort -V
$ snort <uso> -D
Para utilizar o Snort fora do modo promíscuo setamos o parâmetro -p. Este parâmetro somente será interessante caso a variável
$HOME_NET tenha sido definida com o próprio ip da máquina que serve o Snort, pois nesse caso não interessa a ele os pacotes
destinados a outras máquinas senão o localhost.
$ snort <uso> -p
Podemos querer carregar o Snort com um arquivo de configuração alternativo que tenhamos construído para teste, por exemplo. Neste
caso, na chamada do Snort devemos indicar a ele o caminho do arquivo com o parâmetro -c. Neste caso o Snort funcionaria em modo
NIDS, que conheceremos logo adiante.
Vamos conhecer mais parâmetros na medida em que formos conhecendo seus outros dois modos de funcionamento.
Modo sniffer
$ snort -v
Com o comando acima acionamos o Snort para rodar no modo sniffer. Observe como ele simplismente captura os pacotes que
atravessam a interface em modo promíscuo e apresenta o seus cabeçalhos, seja parte do protocolo TCP, UDP ou ICMP, e somente os
cabeçalhos.
Nos cabeçalhos podemos ler os ips e portas de origem e destino, o protocolo e o Snort também nos informa a hora e data da captura.
Podemos também querer ver, mais do que os cabeçalhos, os dados da camada de aplicação. Para tanto adicionamos o parâmetro -d:
$ snort -vd
Com este parâmetro enxergamos não somente os cabeçalhos, mas o conteúdos dos pacotes que podem conter, por exemplo, strings
digitadas claras, se conexão não era criptografada.
Por último, podemos também querer ver os dados dos cabeçalhos da camada de enlace adicionando o parâmetro -e:
$ snort -dev
$ snort -e
Para terminar a captura de pacotes com o modo sniffer, basta digitar <Ctrl>+c. Ao final de uma sessão de captura, algumas
informações interessantes são apresentadas, como a quantidaed de pacotes capturados, a porcentagem de aparição de cada protocolo,
e quantos alertas e logs foram gerados.
Modo logger
Este modo de funcionamento, como foi explicado, se destina a permitir que as informações que vemos no modo sniffer sejam
logadas, seja em arquivos texto, binário ou em bancos de dados.
Este modo se baseia em um único parâmetro a ser adicionado aos parâmetro de sniffing -v (verbose). É o parâmetro -l de log. O
comando mais simples que faz o Snort rodar em modo logger seria:
Simplismente logando
$ snort -v -l <diretório>
Caso omitisse o <diretório>, o Snort provavelmente logaria a saídas em uma pasta com endereço do localhost ou em pastas de
acordo com os ips que originaram os pacotoes.
Podemos, exatamente por causa dessa lógica do Snort, pedir que ele logue as saídas em uma estrutura de diretórios divida por
endereços de origem. Para tanto, passamos o parâmetro -h seguido da sessão da rede a ser considerada:
Logando em tcpdump
Como já sabemos, podemos também arquivar os logs não em arquivos planos, mas em arquivos binários no formato do
tcpdump.
$ snort -l <diretório> -b
Quando logamos em formato tcpdump não precisamos nem informar o parâmetro -v nem informar o home network com -h, pois
com -b o Snort loga por padrão todo o pacote não precisando separar em sessões legíveis e automaticamente organiza os logs.
Para ler os arquivos em tcpdump gravados podemos pedir que o Snort nos mostre as informações que queremos de dentro dos
logs com o parâmetro -r. Por exemplo:
$ snort -dev -r <arquivo.log>
Mais que isso, podemos pedir que nos mostre somente os pacotes icmp adicionando ICMP no final do comando:
Logando em ASCII
Quando não especificamos a formatação do texto (com a opção -K), o Snort cria logs usando PCAP. Dessa forma, não podemos
ler os arquivos com um simples editor de texto, temos de usar programas como o Ethereal. Para podermos ler os arquivos com
editores de texto, usamos '-K ascii', como no exemplo:
Modo NIDS
Este é certamente o modo mais complexo do Snort, pois envolve etapas mais sofisticadas do que aquelas de um simples sniffer
de rede. É também exatamente isso que faz do Snort uma ferramenta especial. As etapas que o modo de NIDS inclui são a
análise dos pacotes segundo as assinaturas, os diagnósticos e as tomadas de decisão sobre o output de acordo com os
diagnósticos dados. As duas últimas etapas são alta e, em alguns casos, facilmente configuráveis através das definições de
regras contidas no ou apontadas pelo snort.conf.
Como neste modo o Snort consome muito mais processamento, é mais eficiente rodá-lo sem o parâmetro -v que o faz direcionar
as saídas para a tela. Pois o esforço de imprimir em tela as saídas, além do de escrever os logs, pode fazer com que o Snort
deixe passar alguns pacotes por debaixo do seu nariz por falta de tempo. É bom, portanto, deixar ele se concentrar em sua
função de análise e de log e utilizar outro programa para a vistoria dos logs.
Este modo é inciado a partir do parâmetro -c, que especifica um arquivo de configuração do Snort a ser lido. O comando, em um
formato simples é:
$ snort -d -c snort.conf
Neste caso, como não definimos arquivo de log, os logs irão para /var/log/snort. Como não definimos o tipo de log, ele será
escrito em texto simples. Podemos, no entanto, tornar a chamada mais elaborada:
Alertas
Por padrão o Snort no modo NIDS arquiva o log dos pacotes e gera de vez em quando logs especiais chamados alertas, que são
logs de aviso de aparentes tentativas de ataque ou vistoria para ataque. Esses logs de alerta são gravados por padrão no
arquivo /var/log/snort/alert. Quando não especificamos preferências quanto aos alertas, como nos comandos acima, o Snort
funciona no modo que chamamos de full alert.
Por padrão, digitar um comandos comos os digitados acima é o mesmo que digitá-los acompanhados do parâmetro -A full:
Outros modos de alertas interessantes são o modo que desabilita alertas, o '-A none', o modo que envia os alertas para o
console (além, possivelmente, dos logs regulares), o '-A console', e modo de análise e log rápidos, o '-A fast'.
Notas finais
Conferindo os alertas
Enfim temos uma boa oportinidade de testar a regra que criamos. Como é uma única regra e foi escrita dentro do nosso arquivo
snort.conf, não precisamos deixá-la na pasta de regras.
Bom, entremos na linha de comando e vamos botar pra rodar nosso Snort no modo NIDS deixando-o logar no diretório padrão
todos os alertas.
$ snort -A full -c snort.conf
Agora, enquanto o Snort roda, abra um navegador qualquer e procure em um site de busca por notícias sobre o presidente Lula.
Abra alguns sites que falem sobre ele, navegue um pouco nas notícias e depois de um tempo feche a aba do navegador e
retorne para o console.
$ cat /var/log/snort/alert
Outros aplicativos
Como já comentado no curso, existem programas que podem auxiliar e muito o uso do Snort. Existem basicamente três
atividades ou funções em que o Snort pode ser auxiliado:
Com 'ativo' quero dizer que um IDS poderia tomar medidas de segurança a partir dos resultados dos logs. O Snort, no entanto,
é passivo na medida em que simplismente loga eventos, mas não bloqueia ips nem normalmente impede de forma alguma que
os ataques aconteçam.
Aqui vai pois a sugestão de três programas destinados a satisfazer cada uma das funções listadas acima. Caso pense em
implementar a sério o Snort, considere bem essas ferramentas pesquisando sobre elas.
1 - Barnyard
O Snort analisa pacote por pacote, procurando aqueles que se encaixam em alguma regra configurada. Antes de passar para o
próximo pacote, o Snort pode precisar gerar um log e/ou um alerta sobre esse pacote. Se, por exemplo, o Snort estiver
escrevendo no banco de dados diretamente, ele precisa esperar a confirmação da escrita no banco antes de analisar o próximo
pacote. Em redes de grande tráfego, esse tempo da confirmação pode fazer com que o Snort deixe de analisar algum pacote, o
que deterioraria a confiabilidade do programa. E se o banco de dados cair, o Snort cai também.
O Barnyard foi feito para contornar esse problema. Você configura o Snort para escrever em um arquivo, e o Barnyard cuida de
jogar os dados desse arquivo para o banco, deixando o Snort livre para a análise de pacotes.
2 - Oinkmaster
Oinkmaster é um programa que gerencia as regras usadas pelo Snort. Ele baixa o arquivo, descompacta, faz backup das regras
antigas e oferece outras facilidades. Enfim, ele nos ajuda a gerenciar as regras.
3 - Guardian
Segundo a própria descrição do site oficial, o Guardian é um programa de que trabalho em conjunto com o Snort para atualizar
automaticamente regras de firewall de acordo com os alertas gerados pelo Snort.
As regras de firewall geradas bloqueiam todos dados que vêm de endereços de máquinas que estão realizando ataques segundo
os diagnóstico dos alertas.
Existem recursos, no entanto, que previnem que o iptables termine bloquando o endereço de máquinas importantes e amistosas.