IDS en la red: SNORT
SNORT ([Roe99]) es un sniffer capaz de actuar como sistema
de detección de intrusos en redes de tráfico moderado; su facilidad de
configuración, su adaptabilidad, sus requerimientos mínimos (funciona
en diferentes Unices, incluyendo un simple PC con Linux, Solaris o cualquier
BSD gratuito),
y sobre todo su precio (se trata de un software completamente gratuito
que podemos descargar desde su página oficial en INet, http://www.snort.org/) lo convierten en una óptima elección en multitud de
entornos, frente a otros sistemas como NFR (Network Flight Recorder) o
ISS RealSecure que, aunque quizás sean más potentes, son también mucho
más pesados e infinitamente más caros.
Para instalar un sistema de detección de intrusos basado en SNORT
en primer lugar necesitamos evidentemente este programa, que podemos descargar
desde su página web. Además, para compilarlo correctamente es
necesario disponer de las librerías libpcap, un interfaz para
tratamiento de paquetes de red desde espacio de usuario, y es recomendable
también (aunque no obligatorio) instalar Libnet, librería para
la construcción y el manejo de paquetes de red. Con este software
correctamente instalado en nuestro sistema, la compilación de SNORT es
trivial.
Si volvemos a la clasificación de IDSes que hemos presentado al principio
de este capítulo, podemos clasificar a SNORT como un sistema basado
en red (se monitoriza todo un dominio de colisión) y que funciona mediante
detección de usos indebidos. Estos usos indebidos - o cuanto menos sospechosos - se reflejan en una base de datos formada por patrones de
ataques; dicha base de datos se puede descargar también desde la propia
página web de
SNORT, donde además se pueden generar bases de patrones `a medida' de
diferentes entornos (por ejemplo, ataques contra servidores web, intentos
de negaciones de servicio, exploits...). El archivo que utilicemos en
nuestro entorno será la base para el correcto funcionamiento de nuestro
sistema de detección de intrusos.
Una vez hemos compilado e instalado correctamente el programa llega el momento
de ponerlo en funcionamiento; y es aquí donde se produce - al menos
inicialmente - uno de los errores más graves en la detección de intrusos.
Por lógica, uno tiende a pensar que el sensor proporcionará mejores
resultados cuantos más patrones de ataques contenga en su base de datos;
nada más lejos de la realidad. En primer lugar, es muy probable que no todos
los ataques que SNORT es capaz de detectar sean susceptibles de
producirse en el segmento de red monitorizado; si situamos el sensor en una
zona desmilitarizada donde únicamente ofrecemos servicio de web, >qué
interés tiene tratar de detectar ataques contra DNS? Lo lógico es que
las políticas implementadas en nuestro cortafuegos ni siquiera dejen
pasar tráfico hacia puertos que no sean los de los servidores web pero,
incluso en caso de que el potencial ataque se produjera entre máquinas del
propio segmento, hemos de evaluar con mucho cuidado si realmente vale la pena
sobrecargar la base de datos con patrones que permitan detectar estos ataques.
Evidentemente, cuanta más azúcar más dulce, pero si el sensor ha de
analizar todo el tráfico, quizás mientras trata de decidir si un paquete
entre dos máquinas protegidas se adapta a un patrón estamos dejando pasar
tramas provenientes del exterior que realmente representan ataques: hemos de
tener presente que el sniffer no detendrá el tráfico que no sea
capaz de analizar para hacerlo más tarde, sino que simplemente lo dejará
pasar. Así, debemos introducir en la base de patrones de ataques los
justos para detectar actividades sospechosas contra nuestra red.
En segundo lugar, pero no menos importante, es necesario estudiar los
patrones de tráfico que circulan por el segmento donde el sensor escucha
para detectar falsos positivos y, o bien reconfigurar la base de datos, o bien
eliminar los patrones que generan esas falsas alarmas. Aunque suene algo crudo,
si un patrón nos genera un número considerable de falsos positivos, debemos
plantearnos su eliminación: simplemente no podremos decidir si se trata de
verdaderas o de falsas alarmas. Esto es especialmente crítico si lanzamos
respuestas automáticas contra las direcciones `atacantes' (por ejemplo,
detener todo su tráfico en nuestro firewall): volviendo al ejemplo de
la zona desmilitarizada con servidores web, podemos llegar al extremo de
detener a simples visitantes de nuestras páginas simplemente porque han
generado falsos positivos; aunque en un entorno de alta seguridad quizás
vale la pena detener muchas acciones no dañinas con tal de bloquear también
algunos ataques (aunque constituiría una negación de servicio en toda
regla contra los usuarios que hacen uso legítimo de nuestros sistemas), en
un entorno normal de producción esto es impensable. Seguramente será más
provechoso detectar y detener estos ataques por otros mecanismos ajenos al
sensor.
En resumen, hemos de adaptar a nuestro entorno de trabajo, de una forma muy
fina, la base de datos de patrones de posibles ataques. Quizás valga la
pena perder tiempo el tiempo que sea necesario en esta parte de la
implantación, ya que eso nos ahorrará después muchos análisis de
falsas alarmas y, por qué negarlo, algún que otro susto; una vez tengamos
todo configurado, podemos utilizar el siguiente script para lanzar SNORT de forma automática al arrancar el sistema (Solaris):
anita:~# cat /etc/init.d/snort
#!/sbin/sh
#
# Instalacion:
# # cp <script> /etc/init.d/snort
# # chmod 744 /etc/init.d/snort
# # chown root:sys /etc/init.d/snort
# # ln /etc/init.d/snort /etc/rc2.d/S99snort
#
# Directorio de log
DIRLOG=/var/log/snort
# Fichero de reglas
RULES=/usr/local/security/snort.conf
# Ejecutable
SNORT=/usr/local/security/snort
# Interfaz
IF=hme0
case "$1" in
'start')
if [ ! -d "$DIRLOG" ]; then
mkdir -p "$DIRLOG"
fi
if [ ! -r "$RULES" ]; then
echo "No puedo leer el fichero de patrones..."
exit -1
fi
if [ ! -x "$SNORT" ]; then
echo "No encuentro el ejecutable..."
exit -1
fi
$SNORT -l $DIRLOG -c $RULES -i $IF -N -D
;;
'stop')
if [ ! -r "/var/run/snort_$IF.pid" ]; then
echo "No puedo obtener el PID..."
exit -1
fi
kill -TERM `cat /var/run/snort_$IF.pid`
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
esac
exit 0
anita:~#
Con el sensor y sus patrones correctamente configurados ya estamos listos
para poner en funcionamiento nuestro sistema de detección de intrusos.
Seguramente hasta ahora no hemos tenido muchos problemas con el IDS; no
obstante, a partir de ahora las cosas se empiezan a complicar un poco, ya que
comienza la segunda parte, la del tratamiento de la información que nuestro
sensor nos va a proporcionar. Y es que desde este momento el sistema de
detección va a empezar a funcionar y a generar logs con notificaciones
de posibles ataques, o cuanto menos de actividades sospechosas; es hora de
decidir cosas como dónde situar al sensor, qué hacer ante la generación
de un evento en el mismo, cómo procesar la información recibida, o
simplemente cuándo rotar los logs generados.
El último de los problemas planteados realmente tiene fácil solución;
>cuándo rotar los logs que SNORT genera? La respuesta es muy
sencilla: depende. Depende de la cantidad de informes generados en nuestro
sensor, depende de la frecuencia con la que debamos realizar informes de los
ataque sufridos, depende de la implementación elegida para ejecutar
respuestas automáticas ante un ataque (si las ejecutamos), etc. En definitiva,
la rotación correcta de unos logs es algo que se debe estudiar y
planificar para cada entorno concreto, no se puede dar un periodo estricto que
se aplique siempre porque sería sin duda erróneo. No obstante, una idea
que nos puede ayudar en la toma de esta decisión es la siguiente: rotaremos
los logs cuando los hayamos procesado y extraído de ellos la
información que nos pueda interesar para proteger nuestro entorno.
SNORT genera logs en el directorio /var/log/snort/ si no
le indicamos lo contrario (podemos hacerlo con la opción `-l' del
programa). En ese directorio encontraremos un fichero denominado alert
con las actividades que se vayan registrando, y, si no hubiéramos especificado
la opción `-N' al arrancar el programa, una serie de subdirectorios
cuyos nombres son las direcciones IP de las máquinas de las que se detecta
alguna actividad (es el denominado `packet logging'). Como nosotros lo
que buscamos es básicamente la generación de alarmas, independiente del
packet logging, no necesitamos generar estos directorios (aunque nada
nos impide hacerlo).
El siguiente shellscript planificado convenientemente con crontab
(si lo ejecutamos más de una vez durante el día quizás nos interese
afinar la variable $FECHA) puede ser utilizado para realizar la
rotación del archivo de alarmas generado por SNORT:
anita:~# cat /usr/local/security/rotalog
#!/bin/sh
#
# Directorio de log
DIRLOG=/var/log/snort
# Fecha (DD/MM/YY)
FECHA=`date +%d.%m.%Y`
# Interfaz
IF=hme0
if [ ! -d "$DIRLOG" ]; then
mkdir -p "$DIRLOG"
fi
cd $DIRLOG
mv alert alert-$FECHA
touch alert
chmod 600 alert
kill -HUP `cat /var/run/snort_$IF.pid`
compress alert-$FECHA
anita:~#
Independientemente de la rotación de logs que llevemos a cabo en
cada sensor, suele resultar interesante centralizar todos los logs
generados en un sólo sistema (a veces se le denomina maestro o master),
aunque sólo sea para realizar estadísticas, seguimientos de máquinas
atacantes y atacadas, o simplemente un `top ten' de piratas. Para ello
podemos establecer relaciones de confianza entre los sensores y ese maestro
para que puedan conectarse entre sí sin necesidad de contraseñas y,
de forma automática, transferir los logs almacenados y rotados. Por
supuesto, a estas alturas dicha relación no la estableceremos mediante la
definición de máquinas confiables en archivos .rhosts o similares, ni
con las herramientas r-, sino mediante SSH y las claves
públicas y privadas de cada máquina. Aparte de una mayor seguridad (no
autenticamos a una máquina simplemente por su dirección o nombre, algo
fácilmente falseable), siguiendo un mecanismo de este estilo conseguimos que
todas las comunicaciones entre sistemas se realicen de forma cifrada, algo que
aquí es muy importante: cualquier información relativa a potenciales
ataques o respuestas automáticas a los mismos se ha de considerar como
confidencial, por lo que sería un grave error echar todo nuestro trabajo
a perder simplemente porque alguien sea capaz de esnifar dicho tráfico.
Volviendo a nuestras cuestiones iniciales, también debíamos decidir
dónde situar lógicamente al sensor; por ejemplo, una cuestión típica
es si debemos emplazarlo detrás o delante del firewall que protege a
nuestra red. En principio, si dejamos que el sensor analice el tráfico antes
de que sea filtrado en el cortafuegos, estaremos en disposición de detectar
todos los ataques reales que se lanzan contra nuestra red, sin ningún
tipo de filtrado que pueda detener las actividades de un pirata; no obstante,
probablemente lo que más nos interesará no es detectar todos estos intentos
de ataque (aunque nunca está de más permanecer informado en este sentido),
sino detectar el tráfico sospechoso que atraviesa nuestro firewall y
que puede comprometer a nuestros servidores. Por tanto, es recomendable
([Con99]) emplazar el sensor de nuestro sistema de detección de
intrusos en la zona protegida; de cualquier forma, los potenciales ataques que
no lleguen al mismo quedarán registrados en los logs del cortafuegos, e
incluso serán neutralizados en el mismo.
Como el sensor ha de analizar todo el tráfico dirigido a las máquinas
protegidas, si nos encontramos en un entorno donde dichas máquinas se conecten
mediante un concentrador (hub) o mediante otras arquitecturas en las que
cualquiera de
ellas vea (o pueda ver) el tráfico de las demás, no hay muchos problemas
de decisión sobre dónde situar al sensor: lo haremos en cualquier parte del
segmento. Sin embargo, si nuestros sistemas se conectan con un switch la
cuestión se complica un poco, ya que en las bocas de este elemento se verá
únicamente el tráfico dirigido a las máquinas que estén conectadas a
cada una de ellas; en este caso, tenemos varias opciones. Una de ellas puede
ser modificar por completo - con todo lo que esto implica - nuestra
arquitectura de red para integrar un concentrador por el que pasen los paquetes
ya filtrados antes de llegar a las máquinas del switch, tal y como
se muestra en la figura 18.2. No obstante, suelen existir alternativas
más sencillas y cómodas, como la replicación de puertos que se puede
configurar en la mayoría de switches; la idea es muy simple: todo
el tráfico dirigido a determinada boca del switch se monitoriza y se
duplica en otra boca. Así, no tenemos más que configurar este port mirroring y replicar la boca por la que se dirige el tráfico hacia el
segmento de máquinas a monitorizar, enviándolo también a una segunda boca
en la que conectaremos nuestro sensor.
Figura 18.2:
Situación del sensor
|
Para acabar con los comentarios sobre dónde y cómo situar al sensor de
nuestro sistema detector de intrusos, un último apunte: quizás nos conviene
recordar que el interfaz por el que se analiza el tráfico (hablando claro,
por el que se esnifan las tramas) no tiene por qué tener dirección IP.
Perfectamente podemos tener un interfaz levantado e inicializado pero sin
asignarle ninguna dirección. Esto nos puede resultar útil si no nos interesa
que en el segmento protegido se detecte una nueva máquina, o simplemente si
no queremos que nuestro sensor sea alcanzable de alguna forma por el resto
de sistemas de su dominio de colisión. Para nuestra comodidad (por ejemplo,
a la hora de centralizar logs de diferentes sensores) podemos usar una
máquina con dos interfaces, una escuchando todo el tráfico y la otra
configurada de forma normal, que será por la que accedamos al sistema.
© 2002 Antonio Villalón Huerta