Приватная лаборатория Nginx Rift ASLR, цепочка эксплойтов и демонстрационные записи
RCE-эксплойт (Proof of concept) для CVE-2026-42945 — критического переполнения кучи в ngx_http_rewrite_module NGINX, появившегося ещё в 2008 году. Уязвимость позволяет неаутентифицированному удалённому злоумышленнику выполнить произвольный код на серверах, использующих директивы rewrite и set.
Этот форк расширяет исходный PoC цепочкой обхода ASLR, которая сочетает переполнение в NGINX с распространённым примитивом LFI/произвольного чтения файлов на том же хосте. Примитив чтения файлов используется для восстановления карт памяти воркеров nginx, libc и живого /proc/<worker>/mem, после чего удалённо вычисляются адрес system() и пригодные цели в куче.
Ранние версии этой лаборатории преднамеренно вызывали крах воркера nginx, чтобы сервис записал core dump, затем получали и разбирали этот core dump через примитив чтения файлов для восстановления чувствительного к ASLR состояния процесса, включая цели в куче. В этом репозитории coreless — это лишь сокращение для «без читаемого crash core dump»: текущий путь по умолчанию заменяет зависимость от crash core на чтение памяти через живой procfs, а сохранённый легаси-путь core-guided по-прежнему использует сгенерированный core dump воркера.
Эта уязвимость — вместе с тремя другими ошибками повреждения памяти (CVE-2026-42946, CVE-2026-40701, CVE-2026-42934) — была автономно обнаружена системой анализа безопасности depthfirst после одного клика по подключению исходного кода NGINX.
Хотите находить такие проблемы в своём коде? Попробуйте ту же систему на https://depthfirst.com/open-defense.
Скриптовый движок NGINX использует двухпроходный процесс: сначала вычисляется требуемый размер буфера, затем копируются данные. Флаг is_args устанавливается в основном движке, когда замена в rewrite содержит ?, но проход вычисления длины выполняется на свежеобнулённом под-движке. Таким образом:
is_args = 0 → возвращает исходную длину захвата.is_args = 1 → вызывает ngx_escape_uri с NGX_ESCAPE_ARGS, расширяя каждый байт, требующий экранирования, до 3 байт.Копирование переполняет недостаточно большой буфер в куче управляемыми данными из URI. Эксплуатация использует межзапросный heap feng shui для повреждения указателя cleanup соседнего ngx_pool_t (распыляемого через тела POST-запросов, поскольку байты URI не могут содержать нулевые байты), перенаправляя его на поддельный ngx_pool_cleanup_s, который вызывает system() при уничтожении пула.
Подробнее об этой уязвимости читайте в нашем техническом разборе.
| Продукт | Затронуто | Исправлено в |
|---|---|---|
| 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 |
Полное уведомление вендора: https://my.f5.com/manage/s/article/K000160932



Этот форк сохраняет исходный раскрывающий PoC нетронутым, но добавляет второе исследовательское направление, сосредоточенное на более реалистичном вопросе:
Можно ли эксплуатировать уязвимость на реальной виртуальной машине x86_64 Linux с включённым ASLR, не полагаясь на жёстко заданные смещения Docker/лаборатории?
Ответ в этом исследовательском форке — да, с важными ограничениями. Рабочие цепочки не отключают ASLR и не используют исходные жёстко заданные адреса кучи/libc. Вместо этого они получают состояние времени выполнения через доступные по HTTP примитивы на том же порту, а затем выбирают конечную цель в куче на основе удалённо полученных данных раскрытия.
Теперь есть два направления эксплойта с включённым ASLR, при этом путь coreless рассматривается как текущий лучший PoC:
nginx_rifter.py: чистый, самодостаточный инструмент оценки и интегрированная точка входа эксплойта. Его метод эксплойта по умолчанию теперь — цепочка coreless через /proc/<nginx-worker>/mem.nginx_rifter_core_v2_1.py: сохранённая легаси-версия nginx_rifter.py с управлением через core. Она полезна для воспроизведения более старого исследовательского пути на основе crash core, протестированного на ВМ, но больше не является предпочтительным PoC.tools/proc_mem_coreless_exploit.py: более ранний автономный исследовательский стенд coreless. Его логика объединена в nginx_rifter.py; инструмент остаётся для повторения сырых экспериментов.Целевая топология намеренно использует один порт:
/api/.../lfi.php?file=.../phpinfo.phpТекущий путь coreless proc-mem выполняет следующие шаги высокого уровня:
/proc/<pid>/maps и отображённого файла libc.system() для этого воркера./proc/<worker>/mem через примитив чтения файлов.Легаси-путь с управлением через core выполняет аналогичное вычисление базового адреса, затем намеренно вызывает крах воркера, читает сгенерированный core-файл через LFI и добывает из этого core распылённые слоты поддельной очистки. Это был полезный исследовательский мост, но он зависит от политики core dump и прав файловой системы, которые реже встречаются в конфигурациях по умолчанию.
Это не то же самое, что исходная детерминированная Docker-демонстрация. Путь x86_64 ВМ оставляет обычный Linux ASLR включённым и пересчитывает адреса, специфичные для процесса, при каждом запуске. Путь Docker coreless также оставляет ASLR включённым и устраняет необычное требование читаемого core, но зависит от поведения разрешений procfs, которое необходимо проверять для целевого класса.
Этот форк — контролируемая исследовательская лаборатория. Цепочки с включённым ASLR опираются на строгие условия, которые не являются универсальными предположениями для продакшена:
/proc/<pid>/maps воркера nginx с тем же UID, отображённый libc и /proc/<pid>/mem на больших отображённых смещениях./proc/<pid>/maps воркера nginx с тем же UID, отображённый libc и сгенерированный core воркера.