
Proof-of-concept per CVE-2026-9256, un overflow del buffer heap nel modulo ngx_http_rewrite_module di NGINX. Dimostra il crash del worker e il denial of service tramite URI appositamente modificati con gruppi di cattura PCRE sovrapposti. Include verifica in più fasi e probing keep-alive.
Campo di applicazione: solo per ambienti di test locali, ambienti di riproduzione autorizzati, verifica delle vulnerabilità e analisi delle regole di protezione. Non utilizzare su obiettivi non autorizzati. Le idee PoC in questo documento verificano solo il comportamento di crash del worker NGINX visibile da remoto, non includono RCE, bypass ASLR o catene di exploit stabili.
CVE-2026-9256 è una vulnerabilità di heap buffer overflow nel modulo ngx_http_rewrite_module di NGINX. L'attivazione della vulnerabilità non avviene semplicemente visitando un URI fisso, ma dipende da uno specifico schema di configurazione rewrite: i gruppi di cattura PCRE nelle regex di rewrite si sovrappongono e la parte di replacement fa riferimento a più variabili di cattura, ad esempio $1, $2.
Quando un attaccante costruisce un URI speciale che fa entrare la logica rewrite nel percorso pertinente, NGINX, durante l'elaborazione del contenuto catturato, la concatenazione del risultato rewrite o l'escape URI/parametri, può presentare una discrepanza tra il calcolo della lunghezza e la scrittura effettiva, causando infine un danneggiamento della memoria heap del processo worker.
Pertanto, la chiave di questa vulnerabilità non è il percorso /api in sé, ma se nella configurazione NGINX di destinazione esiste una regola rewrite vulnerabile che può essere attivata da una richiesta. Il percorso /api utilizzato di default nel PoC è solo un esempio nell'ambiente di riproduzione corrente; nei test reali, è necessario regolare il percorso della richiesta in base alle regole rewrite che presentano gruppi di cattura sovrapposti e che fanno riferimento a più variabili di cattura nella configurazione NGINX.
L'obiettivo attuale del PoC è verificare il comportamento di crash del worker / denial of service. Non tenta di costruire un preciso layout di heap, non tenta di sovrascrivere l'indirizzo di ritorno o i puntatori a funzione, e non dimostra l'esecuzione di codice remoto. Le evidenze stabili osservabili da remoto sono principalmente: la connessione della richiesta di attivazione viene interrotta in modo anomalo, successivamente il servizio NGINX riprende a rispondere, le connessioni keep-alive vengono interrotte dal crash del worker dopo l'attivazione.
Dopo l'attivazione di questa vulnerabilità, non si manifesta necessariamente come un codice di stato HTTP fisso 500, 502 o 400. La ragione è che il modello master-worker di NGINX fa sì che il processo worker vada in crash e venga poi riavviato dal master. L'effetto osservato dall'attaccante da remoto di solito non è un servizio completamente indisponibile, ma una connessione che si interrompe improvvisamente, un timeout di lettura, una connessione resettata, seguita da una successiva richiesta a / che ottiene una risposta normale.
Pertanto, il PoC non può giudicare l'esistenza della vulnerabilità basandosi solo sul codice di stato HTTP di una singola richiesta. Se si invia un URI lungo una volta, si vede la connessione interrotta e si conclude direttamente "la vulnerabilità esiste", il rischio di falsi positivi è elevato. L'interruzione della connessione potrebbe anche essere causata da jitter di rete, timeout del proxy, intercettazione da parte di dispositivi intermedi, limitazione della velocità del backend o chiusura attiva della connessione da parte del server.
Pertanto, il PoC deve essere progettato come una verifica a più fasi:
Solo quando si verificano contemporaneamente "connessione di attivazione anomala + successivo ripristino del servizio + cadute multiple in keep-alive" si può giudicare con maggiore sicurezza l'esistenza di un comportamento di crash del worker stile CVE-2026-9256.
Il percorso di attivazione principale dell'attuale PoC è:
GET /api/++++++++++++++++++++++++++++++++... HTTP/1.1
Host: 127.0.0.1:19321
Dove /api/ è la route di esempio nell'ambiente di test corrente utilizzata per colpire la regola rewrite, seguita da una grande quantità di caratteri +. Il numero predefinito è 4096.
Ci sono principalmente tre motivi per la scelta di +.
In primo luogo, + è un carattere URI legale; quando inviato tramite un client HTTP normale, di solito non viene troncato o riscritto forzatamente come caratteri spazio, #, ecc. Pertanto, il PoC attuale non richiede la costruzione di una riga di richiesta illegale tramite socket raw, come accade per alcune vulnerabilità di bypass del request-target.
In secondo luogo, un gran numero di caratteri ripetuti fornisce un input sufficientemente lungo per i gruppi di cattura rewrite, ampliando la scala di output della successiva concatenazione o elaborazione di escape del replacement, facilitando così il verificarsi di una discrepanza tra il calcolo della lunghezza e la scrittura effettiva.
In terzo luogo, la struttura del payload di + ripetuti è semplice, facile da osservare nei pacchetti catturati, nei log e nelle regole IDS, e facilita la regolazione della lunghezza per test di soglia.
Tuttavia, va notato che + non è l'unico carattere teoricamente in grado di attivare la vulnerabilità. La vera condizione di attivazione rimane "colpire una configurazione rewrite vulnerabile + input in grado di entrare nei gruppi di cattura pertinenti + l'elaborazione dell'output rewrite che innesca un heap overflow". In ambienti diversi, la route di attivazione, il tipo di carattere e la soglia di lunghezza potrebbero dover essere regolati.
L'attuale PoC sceglie di default una grande quantità di + come carattere di attivazione, ma ciò non significa che solo + possa attivare il problema. + è semplicemente il carattere più adatto per essere scritto in un PoC generico, perché è relativamente stabile negli URI, facile da inviare con un client HTTP normale e la sua impronta nei pacchetti catturati è chiara.
Dal punto di vista del principio della vulnerabilità, purché il carattere entri nella logica di escape NGX_ESCAPE_ARGS durante l'elaborazione rewrite di NGINX e si espanda da 1 byte originale a 3 byte in forma %XX, può causare una differenza tra "valore calcolato della lunghezza" e "valore effettivo scritto". In altre parole, il punto di attivazione non è essenzialmente + stesso, ma "la presenza densa di caratteri che possono essere escaped in modalità args".
Oltre a +, i caratteri teoricamente importanti da considerare includono:
Spazio: 0x20
#: 0x23
%: 0x25
&: 0x26
?: 0x3F
Caratteri di controllo: 0x00-0x1F
Byte alti: 0x7F-0xFF
Se questi caratteri entrano nei capture pertinenti e vengono trattati come contenuto args durante l'escape nel replacement rewrite, produrranno un effetto di espansione simile. Ad esempio:
+ -> %2B
& -> %26
% -> %25
# -> %23
? -> %3F
Spazio -> %20
Ogni occorrenza di un tale carattere si espanderà teoricamente da 1 byte a 3 byte, aumentando la lunghezza effettivamente scritta di 2 byte. Se nell'input sono presenti molti di questi caratteri, la lunghezza effettivamente scritta può superare significativamente la lunghezza del buffer calcolata erroneamente in precedenza, facilitando l'innesco dell'heap buffer overflow.
Tuttavia, l'usabilità di diversi caratteri in un PoC non è del tutto uguale.