Scopri di più sul libro di Benny Czarny “Cybersecurity Upside Down”

Per saperne di più
Per le traduzioni dei siti utilizziamo l'intelligenza artificiale e, sebbene ci sforziamo di essere accurati, non sempre le traduzioni sono precise al 100%. La vostra comprensione è apprezzata.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Di OPSWAT

Il maggio 2025 ha segnato la divulgazione pubblica di una vulnerabilità di sicurezza critica, CVE-2025-1974, soprannominata IngressNightmare, che colpisce il controller ingress-nginx di Kubernetes, ampiamente distribuito nelle infrastrutture cloud native. Questa vulnerabilità consente agli aggressori non autenticati di iniettare configurazioni arbitrarie in NGINX, portando potenzialmente a RCE (esecuzione di codice remoto) non autorizzati e alla compromissione completa del cluster.

Nell'ambito del programma OPSWAT Fellowship, i nostri borsisti hanno condotto un'analisi tecnica approfondita per comprendere meglio le cause, il percorso di sfruttamento e le strategie di mitigazione di questo problema ad alta gravità.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Panoramica di CVE-2025-1974

CVE-2025-1974 è una vulnerabilità critica di template injection identificata nelle versioni di ingress-nginx fino alla 1.11.4 e in particolare nella 1.12.0. Gli aggressori con accesso a livello di nodo a un cluster Kubernetes possono sfruttare questa falla per eseguire codice arbitrario utilizzando RCE attraverso il controller ingress-nginx che, per impostazione predefinita, ha privilegi estesi, compreso l'accesso a segreti critici all'interno del cluster.

Il Kubernetes Security Response Committee ha assegnato a questa vulnerabilità un punteggio CVSS v3.1 di 9.8 (gravità critica):

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Componenti chiave di questa analisi

Panoramica di Kubernetes

Kubernetes (K8s) è una piattaforma open-source per automatizzare la distribuzione, la scalabilità e la gestione operativa delle applicazioni containerizzate. I cluster Kubernetes sono tipicamente composti da più macchine, che possono includere sia hardware fisico che macchine virtuali, che lavorano collettivamente per fornire ambienti applicativi altamente disponibili, scalabili e gestibili.

Controllore d'ingresso NGINX

NGINX ingress controller (ingress-nginx) è un ingress controller open-source costruito sopra il server web NGINX. Opera all'interno di un cluster Kubernetes, funzionando principalmente come reverse proxy e bilanciatore di carico. Questo controller interpreta le risorse Ingress definite dagli utenti e le traduce in configurazioni NGINX attivabili per instradare il flusso di traffico all'interno del cluster.

L'esame di ammissione e il suo ruolo

Ingress-nginx si integra con Kubernetes utilizzando un servizio webhook chiamato AdmissionReview. Questo servizio è fondamentale per elaborare gli oggetti nativi di Kubernetes Ingress e tradurli in configurazioni NGINX convalidate e sintatticamente corrette. Sebbene AdmissionReview garantisca l'accuratezza della configurazione, opera in modo indipendente dal controller ingress-nginx e in genere manca di controlli di autenticazione rigorosi. Questa mancanza di autenticazione rigorosa è un fattore chiave che ha contribuito all'exploit di CVE-2025-1974.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Sfruttamento delle vulnerabilità e analisi tecnica

Meccanismo di sfruttamento

Lo sfruttamento di CVE-2025-1974 inizia con una richiesta dannosa. Gli aggressori creano una richiesta dannosa al webhook AdmissionReview, costringendo NGINX a caricare dinamicamente una libreria condivisa in fase di esecuzione. Sulla base di questo meccanismo, i nostri collaboratori hanno analizzato sia il webhook di AdmissionReview che il flusso di lavoro di NGINX per comprendere questo percorso di exploit.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Vulnerabilità dell'iniezione di template

Nel webhook di AdmissionReview, durante l'elaborazione delle richieste in entrata, la funzione CheckIngress trasforma gli oggetti Ingress di Kubernetes in file di configurazione NGINX validi. Il flusso procede come segue:

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974
  1. Ogni configurazione viene analizzata e trasmessa a `generateTemplate` per essere formattata secondo i modelli NGINX predefiniti.
  2. Successivamente, testTemplate verifica la correttezza della configurazione generata rispetto al binario NGINX sottostante.

Tutte le configurazioni di NGINX si basano su modelli predefiniti che si trovano nel file nginx.tmpl all'interno del codice sorgente di ingress-nginx:

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

All'interno della funzione `generateTemplate`, la configurazione viene elaborata come illustrato nel seguente frammento di codice:

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Tuttavia, la convalida e la sanificazione degli input risultano insufficienti. Nello specifico, il campo `uid` di un oggetto Ingress viene inserito direttamente nel modello di configurazione di NGINX, creando un punto di iniezione. Un malintenzionato può sfruttare questa vulnerabilità fornendo un input appositamente manipolato, ad esempio `uid="1234#;\n\n}\n}\n}\n injection_value"`.

Questo input dannoso consente l'iniezione dell'ambito globale nel modello NGINX, consentendo agli aggressori di attivare direttive NGINX arbitrarie e di ottenere potenzialmente un RCE.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Dall'iniezione di modelli all'esecuzione di codice remoto

Spiegazione della funzione testTemplate()

Dopo che la configurazione di NGINX è stata generata dalla funzione `generateTemplate`, la funzione `testTemplate` crea un file di configurazione temporaneo ed esegue la libreria NGINX con il comando `nginx -c {config_file} -t`. Ciò costringe il binario NGINX ad analizzare e convalidare la configurazione.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Per sfruttare la vulnerabilità, un aggressore deve individuare una direttiva in grado di eseguire codice dannoso. Inizialmente, i nostri colleghi hanno individuato la direttiva `load_module` come potenzialmente utile, poiché questa direttiva consente a NGINX di caricare plugin esterni. Tuttavia, tale direttiva è consentita solo nella fase iniziale dell'analisi della configurazione, il che non corrisponde al nostro punto di iniezione.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974
IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Per risolvere questa sfida, abbiamo proseguito le ricerche, che ci hanno portato alla direttiva `ssl_engine`, descritta come: "Il modulo può essere caricato dinamicamente da OpenSSL durante i test di configurazione". Ciò ha suscitato la nostra curiosità per la sua capacità di caricare dinamicamente i moduli, rendendo necessaria un'analisi più approfondita.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Capire la direttiva ssl_engine

Per comprendere meglio come NGINX gestisce la direttiva `ssl_engine` e per individuare le condizioni in cui NGINX consente il caricamento dinamico di moduli aggiuntivi tramite questa direttiva, abbiamo esaminato il codice sorgente di NGINX.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

All'avvio, NGINX carica il proprio stato iniziale, quindi analizza i file di configurazione riga per riga. Ogni direttiva viene gestita dalla struttura `nginx_command_tstructure`, mentre la direttiva `ssl_engine` richiama direttamente le `ngx_openssl_commands`.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974
Figura 1. Definizione di ngx_command_s
IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974
Figura 2 Struttura ssl_engine ngx_command_t

Analizzando la funzione `ngx_openssl_commands`, i nostri colleghi hanno scoperto che essa si avvale del supporto di OpenSSL, in particolare della funzione `ENGINE_by_id`, utilizzata per i moduli SSL con accelerazione hardware.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Analizzando la funzione ENGINE_by_id, abbiamo appurato che essa consente il caricamento dinamico di librerie condivise. Inoltre, se la libreria è compilata con l’estensione __attribute__((constructor)), la funzione associata può essere eseguita immediatamente al momento del caricamento. Ciò indica che, sfruttando la direttiva ssl_engine, un malintenzionato potrebbe caricare librerie condivise arbitrarie sull’host, con il rischio di provocare un’esecuzione di codice remoto (RCE).

Obiettivi delle librerie condivise e strategia di attacco

Per facilitare in modo affidabile l'esecuzione del codice, il passo successivo consiste nell'individuare una libreria condivisa. Piuttosto che affidarsi a librerie esterne, un approccio più valido e controllato emerge dal comportamento stesso di NGINX: il meccanismo del body buffer del client. Questa funzione consente a NGINX di scaricare le richieste in entrata di grandi dimensioni in file temporanei, aprendo opportunità di sfruttamento basate su un comportamento prevedibile di gestione dei file.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Per impostazione predefinita, quando una richiesta in arrivo supera gli 8KB, NGINX scrive il corpo della richiesta in un file temporaneo situato in /tmp/nginx/client-body, utilizzando un nome di file nel formato cfg-{random_value}. Questi file temporanei vengono conservati per un massimo di 60 secondi tra le parti di un messaggio ricevuto.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Dopo aver scritto un corpo parziale della richiesta in un file temporaneo, NGINX rinvia la cancellazione fino a quando non viene ricevuto l'intero corpo. Se la richiesta rimane incompleta e non vengono ricevuti dati per un massimo di 60 secondi, il file viene infine eliminato. Tuttavia, trattenendo intenzionalmente l'ultimo pezzo di dati, un aggressore può mantenere il file temporaneo in uso, rendendolo sfruttabile.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Sebbene sia possibile controllare il contenuto del file caricato, individuarne la posizione nel file system risulta difficile a causa del nome del file generato in modo casuale. Il percorso di archiviazione può essere configurato tramite `client_body_temp_path`, ma il nome del file viene generato in modo casuale in fase di esecuzione, rendendolo imprevedibile. Questa casualità ostacola in modo significativo l’accesso mirato, anche tramite attacchi di forza bruta. Per superare questo ostacolo, il team ha sfruttato i comportamenti intrinseci del sistema operativo Linux. Si consideri il seguente esempio:

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

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).

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Simulare lo sfruttamento

Sulla base dell'analisi precedente, un approccio pratico di sfruttamento per RCE all'interno del pod Ingress-NGINX è:

  1. Caricare una libreria condivisa dannosa utilizzando il meccanismo del body buffer del client di NGINX per memorizzarla temporaneamente sul file system.
  2. Utilizzare l'iniezione di template per avviare un tentativo di forza bruta che costringe NGINX a caricare la libreria condivisa precedentemente caricata tramite direttive vulnerabili.
IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Creazione del payload contenente la libreria condivisa

Per garantire l'esecuzione del codice al momento del caricamento, all'interno della libreria condivisa malevola viene definita una funzione entrypoint con estensione del costruttore. Questa funzione viene eseguita al momento del caricamento da NGINX ed è progettata per stabilire una connessione reverse shell a un host remoto.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Dopo la compilazione, la dimensione della libreria condivisa risultante superava comodamente gli 8KB, consentendo il buffering da parte di NGINX senza richiedere un padding aggiuntivo.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

I nostri colleghi hanno quindi creato una richiesta con un valore di `Content-Length` gonfiato (ad esempio, 1 MB) per creare una discrepanza nelle dimensioni. Ciò ha indotto NGINX a memorizzare nell'area di buffer l'intero corpo della richiesta anziché elaborarlo immediatamente, garantendo che l'oggetto condiviso venisse scritto in una posizione prevedibile.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Attivazione della libreria condivisa tramite iniezione

Una volta implementata la libreria condivisa, abbiamo quindi inserito una direttiva dannosa nella configurazione di NGINX sfruttando il campo uid vulnerabile. Questa direttiva includeva ssl_engine che puntava al percorso del file bufferizzato:

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Affinché l'RCE abbia esito positivo, è necessario che la direttiva `ssl_engine` faccia riferimento al percorso corretto del file memorizzato nel buffer. Ciò può essere ottenuto tramite uno script automatizzato di tipo "brute force" che esegue sistematicamente un'iterazione sulle possibili combinazioni di ID di processo e descrittori di file per identificare il collegamento simbolico valido che punta all'oggetto condiviso memorizzato nel buffer.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Di seguito è riportato un esempio del modello NGINX generato che ha innescato l'exploit.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Una volta sfruttato con successo, l'attaccante potrebbe ottenere l'accesso alla shell nel contesto del pod ingress-nginx, che per impostazione predefinita ha accesso a segreti sensibili del cluster Kubernetes.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Mitigazione e riparazione

Per mitigare efficacemente i rischi associati a CVE-2025-1974, le organizzazioni necessitano di una soluzione che fornisca visibilità e controllo sui propri componenti open-source.

OPSWAT SBOM, una tecnologia fondamentale della piattaforma MetaDefender®, risponde a questa esigenza fornendo un inventario di tutti i componenti software, le librerie, i container Docker e le dipendenze in uso. Ciò consente alle organizzazioni di tenere traccia, proteggere e aggiornare i propri componenti in modo proattivo.

IngressNightmare: vulnerabilità e rimedio all'esecuzione di codice remoto CVE-2025-1974

Nell'esempio precedente, la tecnologia SBOM di MetaDefender Core™ ha analizzato il pacchetto nginx-ingress-controller che conteneva la vulnerabilità CVE-2025-1974. Il sistema ha automaticamente contrassegnato il problema come Critico e ha fornito indicazioni sulle versioni corrette disponibili, consentendo ai team di assegnare rapidamente le priorità e di applicare la patch alla vulnerabilità prima che possa essere sfruttata.

OPSWAT SBOM è disponibile in MetaDefender Core e MetaDefender Software Supply Chain™, consentendo ai team di sicurezza di identificare e agire più rapidamente sulle vulnerabilità. Con OPSWAT SBOM, i team di sicurezza possono:

  • Individuazione rapida dei componenti vulnerabili - Identificazione immediata dei componenti open-source colpiti da attacchi di deserializzazione. In questo modo è possibile intervenire rapidamente per la patch o la sostituzione delle librerie vulnerabili. 
  • Garantire patch e aggiornamenti proattivi - Monitorare costantemente i componenti open-source tramite OPSWAT SBOM per essere sempre al passo con le vulnerabilità di deserializzazione. OPSWAT SBOM è in grado di rilevare componenti obsoleti o insicuri, consentendo aggiornamenti tempestivi e una minore esposizione agli attacchi. 
  • Mantenere la conformità e la reportistica - OPSWAT SBOM aiuta le organizzazioni a soddisfare i requisiti di conformità, in quanto i quadri normativi richiedono sempre più trasparenza nelle catene di fornitura del software.

Rimanete aggiornati con OPSWAT!

Iscriviti oggi stesso per ricevere gli ultimi aggiornamenti sull'azienda, le notizie, le informazioni sugli eventi e molto altro ancora.