Laboratoire privé Nginx Rift ASLR, chaîne d'exploitation et enregistrements de démonstration
Preuve de concept d'exécution de code à distance (RCE) pour CVE-2026-42945, un débordement de tas critique dans le ngx_http_rewrite_module de NGINX introduit en 2008. Ce bug permet une exécution de code à distance sans authentification sur les serveurs utilisant les directives rewrite et set.
Ce fork étend le PoC original avec une chaîne de contournement d'ASLR qui combine le débordement NGINX avec une primitive LFI/lecture arbitraire de fichier courante sur le même hôte. La primitive de lecture de fichier est utilisée pour récupérer les maps des workers nginx, la libc et le /proc/<worker>/mem en direct, puis pour dériver l'adresse de system() et des cibles tas exploitables à distance.
Les versions précédentes de ce lab faisaient planter intentionnellement un worker nginx pour que le service écrive un core dump, puis récupéraient et analysaient ce core dump via la primitive de lecture de fichier afin de récupérer l'état du processus sensible à l'ASLR, y compris les cibles tas. Dans ce dépôt, coreless est seulement un raccourci pour « sans core dump de crash lisible » : le chemin par défaut actuel remplace cette dépendance au core de crash par des lectures mémoire procfs en direct, tandis que le chemin historique préservé core-guided utilise toujours le core dump du worker généré.
Cette vulnérabilité — ainsi que trois autres problèmes de corruption mémoire (CVE-2026-42946, CVE-2026-40701, CVE-2026-42934) — a été découverte de manière autonome par le système d'analyse de sécurité de depthfirst après un simple clic d'intégration du code source de NGINX.
Vous voulez trouver des problèmes comme celui-ci dans votre propre code ? Essayez le même système sur https://depthfirst.com/open-defense.
Le moteur de script de NGINX utilise un processus en deux passes : d'abord calculer la taille de tampon requise, puis copier les données. Le drapeau is_args est défini sur le moteur principal lorsqu'un remplacement rewrite contient ?, mais la passe de calcul de longueur s'exécute sur un sous-moteur fraîchement remis à zéro. Donc :
is_args = 0 → renvoie la longueur de capture brute.is_args = 1 → appelle ngx_escape_uri avec NGX_ESCAPE_ARGS, en développant chaque octet échappable en 3 octets.La copie fait déborder le tampon tas sous-dimensionné avec des données URI contrôlées par l'attaquant. L'exploitation utilise du heap feng shui inter-requêtes pour corrompre le pointeur cleanup d'un ngx_pool_t adjacent (sprayé via des corps de requêtes POST, car les octets d'URI ne peuvent pas contenir d'octets nuls), le redirigeant vers un faux ngx_pool_cleanup_s qui invoque system() lors de la destruction du pool.
En savoir plus sur ce bug dans notre analyse technique.
| Produit | Versions concernées | Corrigé dans |
|---|---|---|
| NGINX Open Source | 0.6.27 – 1.30.0 | 1.31.0, 1.30.1 |
| NGINX Plus | R32 – R36 | R36 P4, R35 P2, R32 P6 |
Avis de sécurité complet du fournisseur : https://my.f5.com/manage/s/article/K000160932



Ce fork conserve le PoC de divulgation original intact, mais ajoute une seconde piste de recherche axée sur une question plus réaliste :
Le bug peut-il être exploité contre une véritable VM Linux x86_64 avec ASLR activé, sans dépendre d'offsets Docker/lab codés en dur ?
La réponse dans ce fork de recherche est oui, avec d'importantes contraintes. Les chaînes fonctionnelles ne désactivent pas l'ASLR et n'utilisent pas les adresses tas/libc codées en dur d'origine. Elles dérivent plutôt l'état d'exécution via des primitives accessibles par HTTP sur le même port, puis sélectionnent la cible tas finale à partir des données de divulgation obtenues à distance.
Il existe désormais deux pistes d'exploitation avec ASLR activé, le chemin coreless étant considéré comme le meilleur PoC actuel :
nginx_rifter.py : le point d'entrée propre et autonome pour l'évaluation et l'exploitation intégrée. Sa méthode d'exploitation par défaut est désormais la chaîne coreless /proc/<nginx-worker>/mem.nginx_rifter_core_v2_1.py : la version historique préservée de nginx_rifter.py, guidée par core. Elle est utile pour reproduire l'ancienne piste de recherche testée sur VM avec core de crash, mais elle n'est plus le PoC préféré.tools/proc_mem_coreless_exploit.py : l'ancien harnais de recherche coreless autonome. Sa logique a été fusionnée dans nginx_rifter.py ; l'outil reste disponible pour rejouer des expériences brutes.La topologie cible est volontairement sur le même port :
/api/.../lfi.php?file=.../phpinfo.phpLe chemin proc-mem coreless actuel effectue les étapes de haut niveau suivantes :
/proc/<pid>/maps du worker nginx et le fichier libc mappé.system() pour ce worker./proc/<worker>/mem via la primitive de lecture de fichier.Le chemin historique guidé par core effectue une dérivation d'adresse de base similaire, puis fait intentionnellement planter un worker, lit le fichier core généré via LFI et fouille ce core pour y trouver les emplacements de faux-cleanup sprayés. C'était un pont de recherche utile, mais il dépend de la politique de core dump et des permissions du système de fichiers, qui sont moins courantes dans les déploiements par défaut.
Ce n'est pas la même chose que la démo Docker déterministe d'origine. Le chemin VM x86_64 laisse l'ASLR Linux normal activé et recalcule les adresses spécifiques au processus à chaque exécution. Le chemin coreless Docker laisse également l'ASLR activé et supprime l'exigence inhabituelle de core lisible, mais il dépend du comportement des permissions procfs qui doit être vérifié pour la classe de cible.
Ce fork est un laboratoire de recherche contrôlé. Les chaînes avec ASLR activé reposent sur des conditions fortes qui ne sont pas des hypothèses de production universelles :