
Exploit de preuve de concept pour la vulnérabilité de double libération Apache mod_http2 (CVE-2026-23918) avec phases de reconnaissance, d'exploitation et d'évaluation des risques RCE.
Affecté: Apache HTTP Server 2.4.66 avec mod_http2 + Event MPM
Corrigé dans: Apache 2.4.67 (mod_h2 v2.0.37)
CVSS 3.1: 8.8 HIGH — Exécution de code à distance non authentifiée possible
CWE: CWE-415 (Double Free)
mod_http2 dans Apache 2.4.66 a un bug de double free dans h2_mplx.c:m_stream_cleanup(). Le problème survient lorsqu'un client envoie une trame HEADERS immédiatement suivie d'un RST_STREAM sur le même flux. Si le timing est bon, le flux se retrouve poussé deux fois dans le tableau de purge m->spurge. Lorsque le mplx est détruit, le pool APR est libéré deux fois, ce qui corrompt le tas et provoque un SIGABRT ou un SIGSEGV.
Apache a corrigé cela dans mod_h2 v2.0.37 en introduisant add_for_purge(), une simple vérification de déduplication qui empêche le même flux d'être ajouté deux fois.
// Vulnérable (< v2.0.37)
APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream; // peut arriver deux fois
// Corrigé (v2.0.37+)
static int add_for_purge(h2_mplx *m, h2_stream *stream) {
for (int i = 0; i < m->spurge->nelts; ++i)
if (APR_ARRAY_IDX(m->spurge, i, h2_stream*) == stream)
return FALSE;
APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream;
return TRUE;
}
Par défaut, le script exécute un pipeline en 3 phases sur la cible :
| Phase | Description |
|---|---|
| 1 — Recon | Détecte la version d'Apache, le support HTTP/2 via ALPN, le type de MPM |
| 2 — Exploit | Envoie des salves HEADERS+RST_STREAM en threads, essaie le mode inline puis staged |
| 3 — RCE Assessment | Mesure la cohérence des crashs et évalue le niveau de risque |
Le score RCE est calculé à partir de trois signaux détectables à distance. Premièrement, si Apache 2.4.66 est en cours d'exécution. Deuxièmement, si le MPM Event ou Worker est utilisé (mod_http2 refuse de démarrer avec Prefork, donc si HTTP/2 fonctionne, c'est un MPM threadé). Troisièmement, la déterministe du crash — un crash dès le premier tour signifie que la corruption du tas est contrôlée et reproductible, ce qui est nécessaire pour le RCE.
pip install hpack requests
# PoC complet sur une cible unique (comportement par défaut)
python poc.py -t 192.168.1.100
# Augmenter la pression avec plus de tours, de plus grosses salves et plus de threads
python poc.py -t 192.168.1.100 -n 20 -b 500 -w 5
# Vérification passive uniquement, rien n'est envoyé à la cible
python poc.py -t example.com --check-only
# Analyser une liste entière de cibles
python poc.py -l sites.txt -o results.json
# Vérification passive sur une liste
python poc.py -l sites.txt --check-only
# Générer un rapport Markdown après l'exécution
python poc.py -t target.com --report report.md
# une cible par ligne, les commentaires sont ignorés
192.168.1.100
example.com
example.com:8443
https://example.com
http://example.com:8080
La correction appropriée est de mettre à niveau Apache vers 2.4.67 ou ultérieur. Si vous ne pouvez pas mettre à niveau immédiatement, désactiver HTTP/2 supprime complètement la surface d'attaque :
# Avant
Protocols h2 http/1.1
# Après (désactive HTTP/2)
Protocols http/1.1
Cet outil est destiné uniquement aux tests de sécurité et à la recherche autorisés. Assurez-vous d'avoir une autorisation écrite explicite avant de l'exécuter contre une cible quelconque. L'auteur décline toute responsabilité en cas d'utilisation abusive.
| Option | Défaut | Description |
|---|
-t | — | Cible unique (nom d'hôte ou IP) |
-l | — | Fichier contenant les cibles, une par ligne |
-p | 443 | Port |
-n | 10 | Nombre de tours d'exploitation |
-b | 200 | Paires HEADERS+RST par tour |
-w | 3 | Connexions parallèles par tour |
-d | 0.1 | Délai entre les tours en secondes |
-m | inline | Mode d'attaque : inline ou staged |
--no-tls | — | Utiliser h2c au lieu de TLS |
--check-only | — | Reconnaissance passive uniquement, pas d'exploitation |
-o | — | Sauvegarder les résultats dans un fichier JSON |
--report | — | Générer un rapport Markdown |
-v | — | Sortie verbose |
| Niveau | Signification |
|---|
| CRITICAL | 2.4.66 confirmé, HTTP/2 actif, Event MPM détecté, crash déterministe — corriger immédiatement |
| HIGH | 2.4.66 confirmé, HTTP/2 actif, MPM threadé utilisé |
| MEDIUM | 2.4.66 détecté mais HTTP/2 ou crash non encore confirmé |
| LOW | Version ne correspond pas ou aucun HTTP/2 détecté |
| NONE | Déjà patché vers 2.4.67+ ou non affecté |