
Immagina di aprire Hacker News e leggere che nel giro di pochi giorni il 70% di internet sarà colpito da due RCE 0day che probabilmente stanno già girando da un po’ e facendo danni nella rete. Ecco, questo è il riassunto abbastanza fedele delle scorse giornate.
Tutto comincia il 20 ottobre, quando il team di sicurezza di PHP pubblica su oss-security un messaggio che di solito non si vede: “ci sono due vulnerabilità critiche, non vi diciamo quali, le patch arrivano domani, tenetevi pronti”. Il giorno dopo escono PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35 e i bug prendono finalmente un nome: CVE-2026-109618 e CVE-2026-109619, battezzati insieme PHP2Shell. Entrambe permettono di eseguire codice da remoto senza autenticazione ed entrambe hanno uno score CVSS di 9.2.
L’embargo, ovviamente, non ha tenuto, ma la storia comincia molto prima di questa settimana.
Seguendo la storyline dello sviluppo di PHP, l’errore di out-of-memory alla base di una delle due vulnerabilità era già stato individuato da uno sviluppatore del core di PHP durante un audit nel 2024. Il bug però non è mai stato corretto: il team non aveva trovato un accordo su come risolverlo e, in assenza di un exploit concreto, la questione era finita in fondo alla lista delle priorità. Due anni dopo, ad agosto 2026, lo stesso problema è stato riscoperto in modo (forse) indipendente da due gruppi. Da una parte Ryan Austin, ricercatore della californiana Calif, che lavorava al progetto “Patch the Planet” di OpenAI e si è fatto aiutare dal modello GPT-5.6 Sol. Dall’altra Wiz, oggi parte di Google Cloud, i cui ricercatori hanno usato Gemini 4 Argon, GPT-5.6 Sol e il loro strumento interno Wiz Atlas. Un bug noto e lasciato lì, che torna fuori grazie all’AI e diventa una RCE critica: è difficile immaginare un esempio migliore di come stia cambiando la ricerca di vulnerabilità.
La divulgazione coordinata era fissata per il 22 ottobre alle 14:00 UTC, ma le cose sono andate diversamente. Dettagli e un PoC sono trapelati in anticipo e la PHP Foundation ha dovuto anticipare il rilascio di un giorno. Il dato più inquietante arriva da Amazon, che ha registrato un tentativo di sfruttamento sui suoi honeypot MadPot già il 17 ottobre, con l’embargo ancora in piedi. Il 21, prima ancora delle patch, Cloudflare dichiarava di vedere i primi attacchi reali e watchTowr segnalava tentativi attivi su entrambe le CVE. Secondo ELLIO, poi, la prima richiesta malevola è arrivata meno di un’ora dopo che Chainguard aveva pubblicato immagini già corrette, rompendo l’embargo e offrendo agli attaccanti il fix in forma binaria da confrontare con le versioni vulnerabili.
E ovviamente sono arrivati i PoC. Su GitHub i repository dedicati a PHP2Shell si sono moltiplicati nel giro di ore, ma come fa notare Recorded Future la qualità è molto variabile e alcuni si basano su teorie di sfruttamento che gli stessi autori hanno poi ritrattato.
Di seguito trovate un PoC pubblicato direttamente dai ricercatori di Wiz, che mostra PHP2Shell in azione su un server WordPress appena installato.
Tutto parte dalla saturazione della memoria da parte del processo PHP. Quando PHP incontra un errore fatale, per esempio quando una richiesta supera il memory limit, non chiude le cose in modo ordinato: fa un bailout, cioè un salto diretto al gestore dell’errore. È veloce, ma si porta via tutto quello che stava succedendo in quel momento, pulizia compresa. Se il salto arriva dopo che PHP ha creato un puntatore, ma prima di averlo inizializzato o azzerato, quel puntatore resta lì, a metà. E siccome un worker PHP serve una richiesta dopo l’altra, quello stato può sopravvivere e finire in mano alla richiesta successiva, magari la vostra, magari quella dell’attaccante.
La CVE-2026-109618 sfrutta proprio l’esaurimento di memoria. Basta una richiesta multipart costruita apposta, per esempio con una parte piena di header o con tanti campi file vuoti, per esaurire la memoria in modo controllato senza sforare i normali limiti di upload. A quel punto la routine di pulizia di fine richiesta legge memoria inizializzata solo per metà e prende decisioni su dati che non dovrebbero esistere. PHP ha confermato una RCE completa via HTTP contro mod_php con i limiti di default. La correzione è concettualmente semplice: in caso di memoria esaurita PHP non molla più tutto a metà, ma si ferma al primo punto sicuro.
La CVE-2026-109619 gioca invece sullo stato globale che resta tra una richiesta e l’altra. Un worker tiene da parte informazioni su errori, sessioni ed estensioni che puntano alla memoria della richiesta in corso, e che andrebbero azzerate prima di liberarla. Se la richiesta si interrompe per un errore fatale, una parte di queste informazioni non viene ripulita, e alla richiesta successiva sullo stesso worker qualcosa la usa prima ancora del normale setup (vi ricordate le scorse vulnerabilità use-after-free?). I percorsi confermati sono due. Il primo passa dai warning generati da impostazioni per directory o per richiesta, come le direttive in .htaccess con mod_php o i PHP_VALUE passati a PHP-FPM, e nascondere gli errori con @ o display_errors non serve a niente. Il secondo è session.upload_progress, una funzionalità attiva per default e raggiungibile da qualunque endpoint POST anche se l’applicazione non usa proprio le sessioni. Qui la RCE è stata dimostrata sia su mod_php sia su PHP-FPM.
I ricercatori hanno quindi messo in fila cinque primitive diverse, che vanno dal crash del worker alla lettura di file arbitrari, passando per la cache delle classi di OPcache, fino a un leak di alcuni KB di memoria del processo restituiti nell’header Set-Cookie: PHPSESSID. Va detto, come sottolinea Imperva, che innescare il bug è facile mentre trasformarlo in esecuzione di codice lo è molto meno: la richiesta successiva deve finire sullo stesso worker e piazzare i dati giusti esattamente nella memoria appena liberata, altrimenti il worker crasha o risponde come se niente fosse. Detto questo, migliaia di tentativi per uno scanner automatico sono un’inezia, e VirusTotal conta oltre 5,1 milioni di host PHP esposti. Prima di provare l’exploit sulle vostre infrastrutture, fate attenzione: il prerequisito è saturare la memoria del worker, e questo potrebbe causare il crash del vostro server.
Che cosa fare adesso, quindi?
La risposta breve è aggiornare, e farlo subito, alla release corretta o al pacchetto patchato della propria distribuzione. Il problema è che tanta gente gira ancora su versioni vecchie: PHP 8.1 e precedenti non ricevono più aggiornamenti, e il team PHP ha pubblicato dei backport minimali per 7.4, 8.0 e 8.1 pensati per chi compila a mano. Chi usa i pacchetti della distro deve aspettare il maintainer, e qui c’è chi si è mosso in fretta: AlmaLinux, per esempio, ha deciso di rilasciare i fix su 8, 9 e 10 senza aspettare Red Hat.
Se non potete aggiornare subito, alcune mitigazioni riducono il rischio, anche se non lo eliminano. Vanno impostate in php.ini, in un file sotto conf.d o nel pool FPM:
- disattivate
session.upload_progress.enabled(e su PHP 8.5 anchefatal_error_backtraces), tenendolo spento anche dopo la patch, visto che quasi nessuno lo usa; - impostate
memory_limit = -1, lasciando il limite di memoria a container o cgroup, e abbassatepost_max_size; - se usate ancora
mod_php, passate a PHP-FPM con MPM event.
Nei log, invece, cercate errori di memoria esaurita insieme a POST multipart anomali, worker che crashano a ripetizione e cookie PHPSESSID di lunghezza assurda.
Al di là delle patch, PHP2Shell è un bel promemoria di quanto sia delicata la gestione degli errori in un vecchio runtime che però è ancora oggi una delle basi della maggior parte delle pagine web. Si parla del 70% di internet colpito, ma il dato nasce dal fatto che circa il 70% dei siti usa PHP. Non è detto che l’exploit vada a segno su un numero così grande di istanze: molti server sono protetti da WAF (come i siti dietro Cloudflare), altri usano installazioni PHP custom per una parte minima del servizio, che non può essere raggiunta da un attaccante per saturarne la memoria (pensate ai task periodici interni dei servizi web).
Il bug, comunque gravissimo, risiede proprio nel codice core di qualcosa con cui interagiamo costantemente (probabilmente anche tu, ora che stai leggendo questo blog). Un’esposizione del genere ricorda molto Log4Shell, che ha causato e continua a causare danni anche sui server mai aggiornati di oggi, e lo stesso succederà con PHP2Shell. Sicuramente ne vedremo delle belle nel prossimo futuro. Comunque, aggiornate, spegnete quello che non vi serve e, se avete ancora un PHP 7 in giro, questa è l’occasione buona per toglierlo di mezzo.
Red Team & Offensive Security Engineer
Parlo di sicurezza informatica offensive, Linux e Open Source





















