martes, noviembre 29, 2016

My SSH in Paranoid Mode: Port-knocking + Latch + Latch Cloud TOTP (+ Latch + Touch ID)

Fortificar un sistema puede ser algo difícil hoy día. Seguir buenas prácticas, cumplir con los requisitos de Mínimo Privilegio Possible, Mínima Superficie de Exposición, y Defensa en Profundidad proteger la confidencialidad, la integridad y la disponibilidad de la información exige mucho trabajo, que va desde proteger las identidades digitales, utilizar segundos factores de autenticación a un largo etcétera de condiciones que debemos cumplir para constituir un ecosistema lo más seguro posible. Los SysAdmin lo tienen difícil, pero la protección de activos es un trabajo interesante, a la par de constructivo.

Figura 1: My SSH in Paranoid Mode: Port-Knocking + Latch + Latch Cloud TOTP ( + Latch)

En muchas ocasiones, los servicios deben estar expuestos, es decir, éstos tienen que estar disponibles en cualquier instante. Por ejemplo, un servidor web debe encontrarse 24x7 disponible. Por otro lado, los denominados servicios de gestión o de administración pueden tener una exposición menor, aunque, generalmente, los tengamos expuestos el mismo número de tiempo. Por ejemplo, un servicio SSH, FTP o, incluso, una VPN, pueden ser servicios críticos para la gestión de una compañía que no deberían estar expuestos el 100% del tiempo, y sí solo cuando se utilicen, ya que su exposición pone en riesgo gran parte de la organización. Este hecho puede quedar confirmado con SSHowDown Attack y las repercusiones mundiales que esto tuvo.

Figura 2: Ataques contra SSH en un log de una semana

Tal y como se puede ver en el artículo SSH Brute Force – The 10 Year Old Attack That Still Persists, no es nueva la existencia de bots que se encargan de realizar ataques de fuerza bruta sobre servicios SSH expuestos en Internet, ya sea para conseguir el acceso al sistema o simplemente para extraer una lista de usuarios en base a un bug, como vimos con el ejemplo del Time-Based Info-Leak de OpenSSH. Todo esto se reduciría, si el servicio de gestión solo estuviera expuesto durante el tiempo necesario, es decir, que se levante o cierre a petición para conseguir aplicar la Mínima Superficie de Exposicíon.

Port-Knocking & Latch

El Port-Knocking es una solución conocida, la cual permite minimizar el tiempo de exposición de un servicio. Imagina 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. Las técnicas de Port-Knocking le permiten configurar la posibilidad de utilizar un puerto no Well-Known para "tras golpear" el puerto conseguir que el servicio SSH esté accesible desde Internet.

Figura 3: Descripción del proceso de Port-Knocking

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.

El pasado mes de Enero, escribí un artículo en el blog de ElevenPaths explicando e implementando esto integrado con Latch como factor de autorización, lo que llamamos SSH en Modo Paranoia. El Port-Knocking era utilizado como un primer factor de autenticación para la habilitación del servicio SSH. Para ello, se utiliza el valor de la dirección IP de origen y el valor del puerto como si fueran una sola clave. En otras palabras, crearemos una aplicación que estará sniffando todo el tráfico que llega a la máquina y cuando la dirección IP origen y el puerto sean iguales a lo buscado se habrá pasado correctamente el primer factor.

Figura 4: Descripción del proceso de Port-Knocking & Latch

Una vez es validado que la dirección IP y el puerto son los esperados, por ejemplo, dirección IP 8.8.8.8 y puerto 9000, se activa el servicio SSH. Pero esto dejaba a merced de cualquier usuario malintencionado que quisiera jugar con nuestro SSH, la posibilidad de capturarnos el paquete de IP Spoofing y poder levantar nuestro servicio. Por esta razón, se decide meter un segundo factor de autorización, basado en Latch.

Figura 5: Demo de Latch protegiendo la apertura de un proceso de port-knocking

Cuando el sistema que estamos montando recibe un paquete TCP con las condiciones apropiadas, nuestro sistema consultará el estado del cerrojo o del Latch asociado a la aplicación. En caso de que el cerrojo esté cerrado, el sistema no levantara el servicio SSH, pero si el cerrojo está abierto, significa que estamos autorizando el arranque del servicio SSH, ya que se han cumplido estas dos condiciones.

SSH y Latch Cloud TOTP

Aún podemos fortificar un poco más el uso del servicio SSH. Nuestro compañero Diego Samuel Espitía escribió un artículo sobre Cómo integrar Latch Cloud TOTP en un servicio SSH. En primer lugar, es importante tener instalado en el sistema la librería libpam-google-authenticator, la cual puede instalarse a través de apt-get install. El proceso para llevar a cabo el intercambio de semilla es fácil: ejecutar la instrucción google-authenticator en el terminal. Esto generará un gran QRCode, el cual debe ser leído con la aplicación de Latch.

Figura 6: Google Authenticator en Terminal

Desde Latch hay que ir a añadir servicio y pulsar sobre ‘Proteger con Cloud TOTP’. Esto hará que tengamos que leer el QRCode anterior, con la aplicación de Latch. Una vez es reconocido el QRCode, se tendrá listo Latch Cloud TOTP para utilizarlo con nuestro servicio SSH.

Figura 7: Latch Cloud TOTP para SSH configurado

Una vez, se generó el QRCode, se puede leer la siguiente información, dónde se almacenará el secreto, el tiempo de refresco, las limitaciones de login, etcétera.

Figura 8: Configuración final de Authenticator

Ahora, hay que configurar la autenticación con el TOTP en el servicio SSH. Para ello, vamos al fichero de configuración de PAM y añadimos esta línea auth required pam_google_authenticator.so. El fichero de configuración se encuentra en /etc/pam.d/sshd.

Figura 9: Autenticación en SSH con Latch Cloud TOTP como 2FA

Hay que tener en cuenta que la línea debe ser introducida en la primera línea. Una vez hecho esto, hay que modificar una directiva del servicio SSH, por lo que para ello debemos editar el fichero /etc/ssh/sshd_config. Buscamos la directiva ChallengeResponseAuthentication y la ponemos a yes. Veremos algo así. Primero nos pide el TOTP y, posteriormente, la clave del usuario.

PoC: Ejemplo final

Al final en este entorno tenemos lo siguiente:
1. Un servicio escrito en Ruby, el cual monitoriza cualquier paquete que llega al equipo y busca una serie de circunstancias en un paquete, como son la dirección IP de origen, el puerto destino y que el flag TCP de SYN esté habilitado. Esto provoca que el sistema sepa que se quiere levantar el servicio SSH, a modo de Port-Knocking.
2. Una vez llega el paquete “clave”, nuestro servicio escrito en Ruby comprobará el estado de Latch. Si el cerrojo se encuentra abierto, se levantará el servicio SSH de cara al exterior, comenzando el tiempo de exposición del servicio de gestión.
3. El usuario se tendrá que conectar por SSH al servicio y se le solicitará el usuario y contraseña, o autenticación de clave pública, en función de lo que esté configurado y, además, un token TOTP, el cual estaremos generando con Latch Cloud TOTP.
Figura 10: Demo de Port-Knocking + Latch Cloud TOTP & Aut + Lath como 2FA

Y aún podríamos ir más allá. Por supuesto, una vez autenticado el usuario con su clave y su Latch Cloud TOTP, aún podríamos añadir Latch para SSH (UNIX) para autorizar el proceso de Login, lo que dejaría el sistema con un proceso de autorización extra después de autenticar al usuario correctamente. Esto, que parece una vuelta de tuerca excesiva, sería útil para entornos en los que se estuviera controlando el uso de cuentas administrativas para mejorar la seguridad.

Figura 11: Latch para SSH (UNIX)

Paso 1: Por ejemplo, el Latch del sistema de Port-Knocking podría ser controlado por un daemon que verificara los horarios de trabajo y que abriera o cerrara el Latch en función de si es horario de trabajo o no, para permitir que el servicio SSH estuviera expuesto o no en Internet para todos los administradores.

Paso 2: Después, un administrador del sistema pediría conexión mediante una petición de Port-Knocking y se autenticaría con sus credenciales y el segundo factor de autenticación basado en Latch Cloud TOTP.

Paso 3: Por último, el supervisor del sistema autorizaría o no esa conexión concreta para ese usuario administrador concreto con un Latch en SSH asociado a la cuenta, lo que permitiría establecer procesos de Verificación de cuatro ojos o Activación con dos llaves.


Figura 12: Configuración Latch para UNIX & SSH en GNU/Linux

Como se puede ver, a la hora de fortificar un sistema, tenemos múltiples elementos de seguridad y distintas capas, que nos pueden ayudar a  que la Superficie de Exposición sea Mínima y que tengamos Defensa en Profundidad, lo que hacemos utilizando varios factores de autenticación, tanto en el propio servicio SSH, como en el levantamiento del servicio.

Autor: Pablo González Pérez (@pablogonzalezpe)
Escritor de los libros "Metasploit para Pentesters", "Ethical Hacking", "Got Root" y “Pentesting con Powershell

4 comentarios:

emilianoalcaraz dijo...

Hola! Muchas gracias por la info. La verdad que para los acreedores de muchos vps suena bien interesante. Pero una pregunta, si utilizas keys para iniciar sección en el ssh y bloqueas el uso de password como asi tambien el inicio de sesion a traves del root, ya evitarías la fuerza bruta? Y que otra ventaja podría brindarme utilizar esta medida de seguridad que proponen?

Saludos,

Emiliano,

www.alcarazweb.com

Chema Alonso dijo...

@emilioalcaraz

1.- Port Knocking reduce el impacto de bugs o ataques de brute-force -> Time-Based Info Leak in OpenSSH
2.- Latch Cloud TOTP es para cuando usas solo password -> incrementa la seguridad de la identidad.
3.- Latch después, ayuda en entornos de Cuentas Supervisadas donde hay Verificación en cuatro ojos.

Saludos!

jordi.ferran dijo...

Puntualmente yo también he entrado en brainstorming para como configurar SSH en modo paranoia. Aunque mi idea (no implementada) era algo más básica. Por defecto indicar desde hace años ya deshabilito acceso remoto para usuario root y también el uso de texto para autenticar usuario. Solamente permito uso de clave privada-publica.

Mi idea "overkill" era levantar firewall para permitir acceso a servicio SSH solamente desde direcciones IP estáticas conocidas. Quizás con IP dinámica si se pudiera esta verificar via DNS (el cliente debe tener acceso para cambiar registro en DNS). El siguiente paso es publicar un servicio web mediante nginx (el apache-httpd lo tengo escondido via reverse-proxy), que permite autenticar petición de usuario y habilitar una public-key conocida en fichero "authorized_keys" de la máquina durante un periodo de 20 a 60 segundos. Es decir que la clave privada del usuario se permite usar durante un periodo muy breve de tiempo y desde direcciones IP conocidas. Algo muy simple de implementar y efectivo. En lugar de definir un paquete TCP en un puerto "no usado", había pensado en esconder la petición entrante tipo trigger "déjame entrar porfavor" en el mismo protocolo HTTP. Y a todo esto también pensé en limitar el acceso mediante firewall a direcciones origen de tipo IPv6. Una gran parte de la red mundial continua usando IPv4 y ello pudiera reducir aún más la casuística. Dado que sin IPv6 local uno pudiera necesitar de infraestructura servidora con IPv6 y además IP spoofing para engañar al firewall objetivo. Algo que no resulta trivial para un no experto en seguridad. Y por si fuera poco también pensé en disponer este servicio de "déjame entrar porfavor (en HTTP)" en servidores clave duplicados en cluster en carios centros de datos diferentes. De manera que el servicio para hacer login no esta distribuido / duplicado en todos los servidores físicos. Solamente en unos pocos. Y son estos los que mediante SSH en la intranet virtual, instalan una clave pública para permitir acceso externo durante un período de tiempo limitado (y configurable).

Aun y así reconozco que no he puesto en marcha esta idea. Por el momento la seguridad actual me funciona y por ahora tampoco administro entornos de producción tan sensibles como para implantar medidas tan extremas.

Pablo González dijo...

Hola @jordi,

En el libro de Hardening Linux se ve cómo fortificar el servicio SSH con medidas como las que decís, buenas prácticas, como son quitar el login remoto como root y deshabilitar la autenticación por texto (y habilitarla con clave pública-privada), además, de otras como no usar puertos por defecto, utilizar fail2ban para evitar fuerza bruta, etc. Al final todo suma. Aquí se propone un 2FA para la parte de usuario, dónde se podría hacer clave público-privada + TOTP, incluso después un Latch para autorizar al usuario. También hacemos hincapié en la necesidad de minimizar la exposición de los servicios (más el uso del mínimo privliegio posible, en la demo se ve root, pero en un entorno de pro, no debería ser), la defensa en profundidad... ;) Con esto del port-knocking estamos también utilizando dos factores para habilitar la exposición del servicio (más luego los factores para autenticarnos como un usuario). La exposición del servicio solo se activará cuando se de la circunstancia del port-knocking basado en clave IP falsa + puerto concreto. Una vez dado esto, autorización con Latch.

Es un modo paranoia que nos da idea de lo que podemos hacer para proteger canales críticos en una organización.

Un saludo!

Entrada destacada

Infraestructuras Críticas y Sistemas Industriales: Auditorías de Seguridad y Fortificación de @0xWord

Desde hoy está disponible a la venta un nuevo libro de 0xWord centrado en la seguridad de los Sistemas Industriales y las Infraestructuras...

Entradas populares