Todos los navegadores principales son vulnerables a un fallo que surgió debido a una implementación inconsistente de los mecanismos de seguridad. Analizamos la historia de un error de 18 años de antigüedad y revelamos las formas peligrosas en que los atacantes lo utilizan para comprometer aplicaciones locales.
Recientemente, los especialistas de Oligo Security revelaron la vulnerabilidad «0.0.0.0 Day», que permite a sitios web maliciosos eludir la protección del navegador e interactuar con servicios que se ejecutan en la red local de una organización, lo que potencialmente lleva a un acceso no autorizado y a la ejecución remota de código.
El problema surge por la implementación irregular de los mecanismos de seguridad en distintos navegadores y por la ausencia de una estandarización en la industria de los navegadores. En consecuencia, la aparentemente inofensiva dirección IP 0.0.0.0 puede convertirse en una poderosa herramienta para que los atacantes exploten servicios locales, incluyendo aquellos utilizados en tareas de desarrollo, sistemas operativos e incluso redes internas.
El impacto de 0.0.0.0 Day tiene un alcance muy amplio, afectando tanto a individuos como a organizaciones. Además, el descubrimiento de campañas activas de explotación (de las cuales hablaremos en este artículo) subraya nuevamente la urgencia de corregir esta vulnerabilidad.
La vulnerabilidad crítica afecta a todos los navegadores web principales (Chromium, Firefox, Safari) y permite a los atacantes comprometer redes locales. 0.0.0.0 Day surgió a raíz de cómo los navegadores manejan las solicitudes de red, lo que podría dar a los hackers acceso a servicios confidenciales que se ejecutan en dispositivos locales.
Este fallo lógico posibilita que sitios externos interactúen con software en ejecución local en MacOS y Linux (localhost) y potencialmente ejecuten código arbitrario en la máquina del visitante, aprovechando la dirección 0.0.0.0 en lugar de localhost/127.0.0.1. Windows no se ve afectado por este problema.
Tras la divulgación responsable de la información, las solicitudes HTTP a 0.0.0.0 ahora se añaden a los estándares de seguridad mediante una Request for Comments (RFC), y algunos navegadores pronto bloquearán por completo el acceso a 0.0.0.0. La dirección ya no será permitida como destino IP en la especificación Fetch, que define cómo deben comportarse los navegadores al realizar solicitudes HTTP.
A comienzos de abril de 2024, Oligo informó a los equipos de seguridad responsables de cada uno de los principales navegadores sobre esta vulnerabilidad. Los expertos de cada empresa reconocieron la deficiencia y trabajarán en cambiar el estándar correspondiente, además de implementar medidas de mitigación a nivel de navegador.
En última instancia, todos los navegadores bloquearán 0.0.0.0, pero el mercado también exige una norma común. La falta de un estándar definitivo ha provocado implementaciones diferentes en cada navegador. Es decir, hoy cada navegador maneja las solicitudes HTTP a la red interna o local de forma distinta.
Correcciones en los navegadores:
Google Chrome (y navegadores basados en Chromium, incluyendo Edge):
0.0.0.0 Day eludía el mecanismo PNA (Private Network Access) de Chromium, que bloquea el acceso de sitios web a 127.0.0.1, localhost y otras direcciones IP privadas mediante JavaScript cuando la página se carga desde sitios públicos.
Tras el informe de Oligo Security, Chrome bloquea el acceso a 0.0.0.0 (Finch Rollout) desde Chromium 128. Google implementará este cambio de forma gradual en los próximos lanzamientos, finalizando en Chrome 133, momento en el que la dirección IP quedará completamente bloqueada para todos los usuarios de Chrome y Chromium.
Es importante destacar que el porcentaje de sitios web que se comunican con 0.0.0.0 va en aumento, según los contadores de Chromium. Dichas páginas podrían ser maliciosas, y actualmente representan el 0,015% de todos los sitios web. Con 200 millones de sitios en el mundo (a agosto de 2024), alrededor de 100 000 sitios públicos podrían comunicarse con 0.0.0.0. La siguiente imagen ilustra este crecimiento.
Apple Safari: los navegadores de Apple se basan en el motor WebKit. Tras el informe de Oligo Security, Apple introdujo cambios en WebKit que bloquean el acceso a 0.0.0.0. La compañía agregó una verificación de la dirección IP de destino. Si está compuesta únicamente de ceros, la solicitud se bloquea.
Mozilla Firefox: Actualmente Firefox no ha aplicado ninguna corrección. Aunque está en proceso, Firefox nunca ha limitado el Private Network Access (PNA), por lo que técnicamente PNA siempre ha estado permitido. Desde este punto de vista, “no hay nada que corregir”, ya que PNA no está implementado de inicio en Firefox.
Tras el informe de Oligo Security, Mozilla modificó la especificación Fetch (RFC) para bloquear 0.0.0.0. Firefox ha priorizado la implementación de PNA, aunque aún no esté lista. En el futuro, 0.0.0.0 se bloqueará en Firefox y no dependerá de la implementación de PNA.
0.0.0.0 Day: un análisis más profundo
Todos tenemos un navegador favorito que usamos a diario. Incluso las aplicaciones que no son navegadores suelen cargar recursos desde dominios externos, por ejemplo, al usar Google Analytics y otros SDK de cliente o al incrustar scripts o videos.
Los desarrolladores siempre han introducido conceptos de seguridad pioneros en los navegadores, como sandbox y cookies solo HTTPS, o han implementado el mecanismo CORS (Cross Origin Resource Sharing) para proteger servidores y usuarios finales. Todas estas medidas mantienen alejados a los sitios maliciosos que recurren a ataques CSRF de datos personales, redes internas y aplicaciones locales.
Los navegadores pueden enviar solicitudes a casi cualquier servidor HTTP usando JavaScript. Cuando el navegador procesa la respuesta cross-site, los mecanismos de seguridad deciden qué hacer:
Sin embargo, a veces la respuesta es irrelevante. Con la vulnerabilidad 0.0.0.0 Day, una sola solicitud podría bastar para causar daño. Antes de entrar en detalles, veamos algo de contexto para comprender la situación.
Volvamos al origen del problema: 0.0.0.0 puede emplearse en varios casos. Posiblemente ya hayas pensado en algunos de sus usos: “todas las direcciones IP del host”, “todas las interfaces de red del host” o sencillamente “localhost”.
RFC 1122 hace referencia a 0.0.0.0 con la notación {0,0}:
RFC 1122 prohíbe el uso de 0.0.0.0 como dirección de destino en IPv4 y solo lo permite como dirección de origen en circunstancias específicas, por ejemplo, durante el proceso DHCPDISCOVER al iniciarse un handshake DHCP, cuando se asigna por primera vez la dirección IP.
A veces 0.0.0.0 se utiliza en archivos /etc/hosts para bloquear ciertos dominios (haciendo la función de bloqueador de publicidad) o, si se usa en políticas de red, CIDR 0.0.0.0/32 significa que todas las direcciones IP están permitidas.
La obtención de huellas digitales (fingerprinting) de los usuarios de un sitio es una técnica bien conocida con múltiples objetivos. El uso lícito más común es la identificación de usuarios recurrentes, pero también puede emplearse de forma malintencionada para recopilar información de inteligencia en campañas de phishing. Un sitio puede averiguar mucho sobre quién lo está visitando en un momento dado, incluso si nunca iniciaste sesión.
En 2020 se descubrió que Ebay intentaba escanear los puertos del visitante apenas cargaba la página. El sitio usaba JavaScript para escanear los puertos en el localhost (127.0.0.1), creando así una huella única. Como el escaneo ocurría dentro del navegador, los firewalls del usuario no podían prevenirlo.
En teoría, los navegadores no deberían poder enviar este tipo de solicitudes, ya que basta una sola para que se produzca la explotación. Durante años la web funcionó así y a nadie le preocupó. Se necesitó tiempo para comprender por completo que este comportamiento podía generar violaciones de seguridad, y para cuando se entendió, ya estaba tan arraigado en cada navegador que resultaba muy difícil cambiarlo.
Los servicios locales e internos siempre han sido un objetivo principal para los ataques. En 2006, Mozilla informó de un interesante problema de seguridad descubierto incluso antes del primer lanzamiento de Chrome en 2008. Curiosamente, el informe de error de hace 18 años sigue abierto.
En el reporte, un usuario decía que sitios públicos atacaban su router en la red interna y afirmaba que los sitios no deberían poder hacer eso.
En aquel momento, las redes internas (y la propia Internet) eran inseguras por naturaleza: muchos servicios carecían de autenticación, por no hablar de certificados SSL y HTTPS que no estaban generalizados. Las páginas web se cargaban a través de HTTP sin cifrar, y los atacantes aprovechaban de manera constante el navegador con fines maliciosos.
Desde 2006, los hackers han abusado del hecho de que las solicitudes aún se envían, mientras los navegadores se concentran en las respuestas. Por ejemplo, un atacante podía modificar la configuración de un router doméstico o de oficina de la víctima usando un JavaScript malicioso en un sitio controlado por el criminal.
Han pasado 18 años, se han publicado cientos de comentarios, pero el error permanece abierto hasta hoy.
En ese lapso, el problema se ha cerrado, vuelto a abrir, reclasificado como “serio” o “crítico” e incluso se ha explotado en entornos reales. Por ejemplo, en junio de 2023, David Adrian, experto en seguridad de Google, informó sobre múltiples casos de uso de la vulnerabilidad 0.0.0.0 Day.
Los responsables del mantenimiento lo han tenido difícil para llegar a un consenso sobre la naturaleza del fallo: ¿es una “vulnerabilidad”, afecta solo a Firefox o es una petición de mejora? Algunos desarrolladores de Firefox argumentaron que no era ni un error ni una funcionalidad. Aun así, el reporte seguirá abierto mientras Firefox no implemente PNA.
Para explotar el fallo bastaba con una sola solicitud HTTP, sin que la respuesta importara. Ejemplos de scripts maliciosos fueron documentados ya en 2006 en ataques contra routers domésticos:
La ausencia de un estándar era la principal fuente de estos problemas, lo que mostraba claramente la necesidad de desarrollar un mecanismo de seguridad común a todos los navegadores. El mundo pedía a gritos un estándar que ampliara el Cross Origin Resource Sharing (CORS) en todos los navegadores, permitiéndoles diferenciar redes locales, privadas y públicas.
Google llenó valientemente ese vacío con Private Network Access.
Durante mucho tiempo no estuvo claro cómo debían comportarse los navegadores al enviar solicitudes a redes internas o locales desde contextos menos privados. Dominios como attacker.com no deberían poder conectarse a localhost en ningún escenario real.
Todos los navegadores principales recurrían a CORS. CORS es de gran ayuda, pero su eficiencia depende del contenido de la respuesta, por lo que la solicitud igual se termina enviando. La historia ha demostrado que basta un solo HTTP para atacar el router doméstico, y si con eso es suficiente, cada usuario debería poder impedir que se haga esa solicitud.
PNA amplía las funciones de CORS limitando la posibilidad de que los sitios web envíen solicitudes a servidores en redes privadas. PNA diferencia redes públicas, privadas y locales. Las páginas cargadas en contextos menos seguros no podrán comunicarse con contextos más seguros. Por ejemplo, attacker.com no puede conectarse a 127.0.0.1 o 192.168.1.1 porque dichas direcciones IP se consideran más restringidas. La imagen siguiente muestra la relación entre redes públicas, privadas y locales en PNA.
¿En qué se diferencia PNA de CORS? Si bien CORS protege el contenido no deseado para que no sea cargado en contextos inseguros, lo hace a nivel de respuesta. Los recursos devueltos en la respuesta se bloquean o se eliminan. PNA mejora esta capacidad al dar la opción de bloquear el envío de la solicitud en sí.
Poniendo a prueba 0.0.0.0: eludir PNA
Según la especificación vigente de PNA, los siguientes rangos de IP se consideran privados o locales:
Durante la investigación se descubrió que 0.0.0.0 no figura en esa lista. En Oligo Security pensaban que, como parte de PNA, los sitios no podrían enviar solicitudes a 0.0.0.0. Según la especificación, la dirección 0.0.0.0 no debería utilizarse como destino.
Para comprobarlo, los investigadores levantaron un servidor HTTP ficticio en localhost (127.0.0.1) e intentaron acceder a él desde un dominio externo mediante JavaScript, usando 0.0.0.0.
El resultado fue que la solicitud llegó al servidor.
¿Qué pasó?
1. Desde un dominio público (.com), el navegador envió una solicitud a 0.0.0.0.
2. El servidor ficticio escucha en 127.0.0.1 (solo en la interfaz loopback, no en todas las interfaces de red).
3. El servidor en localhost recibió la solicitud, la procesó y devolvió una respuesta.
4. El navegador bloqueó que el contenido de la respuesta llegara a JavaScript por CORS.
En otras palabras, los sitios públicos pueden acceder a cualquier puerto abierto en tu máquina sin poder ver la respuesta.
Este es el modo en que se evita la implementación actual de PNA y constituye una deficiencia inherente de los navegadores. Los investigadores informaron su hallazgo a los representantes de todos los navegadores, dentro de la divulgación responsable. Sin embargo, para probar el concepto se requiere una amenaza real y un vector de ataque efectivo.
Es necesario encontrar alguna aplicación que pueda verse afectada por 0.0.0.0 Day, y hay bastantes.
Cuando los servicios usan localhost, suponen un entorno aislado. Dicha suposición puede ser errónea (como en el caso de 0.0.0.0 Day), y lleva a implementaciones inseguras del servidor. Por ejemplo, muchas aplicaciones se saltan la verificación de token CSRF y ponen en riesgo la autorización o la autenticación, pensando que se ejecutan en una red plenamente controlada.
En algunos casos puede que no se requiera autorización ni autenticación, o que no existan verificaciones de tokens CSRF. Cuando una aplicación asume que funciona en un entorno seguro o una red aislada de confianza, permite peticiones POST HTTP sin verificación de autorización o tokens CSRF, y también acceso de escritura a recursos y configuraciones, lo que posibilita la ejecución de código. Incluso una sola solicitud HTTP podría bastar para permitir acceso a tus puertos.
Para hallar una aplicación local vulnerable a ataques desde el navegador, primero se necesita un servidor HTTP funcionando en un puerto local (interfaz de red localhost). Para ejecutar código de forma remota, ese servicio debe contar con una ruta HTTP que permita escribir, configurar o modificar archivos y configuraciones.
Las aplicaciones tienen numerosos endpoints, y los servicios locales suelen hacer concesiones en materia de seguridad, lo que resulta estupendo para los atacantes. Los investigadores se decantaron por el framework Ray, que era vulnerable.
ShadowRay desde el navegador
El equipo de Oligo tomó como base la campaña ShadowRay descubierta en marzo, que apunta a la capacidad de computación de IA. La vulnerabilidad daba a los atacantes la posibilidad de aprovecharse de entornos no seguros. Oligo demostró que tal ataque puede realizarse desde el navegador, usando 0.0.0.0 como vector de ataque.
Primero, en la ventana de la derecha se inicia un clúster local de Ray en localhost. Luego, en la ventana de la izquierda, se inicia un socket que escucha nuevas conexiones para abrir un Reverse Shell. A continuación, la víctima hace clic en un enlace en un correo de phishing que ejecuta el exploit. Este exploit abre una Reverse Shell en la máquina de la víctima.
Este es un ejemplo del código usado para el exploit.
Cómo funciona el ataque en distintos navegadores:
Google Chrome
Apple Safari
Mozilla FireFox
Iniciar ShadowRay desde el navegador es solo uno de los múltiples ataques de ejecución remota de código (RCE) que pueden efectuarse con este método. Veamos algunos vectores de ataque que utilizan 0.0.0.0 Day.
En la reciente campaña SeleniumGreed, los atacantes emplearon servidores públicos de Selenium Grid para obtener acceso inicial a los sistemas de las organizaciones, explotando vulnerabilidades RCE conocidas. Se descubrió que en instancias locales de Selenium Grid el RCE es posible al enviar una solicitud POST a http[:]//0.0.0.0:4444/ con una carga maliciosa preparada.
Otro vector de ataque interesante es usar un clúster local de Selenium Grid para navegar sitios con configuraciones inseguras del navegador, con el fin de acceder a dominios internos y a registros DNS privados detrás de un VPN.
En julio de 2023, Oligo dio a conocer varias vulnerabilidades críticas ShellTorch a los desarrolladores de PyTorch (Amazon y Meta*), que conducían a la ejecución remota de código en PyTorch TorchServe, lo que finalmente permitía al atacante obtener acceso completo al servidor.
Los expertos en IA que usan TorchServe en redes internas (ya sea de forma local o mediante reenvío de puertos) podrían verse afectados por estas vulnerabilidades también a través de 0.0.0.0, resultando en la posible toma de control de un clúster local TorchServe protegido por firewalls o WAF.
Otro vector de ataque interesante consiste en escanear puertos para reconocer a usuarios anónimos, incluso aquellos que no tengan cookies y que nunca hayan iniciado sesión. Los resultados del escaneo de puertos locales pueden contrastarse con otros datos, como el User-Agent, la dirección IP y otros identificadores obtenidos mediante servicios de huellas digitales.
El escaneo reveló que diferentes usuarios dentro de la organización usan los siguientes puertos:
Mientras PNA no se implemente por completo, los sitios públicos pueden enviar solicitudes HTTP a servicios de la red local mediante JavaScript. Para cambiar esto, se necesita estandarizar PNA y que los navegadores lo implementen siguiendo el estándar.
CORS también es útil y ya hace que la web sea mucho más segura. CORS impide que el atacante lea las respuestas cuando se envían solicitudes no válidas.
Si se envía la solicitud y las cabeceras CORS no figuran en la respuesta, el JavaScript malicioso no podrá leer el contenido de esa respuesta. CORS bloquea la respuesta antes de que llegue a JavaScript, pero las solicitudes de tipo “opaque” se pueden enviar con “no-cors” y lograr llegar al servidor (si no nos preocupa la respuesta).
En la demostración de Oligo Security se comprobó que, usando 0.0.0.0 junto con el modo “no-cors”, los ciberdelincuentes pueden usar dominios públicos para atacar servicios que se ejecuten en la máquina local y hasta obtener la ejecución de código arbitrario con una sola solicitud HTTP.
Por ahora, los navegadores han priorizado las correcciones y aplicado cambios críticos, bloqueando 0.0.0.0 como dirección IP de destino. Era importante contar con una solución conjunta para evitar que los navegadores “se pasaran 0day unos a otros” al corregir el problema.
Evidentemente, esperar la corrección del navegador no es la mejor alternativa, así que los desarrolladores pueden adoptar ciertas medidas para proteger sus aplicaciones locales.
Oligo Security compartió las siguientes recomendaciones clave: