Monday, October 27, 2008

Golpeando las puertas del cielo PortKnocking

Golpeando Las puertas del infierno (o del cielo)
Introduccion simple al Port Knocking


Vamos a tomar una definicion de PortKnocking, que esta en la wikipedia

El golpeo de puertos (del inglés port knocking) es un mecanismo para
abrir puertos externamente en un firewall mediante una secuencia
preestablecida de intentos de conexión a puertos que se encuentran
cerrados. Una vez que el firewall recibe una secuencia de conexión
correcta, sus reglas son modificadas para permitir al host que realizó
los intentos conectarse a un puerto específico.
El propósito principal del PK es prevenir un escanéo de puertos por
parte de un atacante que busca posibles servicios vulnerables. Como
los los mismos solo se abren ante un pk correcto, los puertos donde se
brindan los servicios se muestran aparentemente cerrados.
Por lo general este mecanismo se implementa configurando un demonio
para que revise la bitácora o log del firewall para detectar esta
secuencia de intentos de conexión. Otra forma es tener un proceso
examinando paquetes con alguna interfaz de captura de paquetes, pero
esto tiene que hacerse en puertos TCP que se encuentren "abiertos".
El mayor uso del PK es para determinar acceso al puerto 22, el puerto
del Secure Shell (SSH). El golpeo en cuestión es similar a un
handshake secreto. La complejidad del mismo puede variar desde una
simple lista ordenada de intentos de conexión a puertos TCP, UDP, ICMP
u otro protocolo; hasta un hash basado en la dirección origen, tiempo
y otros factores, el cual determinará cuáles serán los puertos a
golpear.
Para la implementación, la idea es que el cliente tenga una aplicación
que ejecute el golpeo antes de acceder al servidor de manera normal.
Un demonio se encuentra escuchando en la máquina donde está el
firewall los paquetes que llegan a la misma. El utilitario del
cliente, responsable de realizar el golpeo de los puertos puede ser
desde un sencillo programa que ejecute comandos de ping, hasta un
complejo programa generador de un hash.
Generalmente no hay ninguna indicación cuando un usuario ejecuta una
secuencia errónea de PK. Simplemente el puerto que se esperaba
estuviese abierto al final de la secuencia, no lo está. Ningún paquete
es enviado al usuario en ningún momento.
A pesar de que esta técnica no ha sido ampliamente adoptada por la
comunidad, ha sido integrada en los rootkits más recientes.


Cuando habla de los rootkits, como el suckit, permiten abrir una
puerta trasera, mediante el envio de mensajes icmp.


Todos sabemos que cuando debemos proteger un puerto de los ataques de
internet, tenemos la opcion de filtrarlos, via iptables. Algunos
puertos pueden ser filtrados, para un grupo de ips, pero otros
como smtp, web, se complica aun mas.

Mas alla que con la web, podamos validar a ciertas direcciones ips
para entrar, podamos validar con usuarios/contraseñas, lo mas comun es
que un servidor web este publicando para todo el mundo. Pero
que un servidor ssh, este escuchando para todo el mundo, es algo muy
peligroso. Yo habia comentado, que uno puede utilizar reglas de
validaciones mediante ips. por ejemplo


iptables -t filter -A INPUT -s localhost -d localhost -p icmp -j ACCEPT
iptables -t filter -A INPUT -s localhost -d localhost -p udp -j ACCEPT
iptables -t filter -A INPUT -s localhost -d localhost -p tcp -j ACCEPT
iptables -t filter -A INPUT -p tcp -s 200.200.200.200 --dport 22 -j ACCEPT
iptables -t filter -A INPUT -j DROP


Con esto estariamos aceptando a 200.200.200.200 a nuestro ssh, pero
que pasa si tenemos una ip dinamica, o una notebook que pueda intentar
ingresar al puerto de ssh, desde una ip dinamica, u otra ip,
que no necesariamente sea conocida?.

Podriamos utilizar un servicio de dns dinamicos, como dyndns,
loguearnos, y luego tener algo asi como

iptables -t filter -A INPUT -p tcp -s mguazzardo.dyndns.org --dport 22
-j ACCEPT

Para ingresar con la direccion asociada a mguazzardo.dyndns.org.


Lo otro, es utilizar Port Knocking. Si bien esta nota esta basada en
portKnocking, existen varios programas e implementaciones, algunas
mejor que otras. Voy a hablar de Knockd, por la sencillez de este.


Para los que no lo conocen, les comento el programa
knockd, es basicamente, port knocking, hay que golpear antes de entrar
El programa, se activa por capa de aplicacion, y mediante mensajes
icmp modificados.
Se instala en el server, donde por ejemplo, podriamos tener cerrados
para todos, el ssh.
En el cliente, tambien se instala el paquete

debian:~# apt-get install knockd
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias... Hecho
Se instalarán los siguientes paquetes NUEVOS:
knockd
0 actualizados, 1 se instalarán, 0 para eliminar y 9 no actualizados.
Se necesita descargar 0B/26,4kB de archivos.
Se utilizarán 115kB de espacio de disco adicional despuÃ(c)s de desempaquetar.
Seleccionando el paquete knockd previamente no seleccionado.
(Leyendo la base de datos ...
52952 ficheros y directorios instalados actualmente.)
Desempaquetando knockd (de .../knockd_0.5-1.1_i386.deb) ...
Configurando knockd (0.5-1.1) ...
Not starting knockd. To enable it edit /etc/default/knockd



Ahora supongamos, que tenemos cerrado, mediante una regla como esta.




iptables -t filter -A INPUT -j DROP



y yo quisiera entrar, entonces, deberia a mi ip, cuando ejecuto el
cliente, dejarme entrar via ssh


entonces...

una vez instalado en el servidor, debemos configurar el archivo /etc/knockd.conf

por defecto, este viene con esta configuracion

[options]
logfile = /var/log/knockd.log

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEP
T
tcpflags = syn

[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEP
T
tcpflags = syn


Lo que dice, que para abrir el ssh, hay que mandar la secuencia de
ports 7000 8000 9000
(Esta secuencia puede ser cambiada).


****************** en el cliente, ejecutamos ***************


pepe:~# knock 192.168.19.129 7000 8000 9000
pepe:~# ssh 192.168.19.129
root@192.168.19.129's password:
Linux debian 2.6.18-6-686 #1 SMP Sun Feb 10 22:11:31 UTC 2008 i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
debian:~# exit
logout
Connection to 192.168.19.129 closed.
pepe:~# knock 192.168.19.129 9000 8000 7000

**************************************************************************************************

Para cerrarlo, como dice ahi, habria que mandar 9000 8000 7000

Yo voy a poner , en mi reglas de iptables, la siguiente, para abrir

command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

Para no tener problemas con el Orden de Matcheo.

Recomendaciones Adicionales al ssh.

Una recomendacion adicional que realizo yo, es cambiar el puerto de
ssh por default. Esto se cambia en el archivo /etc/ssh/sshd_config

para cambiar el puerto, hacemos lo siguiente

# What ports, IPs and protocols we listen for
#Port 22
Port 22222

Por ejemplo, para ponerlo en el 22222

Despues, existen otras clausulas interesantes. Algo muy piola, seria
que los usuarios tuvieran que loguearse pero no como root, o sea,
denegar el acceso de root via ssh.

#PermitRootLogin yes
PermitRootLogin no

Tambien, podria pedir que solo dos usuarios ingresaran. marcelo, y ariel

AllowUsers marcelo, ariel

Luego, para que todo funcione como debe ser, recordemos que tenemos
que reiniciar el demonio, para hacerlo, lo hacemos

debian:~# /etc/init.d/sshd restart
Y ahi todos los cambios seran tomados!.

Conclusion:

Si bien se puede encontrar mucha mas informacion de port Knocking en
la web, esta ha sido solo una introduccion a esta interesante tecnica.
Saludos

No comments: