Un grupo de investigadores de la Universidad de California en Riverside, en colaboración con investigadores de otras universidades y compañías privadas, publicaron a fines de octubre de este año un paper en el que demuestran la existencia de una vulnerabilidad presente en el ecosistema DNS que permite realizar ataques de envenenamiento de la caché DNS, un problema que había sido descubierto en 2008 por el investigador Dan Kaminsky y que en principio se creía solucionado. El hallazgo reciente volvió a poner sobre la mesa la vulnerabilidad al demostrar que mediante una nueva técnica, apodada SAD DNS, es posible provocar el envenenamiento de la caché DNS y lograr que tras una consulta para un nombre de dominio en particular el servidor devuelva una IP potencialmente maliciosa que redireccione a la víctima a un sitio controlado por el atacante y no al sitio que corresponde al nombre de dominio legítimo.
Como ya hemos explicado en publicaciones anteriores, el Sistema de Nombres de Dominio (DNS) se encarga de traducir nombres de dominio a direcciones IP. Esto existe porque es más sencillo para los usuarios recordar nombres como welivesecurity.com que su dirección IP.
Cómo funciona el ecosistema DNS
Antes de entrar en el análisis de SAD DNS, para comprender esta vulnerabilidad es necesario explicar más en detalle cómo funciona la infraestructura global que permite realizar estas traducciones. Para ello veamos la Figura 1. Aquí se muestra el flujo de mensajes completo que se debe realizar, en casos normales, entre distintos servidores públicos para encontrar el registro que contiene la traducción —o resolución— que buscamos.
Como se observa en la imagen anterior, un cliente realiza una petición a un servidor denominado Resolver, también conocido como resolutor recursivo, que para la mayoría de los usuarios será el que les haya asignado su proveedor de servicios de Internet (ISP), o bien, algún servicio público como 8.8.8.8 de Google.
Cuando el Resolver recibe una consulta por parte del cliente, primero se fija en su caché si ya contiene la resolución buscada, en caso de no contar con ese registro, inicia una serie de consultas a otros servidores, en el orden que se ve en la Figura 1.
Lo siguiente que debemos entender es que las consultas DNS típicamente se realizan utilizando el protocolo de capa de transporte UDP, que no mantiene un estado o sesión entre cliente y servidor y cuyo encabezado puede ser fácilmente modificado para aparentar que la consulta proviene de otro equipo. Si bien este protocolo incorpora algunas debilidades en cuanto a la seguridad, su uso es una elección de diseño, ya que estos servidores manejan un gran volumen de consultas y el UDP requiere una menor cantidad de procesamiento y mensajes que el protocolo TCP para intercambiar datos.
Lo que puede ocurrir es que un atacante modifique el encabezado UDP haciéndose pasar por un Servidor Autoritativo e introduzca una resolución falsa que finalmente el Resolver almacene en su caché, provocando su contaminación o “envenenándolo”. A partir de este momento, cualquier cliente que solicite la resolución de un determinado nombre de dominio al Resolver envenenado, recibirá una IP potencialmente maliciosa que lo redireccione al sitio del atacante o a su casilla de email, dependiendo del tipo de registro DNS que se modifique.
Ataque de Kaminsky
Antes de comprender el ataque SAD DNS recientemente conocido, volvamos primero al 2008, año en el que surgieron los primeros ataques de envenenamiento de caché DNS conocidos. En esta época, los Resolvers utilizaban un puerto UDP fijo (53) y la única medida de seguridad que existía era un identificador de 16 bits contenido en el paquete que debía coincidir entre la consulta y la respuesta. Existían (y siguen existiendo) otros tipos de chequeos, como el “bailiwick check”, pero no vienen al caso, ya que no afectan en mayor medida a este tipo de ataques y buscan prevenir otro tipo de problemas.
16 bits representan 65536 valores posibles. El ataque de Kaminsky simplemente consiste en enviar todas estas combinaciones posibles al Resolver, spoofeando la IP de un Servidor DNS Autoritativo en el encabezado UDP, con la esperanza de que uno de esos paquetes contenga el ID correcto (que envió el Resolver y cuya respuesta aún está pendiente) y que llegue al Resolver antes de la respuesta del servidor legítimo. No era exitoso el 100% de las veces, pero si se continúa intentando, las chances aumentan y efectivamente en algún momento se termina contaminando el caché del Resolver. En la práctica, utilizando herramientas automatizadas era posible contaminar el caché en aproximadamente 10 segundos.
¿Cómo se mitigó este ataque? Si en lugar de utilizar siempre el puerto 53 se eligen puertos aleatorios al momento de enviar una consulta, la entropía aumenta significativamente de 65536 valores posibles a 4,294,836,225 (216 * 216 = 232). Si la respuesta DNS llegara a un puerto distinto del cual se realizó la consulta, el paquete es descartado por el sistema operativo y resulta prácticamente imposible que un atacante pueda probar todas estas combinaciones antes de que se produzca la respuesta por parte del servidor legítimo, sin importar cuantas veces lo intente.
¿Problema Resuelto? Aparentemente, no
Después de 12 años desde que se conoció el primer ataque de envenenamiento de caché DNS, al parecer ha vuelto. Como vimos en el análisis del ataque de Kaminsky, la medida de seguridad que se adoptó para mitigar la vulnerabilidad fue la “randomizacion” de los puertos UDP, también conocido como “Source Port Randomization”.
Sin embargo, si un atacante pudiera predecir el puerto abierto de una forma más sencilla que probando todas las combinaciones posibles, estaríamos ante un escenario prácticamente idéntico al anterior que describimos. Aquí es donde entra en juego el hallazgo realizado por los investigadores de la Universidad de California en Riverside y de la Universidad Tsinghua de Beijng.
La idea es simple pero muy ingeniosa. Se trata de derrotar el Source Port Randomization mediante mensajes de error ICMP, utilizados como un ataque tipo canal lateral. La técnica hace uso de una funcionalidad de este protocolo llamada Response Rate Limiting (RRL) que, irónicamente, fue adoptada por motivos de seguridad para prevenir ataques de denegación de servicio distribuidos (DDoS).
De forma predeterminada, este valor máximo de respuestas por segundo es 1000 en servidores Linux, 200 en Windows Server 2019 (versión 1809) y FreeBSD y finalmente, 250 en MacOS 10.15.
Este comportamiento, adoptado para prevenir los ataques conocidos como “Smurf Attack”, permite hacer inferencias sobre la configuración del servidor, en particular, si un puerto se encuentra abierto o cerrado, como veremos más adelante.
Si enviamos un paquete UDP a un puerto cerrado obtendremos un mensaje de error “port unreachable”, pero si el puerto está abierto no obtendremos ninguna respuesta ICMP (la conexión fue exitosa).
Supongamos que el límite de mensajes establecido por el servidor es 1000 por segundo. El ataque SAD DNS consiste en agotar primero este límite con 1000 solicitudes que sepamos que generarán un mensaje de error ICMP y a partir de ese momento, enviar tandas controladas de paquetes UDP, aumentando el número de puerto de manera secuencial en cada consulta. En la Figura 2 se puede observar un diagrama del ataque enviando tandas de 50 paquetes cada 20 milisegundos (máxima velocidad permitida en este ejemplo).
Los primeros 49 paquetes que envía el atacante suplantan la IP del servidor autoritativo, mientras que el último contiene su propia dirección IP. La mayoría de las respuestas ICMP irán a la dirección IP spoofeada, por lo que el atacante no las podrá ver, sin embargo, no lo necesita. El truco consiste en que si todos los puertos se encontraban cerrados el contador del sistema operativo de la víctima ya habrá llegado a 1000, agotando el límite de respuestas establecido por RRL.
Eso significa que si el último paquete de cada tanda que envía el atacante —enviado con su dirección IP— no recibe ningún mensaje de error ICMP, todos los puertos estaban cerrados. Pero si recibe un mensaje de error significa que el contador llegó hasta 999; es decir, uno de los puertos estaba abierto. De esta manera se puede acotar la búsqueda de manera significativa.
Los 1000 puertos todavía representan una cantidad muy alta de posibilidades, pero se puede repetir este proceso de forma similar algunas veces más para acotar aún más la búsqueda.
En teoría, el ataque completo puede tomar hasta 65 segundos, por lo que es probable que la respuesta legítima del servidor haya llegado antes y que el ataque falle. Sin embargo, al igual que en el caso del ataque de Kaminsky, aumentan las chances de que el ataque sea exitoso cuantas más veces se repite.
Los investigadores no han indicado un tiempo promedio que demora una contaminación de caché exitosa, sin embargo, se ha confirmado que el 34% de todos los Resolvers en Internet son vulnerables, incluyendo, por ejemplo, los servicios 8.8.8.8 de Google y 1.1.1.1 de Cloudflare. Los investigadores trabajaron con estas y otras organizaciones para que las vulnerabilidades sean parcheadas antes de publicar el paper.
Si tengo un resolutor recursivo propio, ¿qué mitigaciones debería implementar?
Este ataque puede tener un impacto severo, por lo que se recomienda a aquellos administradores de red que operen servidores DNS de este tipo que adopten las siguientes recomendaciones lo antes posible:
Recomendaciones:
- Actualizar el kernel de Linux a su versión más reciente. Esta vulnerabilidad ya fue corregida mediante la randomización del RRL para agregar aún mayor entropía y efectivamente volver a este ataque impracticable.
- Bloquear los mensajes de error ICMP “port unreachable” en el firewall.
- Mantener el software DNS que se utilice al día.
Detección de un ataque:
- Detectar el timing de los ataques, por ejemplo, si se envían tandas de 50 paquetes cada 20ms, seguramente se trate de un ataque.
- Detectar ID DNS incorrectos en las respuestas que recibe el servidor, es poco habitual que el tráfico legítimo contenga ID incorrectos.