Critical Ingress NGINX Controller Vulnerability Allows RCE Without Authentication

Age
5 months ago
Threat Information
Summary

A critical set of vulnerabilities, known as IngressNightmare, has been identified in the Ingress NGINX Controller for Kubernetes, potentially affecting over 6,500 clusters by allowing unauthenticated remote code execution. These vulnerabilities, identified as CVE-2025-24513, CVE-2025-24514, CVE-2025-1097, CVE-2025-1098, and CVE-2025-1974, have been given a CVSS score of 9.8. They exploit the admission controller component's network accessibility without authentication, allowing attackers to inject arbitrary NGINX configurations through malicious ingress objects. This can lead to unauthorized access to all secrets stored across namespaces, potentially resulting in a full cluster takeover. The flaws are particularly concerning as they enable the execution of arbitrary code by exploiting the admission controller's elevated privileges. To mitigate these risks, users are advised to update to the latest versions of the Ingress NGINX Controller and restrict network access to the admission controller.

How BlueRock Helps

This security issue gives an attacker the ability to achieve unauthenticated remote code execution on Kubernetes Ingress NGINX controllers by exploiting vulnerabilities in the admission controller, potentially leading to full cluster takeover. The following protection guardrails can further prevent the following steps an attacker can take: The attacker first uploads a malicious shared library to the controller's pod and then, by sending a specially crafted request to the unauthenticated admission controller, injects a malicious NGINX configuration that causes this library to be loaded. Library Load Path Allow helps prevent this critical step by blocking the loading of the attacker's shared library if it's placed in and attempted to be loaded from a directory not on the pre-defined allowlist, thus stopping the malicious NGINX configuration from successfully executing the payload. If the library loading is somehow attempted from an allowed path, Container Drift Protection (Binaries & Scripts) further prevents the actual remote code execution by blocking the execution of this unauthorized shared library, as it constitutes new, untrusted code not present in the original container image. Once an attacker achieves remote code execution, they might attempt to establish a reverse shell for interactive control; Reverse Shell Protection detects and blocks such attempts by preventing shell file descriptors from being bound to network sockets, severing this command and control channel. To escalate privileges or move laterally, the attacker might try to run additional tools or scripts from arbitrary locations within the compromised pod; Process Path Exec Allow restricts this by ensuring new processes can only be launched from pre-approved filesystem paths, limiting the attacker's ability to execute arbitrary downloaded tools. Furthermore, if the attacker attempts to execute known malicious or reconnaissance tools like netcat after gaining RCE, Process Exec Deny would block their execution based on policy. The attacker would then likely try to access sensitive information such as API tokens or credentials; Sensitive File Access helps prevent the exfiltration of data by detecting and blocking attempts to read Kubernetes secrets mounted as files within the pod or other critical configuration files designated as sensitive. To achieve wider control, the attacker might abuse the compromised pod's Service Account to interact with the Kubernetes API, aiming to access secrets across all namespaces or deploy malicious workloads. Namespace Execution Guard steps in here, preventing unauthorized broad API interactions indicative of cluster takeover attempts, such as an attempt by the compromised service account to list or access secrets across all namespaces. If the attacker tries to deploy a new malicious workload designed to run with excessive privileges (e.g., securityContext: {privileged: true}), Container Capability Control limits this by enforcing a reduced, policy-defined set of Linux capabilities for any container, thereby restricting what even a "privileged" malicious pod can do at the kernel level. Finally, to gain full control over the node or deploy further unmanaged containers, an attacker with RCE might attempt to interact with the node's container runtime socket (e.g., docker.sock); Container Runtime Socket Protection prevents such unauthorized access to this critical socket from within the compromised pod, thwarting a common container escape and cluster takeover vector.

MITRE ATT&CK Techniques Inferred
  • T1068: Exploitation for Privilege Escalation: The attacker exploited a vulnerability in the Ingress NGINX Controller for Kubernetes, which allows for unauthenticated remote code execution. This vulnerability, named IngressNightmare, affects the admission controller component, allowing an attacker to inject arbitrary NGINX configurations. This is a classic example of Exploitation for Privilege Escalation, where the attacker takes advantage of a flaw to gain elevated privileges within the system.
  • T1021: Remote Services: The attacker uses the vulnerability to execute arbitrary code on the Ingress NGINX Controller's pod. This is done by injecting a malicious NGINX configuration through AdmissionReview requests. This scenario is indicative of Remote System Discovery, where the attacker is attempting to execute code on a remote system to gain control.
  • T1059: Command and Scripting Interpreter: Once the malicious configuration is injected, the attacker can load a shared library to the pod, which effectively leads to remote code execution. This action represents Command and Scripting Interpreter, where the attacker uses scripts or code execution to control the compromised system.
  • T1552: Unsecured Credentials: The attacker is able to access all secrets stored across all namespaces in the Kubernetes cluster by exploiting the elevated privileges and network accessibility of the admission controller. This represents Access to Non-Public Data, where the attacker gains unauthorized access to sensitive information within the system.
  • T1078: Valid Accounts: The attacker can take over the entire Kubernetes cluster by abusing a strong Service Account to read Kubernetes secrets. This is an example of Valid Accounts, where the attacker uses legitimate credentials or access tokens to maintain persistent access to the system.
Fact-Based Attack Chains

F1: Exploitation of IngressNightmare vulnerabilities (CVE-2025-24513, CVE-2025-24514, CVE-2025-1097, CVE-2025-1098, CVE-2025-1974) leading to unauthenticated remote code execution on the Ingress NGINX Controller, secret exfiltration, and potential cluster takeover by abusing its unauthenticated admission controller.

  • Attacker identifies an Ingress NGINX Controller for Kubernetes where the admission controller component is accessible over the network without authentication. (Cited from: "admission controllers, deployed within a Kubernetes pod, are accessible over the network without authentication", "putting over 6,500 clusters at immediate risk by exposing the component to the public internet.")
  • Attacker prepares a malicious payload, such as a shared library, designed to be executed on the controller's pod. (Cited from: "upload a malicious payload in the form of a shared library to the pod")
  • Attacker uploads the malicious payload (shared library) to the Ingress NGINX Controller's pod, potentially utilizing the client-body buffer feature of NGINX. (Cited from: "upload a malicious payload in the form of a shared library to the pod by using the client-body buffer feature of NGINX")
    • BR-75: Critical Directory Write Protection - This mechanism is applicable because if the attacker attempts to upload the malicious shared library to a directory designated as critical by policy (e.g., core application directories), this mechanism would block the unauthorized write attempt, preventing the payload from being staged.
    • BR-54: Container Drift Protection (Binaries & Scripts) - This mechanism is applicable because while it primarily blocks execution, the act of uploading a new shared library (which is executable code) into the container environment is a precursor to drift. The mechanism's manifest of original executables would not include this new library, leading to its execution being blocked later (as covered in steps 6 & 7).
    • BR-62: Linux/Host Drift Protection - This mechanism is applicable because the uploaded shared library constitutes a new file added outside of trusted package managers. While the block occurs at execution time, the detection of this new file is part of the drift protection concept.
  • Attacker crafts a malicious AdmissionReview request (a malicious ingress object). This request includes an arbitrary NGINX configuration injection leveraging one or more vulnerabilities like CVE-2025-24514 (auth-url Annotation Injection), CVE-2025-1097 (auth-tls-match-cn Annotation Injection), CVE-2025-1098 (mirror UID Injection), or CVE-2025-1974 (NGINX Configuration Code Execution). (Cited from: "injecting an arbitrary NGINX configuration remotely by sending a malicious ingress object (aka AdmissionReview requests) directly to the admission controller", "The request, in turn, contains one of the aforementioned configuration directive injections that causes the shared library to be loaded", "CVE-2025-24514 – auth-url Annotation Injection", "CVE-2025-1097 – auth-tls-match-cn Annotation Injection", "CVE-2025-1098 – mirror UID Injection", "CVE-2025-1974 – NGINX Configuration Code Execution")
  • Attacker sends the crafted AdmissionReview request directly to the exposed, unauthenticated admission controller endpoint. (Cited from: "sending a malicious ingress object (aka AdmissionReview requests) directly to the admission controller", "admission controllers [...] are accessible over the network without authentication.")
  • The injected NGINX configuration directive within the AdmissionReview request causes the NGINX process running in the controller's pod to load the attacker's previously uploaded shared library. (Cited from: "The request, in turn, contains one of the aforementioned configuration directive injections that causes the shared library to be loaded")
    • BR-89: Library Load Path Allow - This mechanism is applicable because it restricts the directories from which shared libraries (.so files) can be loaded. If the attacker's shared library is uploaded to and loaded from a path not on the pre-defined allowlist (e.g., a temporary or user-writable directory), this mechanism would block the mmap() call used for library loading.
    • BR-54: Container Drift Protection (Binaries & Scripts) - This mechanism is applicable because the shared library is a new executable component not present in the original container image. Loading this library for execution constitutes container drift, which this mechanism is designed to prevent by blocking the execution of such new code.
    • BR-58: X-Lib Overwrite Supply Chain Defense - This mechanism is applicable because the loading of an unauthorized, malicious shared library due to injected configuration constitutes an unauthorized library interaction. It aims to prevent scenarios where library calls are manipulated, and loading an entirely malicious library fits the broader goal of controlling library interactions, even if not a classic 'xzutils' style compromise of an existing library.
  • The loading of the malicious shared library results in remote code execution (RCE) on the Ingress NGINX Controller's pod. (Cited from: "effectively leading to remote code execution", "resulting in code execution on the Ingress NGINX Controller's pod.")
    • BR-54: Container Drift Protection (Binaries & Scripts) - This mechanism is directly applicable as it prevents the execution of any new executable binaries or scripts (like the malicious shared library) that were not part of the original container image, thus blocking the RCE. If this software ran inside a container, then this mechanism applies because the malicious shared library is new code not present in the original image.
    • BR-88: Process Path Exec Allow - This mechanism is applicable if the RCE, achieved through the loaded library, subsequently attempts to execute new processes (using exec() syscalls) from filesystem paths not on the allowlist. Note: This mechanism does not apply if the NGINX process (parent of the RCE context) is running as root.
    • BR-82: Process Runtime Execution Guardrails - This mechanism is applicable if the RCE attempts to start any new, unauthorized processes within the container. It uses NSJail to enforce that only authorized processes can run.
    • BR-55: Reverse Shell Protection - This mechanism is applicable because the vulnerability leads to RCE. As per its LLM Correlation Rule, if RCE is achieved, it's assumed the attacker can establish a reverse shell, which this mechanism would detect and block by preventing shell file descriptors from being bound to network sockets.
    • BR-62: Linux/Host Drift Protection - This mechanism is applicable because the execution of the malicious shared library represents code execution from a file added outside of trusted package managers, which this mechanism aims to block.
    • BR-65: Container Host Drift Prevention - This mechanism is applicable because it ensures only allow-listed containers/processes can execute new or modified files. If the NGINX controller pod or the NGINX process is not allow-listed to execute this new malicious library, its execution would be blocked.
  • Post-RCE, the attacker injects further malicious NGINX configurations or executes arbitrary commands to read sensitive files and run arbitrary code within the compromised pod. (Cited from: "injecting malicious configuration, and utilizing it to read sensitive files and run arbitrary code.")
    • BR-91: Sensitive File Access - This mechanism is applicable because if the attacker attempts to read files designated as sensitive (e.g., /etc/shadow, SSH keys, API tokens stored in files) using the RCE, this mechanism would detect and potentially block such access attempts based on policy.
    • BR-75: Critical Directory Write Protection - This mechanism is applicable if the attacker, post-RCE, attempts to inject further malicious NGINX configurations by writing to configuration files located in directories protected by this policy.
    • BR-54: Container Drift Protection (Binaries & Scripts) - This mechanism is applicable if the 'execution of arbitrary commands' involves running new binary or script files dropped by the attacker post-RCE that were not part of the original container image.
    • BR-88: Process Path Exec Allow - This mechanism is applicable if the 'execution of arbitrary commands' involves exec()-ing new processes from filesystem paths not on the allowlist. (Note: Root limitation applies if parent is root).
    • BR-90: Process Exec Deny - This mechanism is applicable if the 'execution of arbitrary commands' involves running processes explicitly denied by this mechanism's policy (e.g., default blocks on /nc/wget/curl).
    • BR-82: Process Runtime Execution Guardrails - This mechanism is applicable if the 'execution of arbitrary commands' involves starting new, unauthorized processes.
    • BR-55: Reverse Shell Protection - This mechanism is applicable as the attacker has RCE and might use arbitrary command execution to establish a reverse shell, which this mechanism would block.
    • BR-62: Linux/Host Drift Protection - This mechanism is applicable if the arbitrary code being executed is from a new file not installed via a trusted package manager.
    • BR-65: Container Host Drift Prevention - This mechanism is applicable if the arbitrary code is a new/modified file executed by a non-allow-listed process within the pod's context potentially affecting the host view if filesystem is shared or mechanism has pod visibility.
  • The attacker abuses the (potentially highly privileged) Service Account associated with the Ingress NGINX Controller's pod to interact with the Kubernetes API. (Cited from: "permit an attacker to abuse a strong Service Account", "The admission controller's elevated privileges and unrestricted network accessibility create a critical escalation path")
    • BR-47: Container Capability Control - This mechanism is applicable because it allows defining specific, reduced capabilities for containers, overriding Kubernetes defaults. If the Ingress controller pod was granted excessive Linux capabilities, this mechanism could restrict them, thereby limiting the potential impact of SA token abuse if actions require those capabilities at the pod level.
    • BR-67: Container Root User Control - This mechanism is applicable if the process within the pod abusing the Service Account token is running as root unnecessarily. Preventing non-init processes from running as root could limit the attacker's ability to perform certain actions even with a powerful SA token, especially actions within the pod itself.
    • BR-49: Namespace Execution Guard - This mechanism is applicable as per its LLM Correlation Rule: "IF an attack chain step mentions anything LIKE complete Kubernetes cluster takeover, THEN it's LIKELY this mechanism IS APPLICABLE." Abusing a highly privileged Service Account to interact with the K8s API is a key step towards cluster takeover.
  • Utilizing the compromised Service Account, the attacker gains unauthorized access to and exfiltrates all secrets stored across all namespaces in the Kubernetes cluster. (Cited from: "unauthorized access to all secrets stored across all namespaces in the Kubernetes cluster by attackers", "read Kubernetes secrets")
    • BR-91: Sensitive File Access - This mechanism is applicable if the Kubernetes secrets are mounted as files into the compromised pod or other accessible pods, and these file paths (e.g., default secret mount paths, or specific paths like /.ssh/id_) are monitored. Accessing these files would be detected/blocked.
    • BR-52: Data Resource Mandatory Access Control - This mechanism is applicable if secrets are stored as files in critical data directories protected by this MAC policy, and the attacker uses a non-allow-listed binary (spawned via RCE) to access them.
    • BR-49: Namespace Execution Guard - This mechanism is applicable as accessing all secrets across all namespaces is a significant step towards cluster takeover, fitting the LLM Correlation Rule for this mechanism.
  • This successful exploitation, including RCE and secret exfiltration, can ultimately lead to a complete takeover of the Kubernetes cluster. (Cited from: "can result in cluster takeover", "ultimately facilitate cluster takeover", "complete cluster takeover.")
    • BR-49: Namespace Execution Guard - This mechanism is directly applicable based on its LLM Correlation Rule: "IF an attack chain step mentions anything LIKE complete Kubernetes cluster takeover, THEN it's LIKELY this mechanism IS APPLICABLE."
    • BR-61: Container Runtime Socket Protection - This mechanism is applicable because if the vulnerable software ran inside a container, an attacker achieving RCE and aiming for cluster takeover might attempt to interact with the underlying node's container runtime socket (e.g., containerd.sock or docker.sock) to deploy privileged containers or manipulate existing ones, bypassing Kubernetes API controls. This mechanism would prevent unauthorized processes from accessing that socket.
See Blue Rock In Action