Modo paranoia: Port-Knocking y Latch para fortificar tus sistemas

martes, 26 de enero de 2016

La fortificación de los sistemas es algo que día a día es un quebradero de cabeza para muchos sysadmins. Entendemos la fortificación de sistemas al proceso en el cual se configuran diferentes medidas de seguridad, configuraciones y procesos con el objetivo de que agentes externos no puedan acceder a nuestros sistemas. El objetivo es claro: proteger nuestros activos tanto en confidencialidad, integridad y disponibilidad.
 
En muchas ocasiones, los servicios tienen que estar expuestos, es decir, tienen que estar disponibles en cualquier momento. Un ejemplo claro es un servidor web, éste debe estar disponible el mayor tiempo posible ofreciendo información a los usuarios. En un servidor no solo se ejecutan servicios que deben estar disponibles el mayor tiempo posible, también disponemos de servicios de gestión, como por ejemplo VPN, SSH, incluso FTP, etcétera. Estos servicios son críticos y el simple hecho de que estén expuestos pone en riesgo gran parte de la gestión de la organización.
 
No es una situación nueva que haya bots realizando ataques de fuerza bruta contra servicios, de los llamados de gestión, expuestos en Internet. Tal y como se puede leer en el artículo "SSH Brute Force – The 10 Year Old Attack That Still Persists", no es algo nuevo y puede tener un ratio de éxito mayor de lo deseado.
 
Figura 1: Ataques automatizados contra servicios SSH
 

Una solución conocida en el mundo de la seguridad informática es el Port-Knocking. Para definir la técnica se utilizará un ejemplo. Imaginemos que un administrador de sistemas quiere acceder al menos una vez al día por SSH a sus sistemas para comprobar que todo está correctamente o realizar cualquier otra gestión. El administrador no quiere que el servicio SSH esté expuesto constantemente. El Port-Knocking le permite configurar la posibilidad de utilizar un puerto no Well-Known, por ejemplo, para "tras golpear" el puerto conseguir que el servicio SSH esté accesible desde Internet. En otras palabras, el puerto 22 de SSH se encontrará cerrado, pero cuando el administrador envíe, por ejemplo, un paquete TCP a un puerto concreto será la señal necesaria para activar el servicio SSH en el puerto 22. El puerto 22 de SSH solo estará abierto mientras dure la conexión del administrador de sistemas. Una vez se cierre dicha conexión, de nuevo el puerto quedará oculto. Esto es interesante, ya que el nivel de exposición queda rebajado al mínimo.

En Eleven Paths hemos querido realizar una prueba de concepto ampliando las miras del Port-Knocking utilizándolo como un primer factor de autenticación. Para ello, utilizaremos el valor de la dirección IP de origen y el valor del puerto como clave. Es decir, la suma de la dirección IP origen que aparezca en el paquete TCP, como el valor del puerto destino que aparezca en el mismo paquete formarán la clave.

PoC: Ejemplo sencillo. Paso 1

Como puede visualizarse en la siguiente imagen, el usuario envía un paquete TCP utilizando la técnica IP Spoofing para falsear la dirección IP origen. Es parte de la clave, por lo que el sistema en algún lado tendrá registrado que dirección IP origen es válida para pasar parte de la autenticación. El puerto destino es la otra parte de la clave, por lo que también debe ser esperado por el sistema. Este mecanismo es extensible a utilizar cualquier flag dentro del protocolo TCP.

Figura 2: Port-Knocking con IP Spoofing

Una vez se valida que la dirección IP es la esperada y el puerto al que se dirige el paquete también, por ejemplo el 9000, se activa el servicio SSH en el puerto 22. Como nota aclaratoria, el puerto 9000 no se encuentra a la escucha en nuestro ejemplo. Tenemos una aplicación escrita en Ruby con la que se "sniffa" el tráfico y se detecta a que puerto va dirigido y con qué dirección IP origen. Esto es importante, ya que si se hiciera un escaneo desde el exterior el puerto 9000 saldría cerrado, es decir, nuestro servidor devolvería el flag RST.
 
Como se puede entender fácilmente el nivel de exposición ha disminuido exponencialmente, y además se ha configurado un factor de autenticación jugando con campos del datagrama IP y del paquete TCP.
 
PoC: Si me "sniffan" el paquete tengo un problema. Paso 2
 
La autenticación va sin ningún cifrado, por lo que si alguien captura el paquete que enviamos a nuestro servidor tendríamos un serio problema. Tendrían el mecanismo de autenticación que utilizamos para activar el servicio de SSH, en este caso. A nuestro factor de autenticación podremos sumarle uno de autorización, es decir, una vez que nuestra pequeña aplicación identifique al usuario a través de la dirección IP necesitaremos de un nuevo factor que nos de permiso a acceder al servicio SSH.
 
En el siguiente código se puede visualizar un pequeño ejemplo dónde se ve claramente el código de autenticación y la integración con Latch.  
 
Figura 3: Integración de Latch para factor de autorización
 
PoC: Un nuevo factor con Latch. Esta vez de autorización. Paso 3
 
Integrando Latch para que una vez autenticado el paquete se compruebe si existe autorización podemos evitar la utilización de una copia de nuestro paquete TCP. La idea es sencilla: si Latch tiene el cerrojo echado significará que, aunque el paquete sea correcto, no se está autorizado a utilizar el recurso, por lo que no se lanzará el servicio SSH. Si por el contrario, el cerrojo está abierto significará que tenemos permiso para lanzar el servicio SSH y será ejecutado. Se ha incluido un tiempo de Delay configurable, es decir, el servicio SSH será lanzado a los X segundos. 
 
Figura 4: Latch como factor de autorización para activar servicio
 
PoC: Ejemplo completo. Paso 4
 
Por último vamos a suponer un escenario real en el que un servidor ejecuta la aplicación Ruby que gestiona la autenticación y autorización con 2 mecanismos distintos. En el primer caso querremos ejecutar SSH, para ello se ejecuta la herramienta hping3 para genera un paquete TCP con IP Spoofing y con puerto destino que nos interesa. Cabe destacar que podemos utilizar los flags que nos interesen dentro de un protocolo interno nuestro.
 
Figura 5: Paquete TCP con dirección IP spoofeada y puerto destino
 
Como se puede ver a nuestro servidor llegará un paquete TCP con dirección IP falsa, que es utilizada para identificar, y un puerto que es la otra parte de la clave. Lógicamente, el servidor contestará a la dirección IP, pero no habrá conexión de ningún tipo, ya que no tiene sentido. Nuestro código validará, mediante las condiciones si es un paquete válido de autenticación y se irá al otro factor, en este caso el de autorización.
 
Figura 6: Apertura del cerrojo de Port-Knocking Sysadmin
 
En este instante la aplicación confirmará que se tiene autorización para acceder al recurso y poder lanzarlo. Una vez que esto ocurre se puede leer, en local, el mensaje "Open Sesame". Ahora el usuario podrá, una vez superado el tiempo de espera, acceder al recurso SSH.
 
¿Una vez que acabemos de utilizar el servicio SSH, qué ocurre? Sencillo. En primer lugar se debe cerrar el cerrojo de la aplicación en Latch. Después, con la aplicación hping3 se puede generar un paquete con la siguiente instrucción hping3 -a [dirección IP falsa] -A -p 9000 -c 1 [dirección IP real]. El flag A indica que se envía un ACK, mientras que antes se activaba el flag de SYN. En este momento se reconoce que se quiere cerrar el servicio y se procede a la parada del servicio. En todo momento el sysadmin tiene el control sobre la exposición del servicio de gestión, lo cual es una suma importante para la seguridad del entorno.
 
Recuerda que aún estás a tiempo para participar en el concurso de plugins de Latch. Ideas como éstas pueden servirte de inspiración para desarrollar tu plugin y ganar el premio en bitcoins. ¡Anímate a participar! Tienes de plazo hasta el 15 de Febrero. Además, recuerda que también tenemos un concurso de plugins de Sinfonier.
 
 
Pablo González
pablo@11paths.com





4 comentarios:

  1. El tema de utilizar la IP como parte de la clave para iniciar el proceso está bien, pero qué pasa si estás en una red externa (Tu en Nueva York y Yo en California). Supongo que este paquete no atraviesa los routers al no ser de una dirección válida de la red, no? Cómo se salva este obstáculo? O está pensado para que el sysadmin esté en la propia red?

    ResponderEliminar
  2. Hola Fernando,

    Como bien dices: en LAN funciona sin problemas.

    En Internet dependerá del proveedor de red. Generalmente se haría un control de direcciones IP y sesiones de cada usuario, para evitar, por ejemplo, IP Spoofing. Si tu proveedor de red no realiza esta comprobación podría ser válido.

    El caso de la clave es simbólico, podrías utilizar distintos flags o incluso una secuencia de puertos, etcétera.

    Gracias, un saludo.

    ResponderEliminar
    Respuestas
    1. Perfecto, gracias por responder. La opción de los flags me parece acertada, sería algo algo así como utilizar un canal encubierto. Esto también me lleva a pensar que se podría utilizar el campo de secuencia de IP / TCP ya que suelen ser aleatorios durante el establecimiento de conexión.

      Buen post. Un saludo!

      Eliminar
  3. Se podría utilizar el campo de datos como hace SPA para autenticar y ampliar las funciones: http://www.cipherdyne.org/fwknop/

    Single Packet Authorization retains the benefits of Port Knocking (i.e. service protection behind a default-drop packet filter), but has the advantages listed below over over Port Knocking. For a complete treatment of all fwknop design goals, see the fwknop tutorial.

    SPA can utilize asymmetric ciphers for encryption
    SPA is authenticated with an HMAC in the encrypt-then-authenticate model
    SPA packets are non-replayable
    SPA cannot be broken by trivial sequence busting attacks
    SPA only sends a single packet over the network
    SPA is much faster

    ResponderEliminar