Suricata IDS - Jugando con las reglas

Publicada en Publicada en Linux, Redes, Securización

Buenas a todos! Hace poquito que saqué mi entrada anterior, pero ante la gran aceptación que ha tenido (muchas gracias!) aquí estoy de vuelta 🙂 Hoy vamos a seguir con Suricata IDS realizando un pequeño recorrido por el sistema de reglas.

En la entrada anterior habíamos definido exitosamente una regla que nos avisaba siempre que Suricata viese un paquete ICMP entrando y saliendo, introduciendo en nuestro fichero de reglas en /etc/suricata/rules/custom.rules la siguiente línea:

alert icmp any any -> any any (msg: "ICMP detected";)

¡Pero esto hace mucho ruido! Muchas veces los administradores harán ping a máquinas (o no, dependerá del sitio, no me peguéis :P) en local para comprobar conectividad. Realmente, lo que seguramente queramos es comprobar si se nos ha colado algún ICMP de algún lugar no autorizado (aunque esto sería más del ámbito IPS para denegar ese paquete). Podemos inventarnos los escenarios que queramos más o menos adecuados, pero para un breve ejemplo nos vale 🙂

Lo primero que haremos será definir nuestra red local dentro de Suricata. Eso nos servirá para saber si un paquete inspeccionado viene de dentro de nuestra red, o por el contrario de alguna externa (u otra subred). Debemos editar el fichero /etc/suricata/suricata.yaml de forma que definamos la variable HOME_NET de la siguiente forma:

Definición de nuestra HOME_NET en suricata.yaml

Hemos introducido, como se puede ver, la subred 192.168.65.0/24 como valor de HOME_NET. Esto establecerá que todo paquete proveniente de dicha subred será considerado como nuestra red local. Más abajo podemos ver asimismo la variable EXTERNAL_NET, que establecerá lo que consideramos explícitamente como red externa. En nuestro caso, y de forma predeterminada, está establecida como !$HOME_NET, que referencia a cualquier red que no sea la que hemos definido como local.

Hecho esto, podemos editar un poco más nuestro fichero de reglas. Editamos con nuestro custom.rules de la siguiente forma:

alert icmp $HOME_NET any -> $EXTERNAL_NET any (msg: "Outbound ICMP detected"; sid:1; rev:1; classtype:icmp-custom-event;)

alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg: "Inbound ICMP detected"; sid:2; rev:1; classtype:icmp-custom-event;)
Reglas de control ICMP

Con esto podremos hacer dos cosas:

  • La primera regla establece que se alerte con un mensaje "Outbound ICMP detected" cada vez que se localice un paquete ICMP hacia el exterior.
  • La segunda regla establece que se alerte con un mensaje "Inbound ICMP detected" cada vez que se localicec un paquete ICMP hacia el interior.

Vemos que hemos establecido en ambas reglas algunos parámetros adicionales:

  • sid: Esto le da un identificador numérico a la regla. Es buena práctica darle uno a cada regla, dado que si no a veces puede dar problemas.
  • rev: Acompañando al sid, le da un valor de revisión a la regla (si se cambian constantemente viene bien llevar un control).
  • classtype: A partir de una definición de classtype en el fichero de configuración /etc/suricata/classification.yaml, podemos establecer clasificaciones de reglas. En nuestros visores de logs aparecerá el valor Classification y su prioridad asociada, facilitando mucho el parseo.

Por tanto, nos falta algo; definir el classtype en el fichero /etc/suricata/classification.yaml. Podemos simplemente situarnos al final del fichero y escribir la siguiente línea:

config classification: icmp-custom-event, ICMP event,2
Clasificación de eventos ICMP

Como vemos, son tres campos a rellenar:

  • El identificador de la clasificación, en este caso icmp-custom-event.
  • El mensaje a imprimir en los logs como category, en este caso ICMP event.
  • La prioridad de la clasificación, en este caso 2. Podemos ir variando el valor de menor a mayor en función de su severidad o lo importante que consideremos que es la alerta, de 1 a 255.

Nota: Ya existe de forma predeterminada una clasificación icmp-event, pero estamos aprendiendo a definirlo todo nosotros! 😛

Una vez guardado esto, recargaremos (que no reiniciaremos, aunque también valdría, pero eso equivale a una pérdida de servicio en lo que vuelve a levantarse) el servicio:

sudo systemctl reload suricata

Vemos a continuación el resultado dentro de los visores de eventos fast.log y eve.json (dejando fuera en este último las entradas de estado):

Prueba de las reglas de control ICMP

Podéis ver destacado (en rojo oscuro, para no quedarnos ciegos) elementos importantes de nuestras reglas. He dividido las marcas en los dos pings para que se ve mejor, pero se ve que los datos son los mismos:

  • En el primer ping (ida y vuelta) podéis ver destacadas las IPs origen y destino; se puede ver cómo en el primero el origen es nuestra red local, y el destino, el servidor DNS de Google, está en el exterior. En el segundo, es a la inversa.
  • En el segundo ping (idas y vuelta) podéis ver destacados datos de nuestra regla: el sid o identificador con su rev o revisión, el mensaje definido en la regla dentro de signature, la categoría ICMP Event  y su prioridad nivel 2 asociada.

¡Pues todo parece haber ido bien! 🙂 Ahora probaremos algo más complicado, configurando la siguiente regla en custom.rules:

alert tcp 192.168.65.133 any -> any !80 (app-layer-protocol: http; msg: "HTTP but not port 80"; sid:3; rev:1;)

Esta regla hace lo siguiente:

  • Comprobar que el origen del paquete es nuestra IP (en nuestro caso y en nuestr máquina es la 192.168.65.133), y el destino es cualquiera con puerto diferente a 80.
  • Comprobar que el protocolo de aplicación es HTTP.
  • Si coincide, generar una entrada de log con mensaje "HTTP but not port 80).

Esto nos puede servir para detectar conexiones desde una IP hacia cualquier sitio utilizando protocolo HTTP en un puerto diferente al 80, por ejemplo aplicaciones extrañas o incluso malware (se suele ver mucho en adwares).

Para la prueba, podemos ejecutar en otra máquina virtual a la que tengamos acceso desde Suricata el siguiente comando para levantar un servidor HTTP simple en python3 en el puerto 8000, diferente al 80 y por tanto sospechoso:

python3 -m http.server

Ahora podemos simplemente acceder a este servidor simple desde la máquina con Suricata con un explorador web y ver las entradas de log en eve.json: 

Pruebas con la regla de detección de tráfico HTTP extraño

Vemos que correctamente ha detectado la conexión e imprime una buena cantidad de valiosos datos acerca de la petición HTTP.

Hasta aquí un breve recorrido por las reglas de Suricata y los campos que considero más importantes para su gestión 🙂 Espero que lo aprovechéis bien y os sirva para aprender! Un saludo!!

PD: Aquí tenéis la entrada anterior:

Suricata IDS - Instalación, puesta en marcha y primera prueba

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *