
Regole di rilevamento per CVE-2026-23918 Apache http2 RCE - Crediti: stringa.ai, isec.pl
Pubblicato: 2026-05-04
CVSSv3: 8.8 (Alto)
Tipo: Esecuzione di codice remoto / Denial of Service (corruzione della memoria double-free)
Componente: Apache HTTP Server mod_http2 (percorso di pulizia dello stream in h2_mplx.c)
Interessato: Apache HTTP Server 2.4.66 con HTTP/2 abilitato e MPM multi-threaded
Riferimenti:
CVE-2026-23918 è una vulnerabilità di corruzione della memoria double-free nell'implementazione del protocollo HTTP/2 di Apache HTTP Server 2.4.66, che interessa solo il percorso di pulizia dello stream del modulo mod_http2 in h2_mplx.c. Consente a un attaccante remoto non autenticato di mandare in crash i processi worker di Apache (Denial of Service) con una singola connessione TCP e due frame HTTP/2. In condizioni presenti sui sistemi derivati da Debian e sulle immagini Docker ufficiali di Apache, il double-free può essere trasformato in una piena esecuzione di codice remoto.
Lo sfruttamento del DoS è stato confermato in ambienti reali. Sono state osservate scansioni Internet su larga scala rivolte a endpoint HTTP/2. L'exploit RCE si è dimostrato utilizzabile in ambienti controllati, anche se al momento non vi è alcuna evidenza di sfruttamento pubblico diffuso per la RCE.
MPM prefork non è interessato: la vulnerabilità richiede una configurazione MPM multi-threaded (worker, event o simile). CVE-2026-23918 interessa solo Apache HTTP Server versione 2.4.66.
Attacker opens HTTP/2 connection to Apache 2.4.66 (mod_http2 loaded, multi-threaded MPM) └─ Sends HTTP/2 HEADERS frame on stream N (opens the stream) └─ Immediately sends RST_STREAM on stream N (non-zero error code) └─ Sent BEFORE the multiplexer has registered the stream
Two nghttp2 callbacks fire in sequence: ├─ on_frame_recv_cb (RST received) → calls h2_mplx_c1_client_rst → m_stream_cleanup └─ on_stream_close_cb (stream closed) → calls h2_mplx_c1_client_rst → m_stream_cleanup
Result: same h2_stream pointer pushed onto spurge[] cleanup array TWICE
c1_purge_streams() iterates spurge[] and calls h2_stream_destroy() on each entry: ├─ First call: valid — frees the stream └─ Second call: DOUBLE-FREE — operates on already-freed memory → heap corruption
DoS path (trivial, in the wild): └─ Heap corruption → SIGABRT in worker process → worker dies → service disruption
RCE path (requires mmap allocator — default on Debian/Ubuntu and official Docker): └─ Attacker places fake h2_stream struct at freed virtual address via mmap reuse └─ Points pool cleanup function pointer to system() └─ Uses Apache scoreboard shared memory (fixed address, ASLR-resistant) as payload container └─ c1_purge_streams() executes system() with attacker-controlled argument → RCE
> **Asimmetria chiave:** Il percorso DoS non richiede competenze di manipolazione dell'heap ed è già oggetto di sfruttamento attivo. Il percorso RCE è tecnicamente impegnativo, ma è stato dimostrato in condizioni di laboratorio e sarà quasi certamente armato nel prossimo futuro, dato l'indirizzo fisso dello scoreboard resistente ad ASLR.
---
## Architettura di rilevamento
> Questa sezione spiega perché gli strumenti di rilevamento qui differiscono sostanzialmente da un tipico pacchetto di escalation dei privilegi locali.
Copy Fail (CVE-2026-31431) era una vulnerabilità **lato host, post-accesso**. L'attaccante necessitava di una presenza già attiva sul sistema. Il rilevamento risiedeva principalmente a livello di syscall (auditd, Wazuh) con scansione YARA dello script PoC su disco.
CVE-2026-23918 è una vulnerabilità **lato rete, pre-accesso**. L'exploit arriva come frame del protocollo HTTP/2 sulla rete prima che venga eseguito qualsiasi codice applicativo. Questo sposta in modo significativo lo stack di rilevamento:
| Livello | Copy Fail (LPE) | CVE-2026-23918 (RCE) |
|---|---|---|
| **Rilevamento primario** | Regole syscall di Auditd | Regole di rete Suricata |
| **WAF (ModSecurity)** | Limitato — non vede l'exploit | Rilevante — anomalia + post-exploit |
| **Auditd** | Rilevamento principale | Rilevamento degli esiti (crash, post-exploit) |
| **YARA** | Cerca lo script PoC | Cerca web shell (artefatti post-exploit) |
| **IDS di rete** | Non applicabile | Livello di rilevamento di prima classe |
| **Ispezione TLS** | N/D | Necessaria per una copertura Suricata completa |
La regola pratica: per una RCE a livello di rete, lavorare dall'esterno verso l'interno (rete → WAF → host). Per l'escalation dei privilegi locale, lavorare dall'host verso l'esterno.
---
## Limiti del rilevamento
> **Leggere questo prima di distribuire qualsiasi regola.**
**1. TLS termina la visibilità HTTP/2.**
La maggior parte delle distribuzioni Apache in produzione servono HTTPS. Suricata non può ispezionare il contenuto dei frame HTTP/2 cifrati senza che sia configurata la decifratura TLS. Se la tua distribuzione Suricata non ha accesso alle chiavi di sessione TLS o a un mirror di decifratura, le regole a livello di rete di seguito rileveranno solo:
- HTTP/2 in chiaro (h2c) — poco comune in produzione ma presente in ambienti interni
- La firma di rete del comportamento delle connessioni TCP (numero di connessioni, pattern RST a livello TCP)
Per le distribuzioni HTTPS, abilita la decifratura TLS di Suricata tramite l'impostazione `tls-decrypt` e la registrazione delle chiavi di sessione, oppure affidati ai livelli WAF (ModSecurity/Coraza) e host-based (auditd/Wazuh).
**2. ModSecurity non può bloccare l'innesco dell'exploit.**
Il double-free avviene all'interno del parser dei frame HTTP/2, prima che una richiesta HTTP completa venga assemblata e passata a ModSecurity. Il WAF vede la richiesta solo dopo il completamento del parsing dei frame — a quel punto il danno potrebbe essere già fatto. ModSecurity in questo pacchetto è usato per il rilevamento delle anomalie, il rate limiting e il rilevamento post-exploitation, non come blocco per l'innesco.
**3. MPM prefork non è interessato.**
Se la tua distribuzione Apache utilizza `mpm_prefork_module` (mono-thread), questa vulnerabilità non si applica. Il bug si manifesta solo negli MPM multi-thread (`mpm_event_module` o `mpm_worker_module`). Verifica con `apachectl -V | grep MPM` prima di distribuire regole che produrrebbero falsi positivi su server prefork.