Envío de registros, alertas y datos de telemetría a través de un diodo de datos

Descubre cómo
Utilizamos inteligencia artificial para traducir el sitio web y, aunque nos esforzamos por garantizar la precisión, es posible que las traducciones no sean siempre 100 % exactas. Agradecemos tu comprensión.

IngressNightmare: Vulnerabilidad de ejecución remota de código CVE-2025-1974 y medidas correctivas

Por OPSWAT
Comparte esta publicación

En mayo de 2025 se hizo pública una vulnerabilidad de seguridad crítica, CVE-2025-1974, conocida como «IngressNightmare», que afecta al controlador ingress-nginx de Kubernetes, ampliamente implantado en infraestructuras nativas de la nube. Esta vulnerabilidad permite a atacantes no autenticados inyectar configuraciones arbitrarias en NGINX, lo que podría dar lugar a la ejecución remota de código (RCE) no autorizada y al compromiso total del clúster.

En el marco del programa OPSWAT , nuestros becarios llevaron a cabo un análisis técnico exhaustivo para comprender mejor la causa raíz, la vía de explotación y las estrategias de mitigación relacionadas con este problema de alta gravedad.

Resumen de CVE-2025-1974 

CVE-2025-1974 es una vulnerabilidad crítica de inyección de plantillas detectada en las versiones de ingress-nginx hasta la 1.11.4 y, en concreto, en la 1.12.0. Los atacantes con acceso a nivel de nodo a un clúster de Kubernetes pueden aprovechar esta vulnerabilidad para ejecutar código arbitrario mediante RCE a través del controlador ingress-nginx, el cual, por defecto, cuenta con amplios privilegios, incluido el acceso a secretos críticos dentro del clúster.

El Comité de Respuesta de Seguridad de Kubernetes ha asignado a esta vulnerabilidad una puntuación CVSS v3.1 de 9,8 (gravedad crítica):

Interfaz de usuario de métricas CVSS para CVE-2025-1974 que muestra las opciones de explotabilidad e impacto para IngressNightmare

Elementos clave de este análisis

Descripción general de Kubernetes

Kubernetes (K8s) es una plataforma de código abierto diseñada para automatizar la implementación, el escalado y la gestión operativa de aplicaciones en contenedores. Los clústeres de Kubernetes suelen estar formados por varias máquinas, que pueden ser tanto hardware físico como máquinas virtuales, y que funcionan de forma conjunta para proporcionar entornos de aplicaciones de alta disponibilidad, escalables y fáciles de gestionar.

Controlador de Ingress de NGINX

El controlador de Ingress de NGINX (ingress-nginx) es un controlador de Ingress de código abierto basado en el servidor web NGINX. Opera dentro de un clúster de Kubernetes, donde actúa principalmente como proxy inverso y equilibrador de carga. Este controlador interpreta los recursos de Ingress definidos por los usuarios y los traduce en configuraciones de NGINX ejecutables para dirigir el flujo de tráfico hacia el clúster y dentro de él.

El proceso de admisión y su función

Ingress-nginx se integra con Kubernetes mediante un servicio de webhooks denominado AdmissionReview. Este servicio es crucial para procesar objetos Ingress nativos de Kubernetes y traducirlos a configuraciones de NGINX validadas y sintácticamente correctas. Aunque AdmissionReview garantiza la precisión de la configuración, opera de forma independiente del controlador ingress-nginx y, por lo general, carece de controles de autenticación rigurosos. Esta falta de autenticación estricta es un factor clave que contribuyó a la vulnerabilidad de CVE-2025-1974.

Diagrama de CVE-2025-1974 (IngressNightmare) que muestra el flujo de trabajo de AdmissionReview en el controlador NGINX de Kubernetes Ingress

Aprovechamiento de vulnerabilidades y análisis técnico

Mecanismo de explotación

En esencia, la explotación de CVE-2025-1974 comienza con una solicitud maliciosa. Los atacantes crean una solicitud maliciosa dirigida al webhook AdmissionReview, lo que obliga a NGINX a cargar dinámicamente una biblioteca compartida en tiempo de ejecución. Partiendo de este mecanismo, nuestros compañeros analizaron tanto el webhook AdmissionReview como el flujo de trabajo de NGINX para comprender esta vía de explotación.

Diagrama de CVE-2025-1974 (IngressNightmare) que muestra la ruta de explotación de Kubernetes a través de un objeto Ingress malicioso y NGINX

Vulnerabilidad de inyección de plantillas

En el webhook de AdmissionReview, al procesar las solicitudes entrantes, la función CheckIngress transforma los objetos Ingress de Kubernetes en archivos de configuración válidos de NGINX. El proceso se desarrolla de la siguiente manera:

Fragmento de código Go que muestra la lógica de inyección de plantillas relacionada con la vulnerabilidad CVE-2025-1974 (IngressNightmare)
  1. Cada configuración se analiza y se pasa a `generateTemplate ` para que se formatee según las plantillas predefinidas de NGINX.
  2. A continuación, testTemplate comprueba que la configuración generada sea compatible con el binario de NGINX subyacente.

Todas las configuraciones de NGINX se basan en plantillas predefinidas que se encuentran en el archivo nginx.tmpl, dentro del código fuente de ingress-nginx:

Fragmento de código que muestra una vulnerabilidad de inyección de plantillas relacionada con CVE-2025-1974 (IngressNightmare)

Dentro de la función `generateTemplate `, la configuración se procesa tal y como se muestra en el siguiente fragmento de código:

Fragmento de código Go que muestra la lógica de análisis de anotaciones relacionada con la inyección de plantillas CVE-2025-1974 (IngressNightmare)

Sin embargo, la validación y la sanitización de las entradas son insuficientes. Concretamente, el campo «uid» de un objeto Ingress se inserta directamente en la plantilla de configuración de NGINX, lo que crea un punto de inyección. Un atacante puede aprovechar esto enviando entradas manipuladas, como «uid="1234#;\n\n}\n}\n}\n injection_value"».

Esta entrada maliciosa permite la inyección de variables de ámbito global en la plantilla de NGINX, lo que permite a los atacantes activar directivas arbitrarias de NGINX y, potencialmente, lograr la ejecución remota de código (RCE).

Código de configuración de Nginx que muestra una inyección de plantillas relacionada con la vulnerabilidad CVE-2025-1974 (IngressNightmare)

De la inyección de plantillas a la ejecución remota de código

Explicación de la función testTemplate()

Una vez que la función `generateTemplate` ha generado la configuración de NGINX, la función `testTemplate` crea un archivo de configuración temporal y ejecuta el binario de NGINX con el comando `nginx -c {config_file} -t`. Esto obliga al binario de NGINX a analizar y validar la configuración.

Código Go para la función `testTemplate()` y las interfaces relacionadas con la vulnerabilidad CVE-2025-1974 (IngressNightmare)

Para aprovechar la vulnerabilidad, un atacante debe identificar una directiva capaz de ejecutar código malicioso. En un primer momento, nuestros compañeros identificaron la directiva `load_module` como potencialmente útil, ya que esta directiva permite a NGINX cargar complementos externos. Sin embargo, esta directiva solo está permitida en la fase inicial del análisis de la configuración, lo que no se ajusta a nuestro punto de inyección.

Captura de pantalla del código que muestra la sintaxis y el contexto de «load_module», en relación con CVE-2025-1974 (IngressNightmare)
Salida de la terminal que muestra un error en la prueba de configuración de Nginx relacionado con CVE-2025-1974 (IngressNightmare): error en «load_module»

Para resolver este problema, continuamos investigando, lo que nos llevó a la directiva ssl_engine, descrita como «OpenSSL puede cargar el módulo de forma dinámica durante las pruebas de configuración». Esto despertó nuestra curiosidad debido a su capacidad para cargar módulos de forma dinámica, lo que requería un análisis más detallado.

Captura de pantalla del código en la que se explica la sintaxis del dispositivo ssl_engine en el contexto de CVE-2025-1974 (IngressNightmare)

Explicación de la directiva ssl_engine

Para comprender mejor cómo gestiona NGINX la directiva `ssl_engine`, así como para determinar en qué condiciones NGINX permite la carga dinámica de módulos adicionales a través de esta directiva, hemos analizado el código fuente de NGINX.

Fragmento de código C que muestra el análisis de la configuración de NGINX, en relación con la directiva `ssl_engine` de la vulnerabilidad CVE-2025-1974 (IngressNightmare)

Al iniciarse, NGINX carga su estado inicial y, a continuación, analiza los archivos de configuración línea por línea. Cada directiva se gestiona mediante la estructura `nginx_command_t`, y la directiva `ssl_engine` invoca directamente a `ngx_openssl_commands`.

Definición de la estructura C para ngx_command_s relacionada con CVE-2025-1974 (IngressNightmare) y la directiva ssl_engine
Figura 1. Definición de ngx_command_s
Fragmento de código que muestra la matriz de la directiva `ssl_engine`, en relación con el contexto de CVE-2025-1974 (IngressNightmare)
Figura 2: Estructura `ngx_command_t` de ssl_engine

Al analizar la función ngx_openssl_commands, nuestros compañeros descubrieron que depende de la compatibilidad con OpenSSL, concretamente de la función ENGINE_by_id, que se utiliza para los módulos SSL con aceleración por hardware.

Fragmento de código C que muestra la lógica de la directiva ssl_engine, relevante para el análisis de CVE-2025-1974 (IngressNightmare)

Al analizar la función ENGINE_by_id, determinamos que permite la carga dinámica de bibliotecas compartidas. Además, si la biblioteca se compila con la extensión __attribute__((constructor)), la función asociada puede ejecutarse inmediatamente tras la carga. Esto indica que, al aprovechar la directiva ssl_engine, un atacante podría cargar bibliotecas compartidas arbitrarias en el host, lo que podría dar lugar a una ejecución remota de código (RCE).

Librerías compartidas como objetivo y estrategia de ataque

Para facilitar la ejecución de código de forma fiable, el siguiente paso consiste en identificar una biblioteca compartida. En lugar de recurrir a bibliotecas externas, el propio comportamiento de NGINX ofrece un enfoque más viable y controlado: el mecanismo de búfer del cuerpo de la solicitud del cliente. Esta característica permite a NGINX descargar las solicitudes entrantes de gran tamaño en archivos temporales, lo que abre la puerta a posibles vulnerabilidades basadas en un comportamiento predecible en el manejo de archivos.

Código de nginx.conf que muestra las rutas temporales y la configuración del búfer, relevante para el ataque CVE-2025-1974 (IngressNightmare)

De forma predeterminada, cuando una solicitud entrante supera los 8 KB, NGINX escribe el cuerpo de la solicitud en un archivo temporal ubicado en /tmp/nginx/client-body, utilizando un nombre de archivo con el formato cfg-{valor_aleatorio}. Estos archivos temporales se conservan durante un máximo de 60 segundos entre los fragmentos recibidos correctamente de un mensaje.

Diagrama de CVE-2025-1974 (IngressNightmare) que muestra el flujo del ataque dirigido a las bibliotecas compartidas y los archivos temporales de NGINX

Tras escribir una parte del cuerpo de la solicitud en un archivo temporal, NGINX pospone su eliminación hasta que se haya recibido el cuerpo completo. Si la solicitud sigue sin completarse y no se reciben datos durante un máximo de 60 segundos, el archivo acaba siendo eliminado. Sin embargo, al retener intencionadamente el fragmento final de datos, un atacante puede mantener el archivo temporal en uso, lo que lo hace vulnerable a un ataque.

Diagrama que muestra el flujo del ataque CVE-2025-1974 (IngressNightmare), dirigido a las bibliotecas compartidas de NGINX y a la eliminación de archivos

Aunque es posible controlar el contenido del archivo subido, resulta difícil localizarlo en el sistema de archivos debido a que el nombre del archivo es aleatorio. La ruta de almacenamiento se puede configurar mediante client_body_temp_path, pero el nombre del archivo se genera aleatoriamente en tiempo de ejecución, lo que lo hace impredecible. Esta aleatoriedad dificulta considerablemente el acceso selectivo, incluso mediante ataques de fuerza bruta. Para superar esto, el equipo aprovechó comportamientos inherentes al sistema operativo Linux. Consideremos el siguiente ejemplo:

Código en Python que aprovecha la vulnerabilidad CVE-2025-1974 (IngressNightmare) mediante la escritura de archivos y una lógica de bucle infinito

This code opens a file and keeps it in an active state, closely mimicking the behavior of NGINX's client body buffer mechanism. Using /proc/{pid}/fd directory, attackers can find symbolic links created by the Linux kernel that map open file descriptors to their corresponding file paths. This route allows attackers to reduce the brute-force space to only two variables: the process ID (pid) and the file descriptor (fd).

Salida de la terminal que muestra detalles sobre los procesos y los descriptores de archivo relevantes para la estrategia de ataque CVE-2025-1974 (IngressNightmare)

Simulación de la explotación

A partir del análisis anterior, un enfoque práctico para la explotación de RCE dentro del pod de Ingress-NGINX es:

  1. Sube una biblioteca compartida maliciosa utilizando el mecanismo de búfer del cuerpo de la solicitud del cliente de NGINX para almacenarla temporalmente en el sistema de archivos.
  2. Utiliza la inyección de plantillas para lanzar un ataque de fuerza bruta que obligue a NGINX a cargar la biblioteca compartida subida previamente a través de directivas vulnerables.
Diagrama de flujo de explotación de VE-2025-1974 (IngressNightmare) que muestra la ruta de ataque a través de Ingress-NGINX hasta NGINX

Creación de la carga útil que contiene la biblioteca compartida

Para garantizar la ejecución del código al cargarse, se define una función de punto de entrada con extensión de constructor dentro de la biblioteca compartida maliciosa. Esta función se ejecuta cuando NGINX la carga y está diseñada para establecer una conexión de shell inverso con un host remoto. 

Código en C para la creación de la carga útil de CVE-2025-1974 (IngressNightmare) mediante una biblioteca compartida y un comando de shell inverso

Tras la compilación, el tamaño de la biblioteca compartida resultante superó holgadamente los 8 KB, lo que permitió que NGINX la almacenara en el búfer sin necesidad de rellenarla con datos adicionales.

Lista de terminal que muestra la biblioteca compartida «danger.so» para la creación de la carga útil de CVE-2025-1974 (IngressNightmare)

A continuación, nuestros compañeros elaboraron una solicitud con un valor de «Content-Length» inflado (por ejemplo, 1 MB) para provocar una discrepancia de tamaño. Esto hizo que NGINX almacenara en el búfer todo el cuerpo del mensaje en lugar de procesarlo inmediatamente, lo que garantizaba que el objeto compartido se escribiera en una ubicación predecible.

Código Go para crear una carga útil con una biblioteca compartida, relacionada con el exploit CVE-2025-1974 (IngressNightmare)

Activación de la biblioteca compartida mediante inyección

Una vez instalada la biblioteca compartida, a continuación inyectamos una directiva maliciosa en la configuración de NGINX aprovechando el campo «uid» vulnerable. Esta directiva incluía «ssl_engine» apuntando a la ruta del archivo almacenado en el búfer:

Código JSON que muestra un objeto Ingress de Kubernetes con inyección para el exploit CVE-2025-1974 (IngressNightmare)

Para que el RCE tenga éxito, es necesario que la directiva `ssl_engine` haga referencia a la ruta correcta del archivo almacenado en el búfer. Esto se puede lograr mediante un script automatizado de fuerza bruta que recorra sistemáticamente las posibles combinaciones de ID de proceso y descriptores de archivo para identificar el enlace simbólico válido que apunta al objeto compartido almacenado en el búfer.

Código en Go que aprovecha la vulnerabilidad CVE-2025-1974 (IngressNightmare) mediante la inyección de bibliotecas compartidas y la validación de webhooks

A continuación se muestra un ejemplo de la plantilla de NGINX generada que activó el exploit.

Código de configuración de Nginx que muestra una inyección relacionada con CVE-2025-1974 (IngressNightmare) a través de las directivas `ssl_engine` y `mirror`

Si la explotación se llevaba a cabo con éxito, el atacante podía obtener acceso a la shell en el contexto del pod «ingress-nginx», que, por defecto, tenía acceso a secretos confidenciales del clúster de Kubernetes.

Salida del terminal del comando «kubectl get secrets -A», relacionada con CVE-2025-1974 (IngressNightmare)

Mitigación y remediación

Para mitigar de forma eficaz los riesgos asociados al CVE-2025-1974, las organizaciones necesitan una solución que les proporcione visibilidad y control sobre sus componentes de código abierto.

OPSWAT , una tecnología fundamental de la plataforma MetaDefender®, responde a esta necesidad al ofrecer un inventario de todos los componentes de software, bibliotecas, contenedores Docker y dependencias que se utilizan. Permite a las organizaciones realizar un seguimiento, proteger y actualizar sus componentes de forma proactiva.

Captura de pantalla de la interfaz de usuario que muestra la vulnerabilidad crítica CVE-2025-1974 (IngressNightmare) en nginx-ingress-controller

En el ejemplo anterior, la tecnología SBOM de MetaDefender analizó el paquete nginx-ingress-controller, que contenía la vulnerabilidad CVE-2025-1974. El sistema clasificó automáticamente el problema como «crítico» y proporcionó información sobre las versiones corregidas disponibles, lo que permitió a los equipos priorizar y corregir rápidamente la vulnerabilidad antes de que pudiera ser explotada.

OPSWAT está disponible en MetaDefender Core MetaDefender Software Chain™, lo que permite a los equipos de seguridad identificar las vulnerabilidades y actuar con mayor rapidez. Con OPSWAT , los equipos de seguridad pueden:

  • Localice rápidamente los componentes vulnerables: identifique de inmediato los componentes de código abierto afectados por ataques de deserialización. Esto garantiza una actuación rápida, ya sea mediante la aplicación de parches o la sustitución de las bibliotecas vulnerables. 
  • Garantice la aplicación proactiva de parches y actualizaciones: supervise continuamente los componentes de código abierto mediante OPSWAT para adelantarse a las vulnerabilidades de deserialización. OPSWAT puede detectar componentes obsoletos o inseguros, lo que permite realizar actualizaciones oportunas y reducir la exposición a los ataques. 
  • Garantizar el cumplimiento normativo y la presentación de informes: OPSWAT ayuda a las organizaciones a cumplir los requisitos normativos, en un contexto en el que los marcos reguladores exigen cada vez más transparencia en las cadenas de suministro de software.
Etiquetas:

¡Mantente al día con OPSWAT!

Regístrate hoy mismo para recibir las últimas novedades de la empresa, historias, información sobre eventos y mucho más.