Detectando y deteniendo escaneos de red: PortSentry

Enumerar los servicios que se exponen en una red, es uno de los primeros pasos que cualquier hacker que se precie de tal ejecutara al infiltrarse; un escaneo de puertos, identificar servicios para luego encontrar alguna vulnerabilidad que permita el acceso o la explotación del mismo.

Para hacerle la vida mas a estos muchachos, existen los llamados honeypots, servicios creados con el único fin de al ser accedidos por alguien que intenta enumerar o explotar una red, se nos envié una alerta o se tome una contra medida para detener al atacante. En general, estos sistemas son independientes de cualquier otro servicio de la red e incluso corren en ambientes mas controlados para evitar filtraciones.

Hoy instalaremos PortSentry uno de los mas simples y fáciles de configurar, pero que actuara de forma implacable contra cualquier ataque que registre. Es una aplicación bastante veterana y que no recibe actualizaciones hace bastante, pero la realidad es que no las precisa, hace lo que tiene que hacer de una forma efectiva y si esta correctamente configurado casi no tiene falsos positivos.

Hoy, instalaremos esta aplicación desde los repositorios de Debian 9 (Stretch), pero sus fuentes están disponibles en la pagina del proyecto del cual surge, Sentry Tools y son muy simples de compilar en cualquier sistema.

Instalando PortSentry

Primero, veremos como compilarlo desde las fuentes para luego ver su instalación desde los repositorios de Debian y continuar con la configuracion que sera generica a todos los sistemas.

wget -O portsentry-1.2.tar.gz https://sourceforge.net/projects/sentrytools/files/portsentry%201.x/portsentry-1.2/portsentry-1.2.tar.gz/download
tar zxvf portsentry-1.2.tar.gz
cd portsentry_beta

Para la compilacion, deberemos elegir el sistema en el cual lo instalaremos, para ver la lista disponible, bastara con ejecutar el comando make sin pasarle parametros. Para nuestro caso, utilizaremos el sistema «linux»

Antes de compilar, deberemos solucionar un pequeño problema en el codigo donde hay un salto de linea que no deberia estar, para esto buuscaremos la linea 1584 y borraremos el salto de linea al final de esta, para que el contendido de la misma quede de esta manera

printf ("Copyright 1997-2003 Craig H. Rowland \n");

Después procederemos a compilar e instalar ignorando los warnings que son solo temas de prolijidad en el código que a los compiladores de no les gusta y no errores reales.

make linux
make install

Este tipo de instalación, usara como raíz la ruta «/usr/local/psionic/portsentry/», dato a tener en cuenta para la parte de configuración ya que esta la haremos en base a los directorios del instalador para Debian y estos no coinciden.

Para la instalación en Debian/Ubuntu, simplemente ejecutaremos el comando

apt-get install portsentry

Debian Rules!!!

Este instalador, nos generara las carpetas necesarias, ademas de los scripts de inicio necesarias, siendo «/etc/portsentry» la que nos interesara en este caso, ya que contiene los archivos de configuración de la aplicación.

Configurando PortSentry

La aplicación esta configurada para no hacer absolutamente nada por defecto, ya que cada sistema es único y no hay una configuración que funcione universalmente.
Como parámetros iniciales, la aplicación escucha en puertos que normalmente no son utilizados y solo loguea violaciones al syslog local sin tomar acciones de ningún tipo.

Veamos el archivo de configuración principal «/etc/portsentry/portsentry.conf» (si compilaron la aplicación, este estara en «/usr/local/psionic/portsentry/portsentry.conf») y los parámetros con los cuales modificaremos su comportamiento.

TCP_PORTS y UDP_PORTS: En este parámetro, definiremos los puertos que querramos utilizar para que la aplicación escuche conexiones y alerte o bloquee al equipo desde el que se genero la misma, por defecto, ya tendremos cargados datos para estos valores. Se ignoran si la aplicación levanta en modo stealth o advanced.

ADVANCED_PORTS_TCP y ADVANCED_PORTS_UDP: Estos parámetros hacen que la aplicación escuche en todos los puertos por debajo del indicado, solo quitando los que estén en el momento de su ejecución ocupados por otra aplicación, por defecto, se escuchara en todos los puertos por debajo de 1024. Solo están disponibles si se levanta en modo stealth o advanced.

RESOLVE_HOST: Este parametro intentara reslver el nombre del atacante usando Reverse DNS para mostrarlo en las alertas. Por defecto esta desactivado.

BLOCK_TCP y BLOCK_UDP: Este parámetro define que hacemos con el «atacante», los valores para este parametro son 3, 0 para solo loguear la conexión, 1 para bloquear la ip de origen y 2 para solo ejecutar una aplicación (alerta de otro tipo o incluso otro tipo de bloqueo que no este definido, por ejemplo si queremos ser muy paranoicos, bloquear la misma ip en todos los equipos de la red. Por defecto esta en «0».

KILL_ROUTE: Este es uno de los parametros que hace que la magia ocurra, aqui definiremos el comando con el que bloquearemos la ip atacante, ya sea con una ruta que envie el trafico a un agujero negro (o un nullroute que queda mas lindo) «/sbin/route add -host $TARGET$ reject», creando una regla para nuestro firewall preferido (iptables, ipfw, ipchains o el que querramos realmente). Por defecto se usa el nullroute ya que es compatible con la mayoria de las distribuciones.

KILL_HOSTS_DENY: Como si no fuera suficiente, podremos bloquear tambien al agresor utilizando «TCP Wrappers», esto hara que su ip sea agregada al archivo hosts.deny. Con este metodo, podriamos restringir algun servicio en particular en caso de que dropear la ruta sea muy extremo. Por defecto, se bloquean todos los servicios.

KILL_RUN_CMD_FIRST: Este parámetro, configura el orden en que se ejecutan los pasos, con el valor «0» primero se bloqueara al atacante para después ejecutar el comando externo en caso de tenerlo configurado, el valor «1» invertirá el orden. Por defecto, su valor es «0».

KILL_RUN_CMD: Aqui configuraremos un comando a correr (antes o despues del bloqueo, segun lo configurado en el parametro anterior), podremos utilizar las variables $TARGET$ (IP atacante), $PORT$ (puerto escaneado) y $MODE$ (TCP o UDP) creadas por PortSentry para pasarselas a nuestro script. Aqui podríamos utilizar un script para enviarnos la alerta por correo por ejemplo.

SCAN_TRIGGER: Este parametro define la cantidad de veces que un ip puede conectarse a un puerto sin generar respuesta o alarma. Por defecto esto esta en «0», subir demasiado (mas de 1 o 2) haria que el programa no tuviese mucha utilidad.

PORT_BANNER: Aquí podremos configurar el mensaje que podremos pasarle al atacante para intentar disuadirlo de continuar con el escaneo, si esta usando algo automatizado, probablemente ni lo vea.

Por ultimo, configuraremos el modo en el que iniciaremos nuestra aplicación, para esto, modificaremos el o los parámetros en el archivo «/etc/default/portsentry», TCP_MODE y/o UDP_MODE, aquí podremos iniciar en modo normal (espera conexiones establecidas de forma normal SYN/SYN ACK/SYN ACK) utilizando los valores tcp o udp, stealth (los mismo que el anterior pero también detectando las conexiones stealth SYN/SYN ACK/RST) con stcp o sudp o en modo advanced (bindeandose a todos los puertos por debajo del definido en DVANCED_PORTS_TCP) utilizando atcp o a udp.

Ahora solo nos queda iniciarlo, para debian, al tenerlo configurado como un servicio podremos ejecutar simplemente

service portsentry start

Para las demas distribuciones, se debera ejecutar (dependiendo del modo en el que se quiera iniciar modificando los parametros)

/usr/local/psionic/portsentry/portsentry -tcp -udp

Testeando nuestro sistema

Para nuestros tests, utilizaremos dos equipos, el «atacante» sera la ip 10.181.0.211 y como nuestra damisela en peligro, estara la 10.181.0.203.

Para la primer prueba, utilizaremos el modo de solo alertar en el modo tcp escuchando en el puerto 6667. configuraremos solo estos parametros en nuestro conf y luego reiniciaremos la aplicación.

TCP_PORTS="6667"
BLOCK_TCP="0"
SCAN_TRIGGER="0"
PORT_BANNER="** ACCESO DENEGADO *** SU INTENTO DE ACCESO HA SIDO REGISTRADO."

Ejecutaremos ahora un ping desde el atacante, luego un connect al puerto 6667 (utilizando el viejo y querido telnet) y volveremos a probar conectividad con un ping.

portsentry attack block

Esto activara la alerta en nuestro server, pero solo la logueara a nuestro archivo de syslog sin tomar ninguna accion

portsentry defender logonly

 

 

Para nuestra segunda prueba, utilizaremos el mas extremo de los casos y bloquearemos al usuario con un nullroute, para esto usaremos los siguientes parametros.

TCP_PORTS="6667"
BLOCK_TCP="1"
KILL_ROUTE="/sbin/route add -host $TARGET$ reject"
SCAN_TRIGGER="0"
PORT_BANNER="** ACCESO DENEGADO *** SU INTENTO DE ACCESO HA SIDO REGISTRADO."

Y realizaremos la misma prueba, ping, connect, ping, donde veremos que luego del connect, nuestro server dejara de contestar cualquier paquete que provenga del atacante.

portsentry block attack nullroute

En nuestro server, veremos la alerta generada, el aviso del bloqueo y la ruta cargada con la ip del atacante

portsentry defend log nullroute
portsentry defend nullroute

Si queremos sacar la ip de la lista negra y volverle a dar acceso, deberemos eliminar la ruta y reiniciar la aplicación.

route del -host 10.181.0.211 reject

Por ultimo, bloquearemos el equipo utilizando «TCP Wrappers», en este modo, el equipo respondera pings, pero cualquier servicio que este publicado, sera inaccesible para el atacante. Para esta prueba, utilizaremos un simple telnet al puerto de SSH como prueba de servicio.

portsentry attack tcp wrappers

Como vemos, el SSH deja de reportar datos al estar bloqueado por TCP Wrappers, pero el ping y connect al puerto 22 que se manejan a menor nivel, siguen respondiendo.
En nuestro server veremos el log y la ip atacante en el archivo /etc/hosts.deny

portsentry defend tcp wrappers log
portsentry defend hosts deny

Para desbloquear la ip atacante en este caso, deberemos borrar del archivo «/etc/hosts.deny» la linea que la contenga (en nuestro ejemplo «ALL: 10.181.0.211 : DENY»)

Y eso seria todo, ya tenemos nuestro honeypot para detectar y/o bloquear escaneos ofensivos.

PS: Si se quisiera hacer esto mas paranoico, podríamos mover nuestro SSH de puerto y poner en su lugar a PortSentry, esto haría que cualquiera que intente conectarse por SSH sin saber de nuestro cambio, sea bloqueado (aunque puede ser un arma de doble filo)

Deja un comentario