martes, 25 de noviembre de 2008

Port Knocking: Despistando a los intrusos

Hola!

Hoy vamos a ver una técnica que nos va a venir de perlas para, de algún modo, encubrir los servicios que corren en nuestra maquina.

Imaginemos que tenemos un PC que actúa como servidor, y en el tenemos instalado un FTP (wu_ftpd por ejemplo, que tiene bastantes vulnerabilidades en según que versiones). Cualquiera que hiciera un barrido de puertos con nmap podría ver que tenemos un precioso puerto 21 abierto, incluso podría averiguar que versión de FTP utilizamos con el mismo nmap o a través de telnet.
Esto empieza a ser preocupante, una sola búsqueda en bugtraq, SecurityFocus o MilWorm podria poner los dientes largos a nuestro atacante y poner en jaque nuestra seguridad.

El caso es que a nmap no es fácil engañarlo, porque si un puerto esta filtrado, lo va a detectar igual, pero no va a saber que servicio corre en el. Ejemplo:

Resultado de nmap con puerto 22 abierto:



Resultado de nmap con puerto 22 filtrado con iptables:


Como podemos ver, en el primer caso no solo ha averiguado que usamos OpenSSH, incluso ha sabido que SO utilizamos!!!
En el segundo caso hemos filtrado las conexiones con una sencilla regla de iptables:

slayer@Erhard:~$ sudo iptables -A INPUT -s ip-que-permitimos -p tcp --dport 22 -j ACCEPT

Así solo pasa esa IP por el puerto 22, ademas si hacemos:

slayer@Erhard:~$ sudo iptables -A INPUT -p tcp --dport 22 -j DROP

Ahí ya no entra ni Dios.

Todo esto es muy bonito, pero claro, tiene una pega ¿¿Como voy a saber yo desde que IP me voy a conectar a mi servidor SSH?? Cada vez que me conecte desde fuera voy a tener
una IP publica distinta, y si filtro por una IP que no tengo no me voy a conectar.

¿Como solucionamos esto?


Con Port-Knocking, una técnica mediante la cual, haciendo una "llamada" a determinados puertos con un determinado orden nos abre el puerto de un servicio conocido, como SSH o FTP.

Nosotros por defecto vamos a cerrar el puerto 22 a todo ser viviente:

slayer@Erhard:~$ sudo iptables -A INPUT -p tcp --dport 22 -j DROP

Y a continuación, con netcat, abrimos un puerto alto, el 5000, el cual, al conectarnos, abrirá el puerto 6000 durante 10 segundos. Esto de los 10 segundos tiene un sentido, si alguien nos sniffara veria que conectamos con el puerto 5000, el único abierto, y finalmente que nos conectamos a ssh, pero no podrá conectarse a el, entonces tratara de hacer un nuevo barrido con nmap, y vera el puerto 5000 abierto y el 22 cerrado, como el 6000 solo ha estado 10s abierto ni llegara a detectarlo... ;) (todo esto lo podemos complicar haciendo la llamada a mas puertos... of course)

slayer@Erhard:~$ sudo nc -l -p 5000 -c "nc -l -p 6000 -q 10 -e 'sshon.sh'" >/dev/null 2>&1 &

Con esta instrucción conseguimos nuestro propósito, y ademas, al conectarnos al puerto 6000 este ejecutara un script llamado sshon.sh que podría tener un contenido como este:

#!/bin/bash
#sshon by SLaYeR
#Open especific port in IpTables

IP=`netstat | grep 5000 | awk '{print $4}' | cut -d: -f1`
PORT=22
iptables -D INPUT -p tcp --dport $PORT -j DROP
iptables -A INPUT -S $IP --dport $PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $PORT -j DROP
if [ $? == 1 ]; then
echo "Debes de ser root para ejecutar el comando"
fi

Que si observáis lo que hace es recoger la IP que se conectó al puerto 5000, eliminar la anterior regla que deniega el trafico al puerto 22, nos habilita el acceso desde la nueva IP y vuelve a denegar el resto de trafico.

Así, para conectarnos a SSH, primero, mediante netcat conectaríamos con el puerto 5000, a continuación con el 6000 y después (mejor desde otra consola) conectaríamos con SSH:

slayer@Erhard:~$ sudo nc xxx.xxx.xxx.xxx 5000 && nc xxx.xxx.xxx.xxx 6000 && ssh slayer@xxx.xxx.xxx.xxx

Podemos hacerlo mediante este comando o con varios terminales. Solo recordaros, que esta regla seguirá vigente hasta que la eliminemos, así que o bien esperáis a llegar a casa para quitarla, o en lugar de cerrar sesión con SSH, elimináis la regla que os da acceso y ya os echa el solito...XD