Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/w5m1n9/nginx-ngx_http_rewrite_module-heap-buffer-overflow-cve-2026-9256
Анализ уязвимостейЭксплуатацияВеб-безопасностьФаззингТестирование на Проникновение
GitHubw5m1n9/nginx-ngx_http_rewrite_module-heap-buffer-overflow-cve-2026-9256

NGINX-ngx_http_rewrite_module-heap-buffer-overflow-CVE-2026-9256

Эксплойт-доказательство концепции для CVE-2026-9256, переполнение кучи в модуле NGINX ngx_http_rewrite_module. Подтверждает удаленное падение рабочего процесса через специально сформированный URI со спецсимволами, с многостадийным зондом keep-alive для надежного обнаружения.

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
22 месяцев назадЕщё не проверено

CVE-2026-9256 NGINX ngx_http_rewrite_module PoC: выводы и размышления

Область применения: только для локальных полигонов, авторизованных сред воспроизведения, проверки уязвимостей и анализа защитных правил. Не используйте на неавторизованных целях. Идеи PoC в этом документе проверяют только удаленно наблюдаемое поведение аварийного завершения worker NGINX, не включают RCE, обход ASLR или стабильную цепочку эксплуатации.

1. Контекст уязвимости

CVE-2026-9256 — это уязвимость переполнения кучи в модуле ngx_http_rewrite_module NGINX. Триггер уязвимости — не просто обращение по определенному фиксированному URI, а зависимость от конкретного шаблона конфигурации rewrite: в rewrite-регулярном выражении существуют перекрывающиеся группы захвата PCRE, а в части replacement (замены) используются несколько переменных захвата, например $1, $2.

Когда злоумышленник создает специальный URI, который приводит к выполнению логики rewrite по соответствующему пути, NGINX при обработке захваченного контента, склейке результатов rewrite или экранировании URI/параметров может столкнуться с несоответствием рассчитанной длины и реальной записи, что в итоге приводит к повреждению памяти кучи worker-процесса.

Поэтому ключ к этой уязвимости — не сам путь /api, а наличие в конфигурации целевого NGINX уязвимого правила rewrite, которое может быть активировано запросом. Путь /api, используемый в PoC по умолчанию, — это всего лишь пример пути в текущей среде воспроизведения; при реальном тестировании путь запроса необходимо корректировать в соответствии с правилами rewrite, содержащими перекрывающиеся группы захвата и ссылающимися на несколько переменных захвата.

Текущая цель PoC — проверка поведения аварийного завершения worker / отказа в обслуживании. Он не пытается создать точную раскладку кучи, не пытается перезаписать адрес возврата или указатели функций, не доказывает удаленное выполнение кода. Стабильные свидетельства, наблюдаемые на удаленной стороне, в основном: аномальное разрывы соединения при отправке триггерного запроса, затем восстановление работы службы NGINX, прерывание keep-alive соединений сбойным worker после триггера.

2. Почему нельзя полагаться только на код состояния HTTP?

После срабатывания этой уязвимости не обязательно проявляется фиксированный код 500, 502 или 400. Это связано с тем, что модель master-worker NGINX: после аварийного завершения worker-процесса мастер запускает новый worker. Удаленно атакующий обычно наблюдает не полную недоступность всего сервиса, а внезапный разрыв соединения, тайм-аут чтения, сброс соединения, после чего повторный запрос к / снова дает нормальный ответ.

Поэтому PoC не может судить о наличии уязвимости только по коду состояния HTTP одного запроса. Если отправить один длинный URI, увидеть разрыв соединения и сразу сделать вывод «уязвимость есть», вероятность ложного срабатывания высока. Разрыв соединения может быть также вызван сетевыми колебаниями, тайм-аутом прокси, перехватом промежуточным устройством, ограничением на бэкенде или активным закрытием соединения сервером.

Следовательно, PoC должен быть спроектирован как многоэтапная проверка:

  1. Сначала убедиться, что цель жива.
  2. Затем проверить, что примерный путь rewrite может сработать.
  3. Отправить запрос-триггер переполнения и наблюдать, не оборвалось ли соединение аномально или не истек ли тайм-аут.
  4. Сразу отправить обычный запрос, чтобы убедиться, что NGINX снова отвечает.
  5. С помощью keep-alive многократно проверять, не разрывается ли стабильно соединение worker после триггера.

Только когда одновременно наблюдаются «аномальный разрыв соединения при триггере + последующее восстановление службы + многократные разрывы keep-alive», можно с большей уверенностью судить о наличии поведения CVE-2026-9256 (аварийное завершение worker).

3. Идея построения PoC

Текущий основной путь триггера PoC:

root@kitploit:~
GET /api/++++++++++++++++++++++++++++++++... HTTP/1.1
Host: 127.0.0.1:19321

Здесь /api/ — примерный маршрут в текущем полигоне для попадания в правило rewrite, после него добавляется большое количество символов +. По умолчанию их 4096.

Выбор + обусловлен тремя основными причинами.

Во-первых, + — допустимый символ URI. При отправке обычным HTTP-клиентом он обычно не обрезается и не принудительно перекодируется, как пробел, # и т.д. Поэтому текущий PoC не требует использования raw-сокетов для создания недопустимой строки запроса, как в некоторых обходах request-target.

Во-вторых, большое количество повторяющихся символов позволяет группам захвата rewrite получить достаточно длинный ввод, расширяя масштаб вывода при последующей склейке replacement или экранировании, что упрощает проявление несоответствия между рассчитанной длиной и реальной записью.

В-третьих, структура полезной нагрузки из повторяющихся + проста, что облегчает наблюдение в трафике, журналах и правилах IDS, а также удобно для регулировки длины и тестирования порогов.

Однако следует отметить: + — не единственный теоретически возможный символ-триггер. Реальное условие срабатывания по-прежнему состоит в «попадании в уязвимую конфигурацию rewrite + ввод обрабатывается соответствующими группами захвата + обработка вывода rewrite вызывает переполнение кучи». В разных средах могут потребоваться корректировки маршрута, типа символа и порога длины.

3.1 Пояснение по другим возможным символам-триггерам

Текущий PoC по умолчанию выбирает символ + в большом количестве. Это не значит, что только + может вызвать проблему. + — наиболее подходящий символ для написания универсального PoC, так как он относительно стабилен в URI, легко отправляется обычными HTTP-клиентами, а его характеристики в захвате трафика четкие.

С точки зрения принципа уязвимости: если символ в процессе обработки rewrite NGINX попадает в логику экранирования NGX_ESCAPE_ARGS и при этом расширяется с исходного 1 байта до 3 байт в виде %XX, это может вызвать несоответствие «рассчитанная длина < реальная запись». То есть триггерная точка в основе своей — не сам +, а «плотное появление символов, подлежащих экранированию в режиме args».

Помимо +, теоретически стоит учитывать следующие символы:

root@kitploit:~
пробел: 0x20
#: 0x23
%: 0x25
&: 0x26
?: 0x3F
управляющие символы: 0x00-0x1F
старшие байты: 0x7F-0xFF

Если эти символы попадут в соответствующий захват и будут обрабатываться как содержимое args при экранировании в replacement rewrite, они вызовут аналогичный эффект расширения. Например:

root@kitploit:~
+      -> %2B
&      -> %26
%      -> %25
#      -> %23
?      -> %3F
пробел -> %20

Каждый такой символ теоретически расширяется с 1 до 3 байт, увеличивая длину реальной записи на 2 байта. Если во вводе содержится много таких символов, реальная длина записи может значительно превысить ошибочно рассчитанную длину буфера, что упрощает вызов heap buffer overflow.

Однако пригодность разных символов в PoC неодинакова.

+ — самый стабильный. Он обычно может быть напрямую включен в HTTP request-target, редко обрезается браузером или инструментами командной строки, и не меняет структуру path/query URI. Поэтому текущий PoC использует 4096 символов + в качестве полезной нагрузки по умолчанию.

& также может быть кандидатом, так как в режиме args он экранируется в %26. Но в shell & означает выполнение в фоне, а в URL часто используется как разделитель параметров запроса, поэтому при тестировании нужно обращать внимание на кавычки и положение, иначе запрос может быть отправлен не так, как планировалось.

% также может быть кандидатом, так как он экранируется в %25. Однако % сам по себе является префиксом URL-кодирования, и некоторые клиенты, прокси или фреймворки могут попытаться интерпретировать последовательности %XX. При неправильном составлении цель может получить не исходный символ %, а предварительно обработанный клиентом контент.

? теоретически относится к символам, подлежащим экранированию, но в HTTP request-target он разделяет path и query. Если поместить его прямо в путь, последующее содержимое может быть интерпретировано как query string, что изменит диапазон захвата rewrite. Поэтому он больше подходит для дополнительных тестов, а не как основной символ PoC по умолчанию.

# теоретически может вызвать экранирование, но браузер не отправляет фрагмент после # серверу, многие продвинутые HTTP-клиенты также кодируют или обрезают его. Поэтому для тестирования буквального # обычно требуются raw-сокеты, Burp Repeater или инструменты, сохраняющие исходный request-target, нельзя полагаться на адресную строку браузера.

Пробел 0x20 также относится к экранируемым символам, но в строке запроса HTTP/1.1 пробел сам является разделителем. Если поместить его напрямую в request-target, будет нарушена структура строки запроса. При тестировании, если записать как %20, то в какой форме его увидит сервер на этапе обработки (кодированной или декодированной) зависит от конкретного процесса разбора и позиции rewrite. Поэтому пробел больше подходит для пояснения принципов и вспомогательного тестирования, а не как полезная нагрузка по умолчанию.

Управляющие символы 0x00-0x1F и старшие байты 0x7F-0xFF также входят в диапазон экранирования, но в реальных HTTP-каналах они чаще перехватываются, нормализуются или отклоняются клиентами, прокси, WAF или HTTP-парсером NGINX. Они могут служить примерами объектов экранирования на уровне исходного кода, но не рекомендуются в качестве символов-триггеров по умолчанию для обычного PoC.

Поэтому причина использования + в текущем PoC не в том, что уязвимость может быть вызвана только +, а в том, что + одновременно удовлетворяет трем условиям: может вызвать расширение при экранировании args, легко стабильно отправляется и не изменяет существенно структуру URI. При разработке защитных правил или анализе трафика нельзя ограничиваться только обнаружением последовательностей +. Необходимо также учитывать комбинации с высокой плотностью других экранируемых символов, особенно +, &, %, ?, # и т.п., появляющихся в длинных URI.

С точки зрения обнаружения, более разумное обобщение не:

root@kitploit:~
после /api/ много символов +

а:

root@kitploit:~
в длинных URI много специальных символов, которые в режиме NGX_ESCAPE_ARGS расширяются до %XX

Если правило обнаруживает только ++++, оно может покрыть только текущее написание PoC. Если злоумышленник заменит полезную нагрузку на &&&&, %%%%, ???? или смешает +%&?#, единичный признак + может пропустить атаку. Более надежный подход к обнаружению — совместная оценка длины URI, плотности специальных символов, количества повторений, опасного пути rewrite и поверхности NGINX.

4. Логика нормализации цели

Функция normalize_target в PoC обрабатывает ввод из командной строки, поддерживая три формы:

root@kitploit:~
python3 CVE-2026-9256-poc.py 127.0.0.1:19321
python3 CVE-2026-9256-poc.py 127.0.0.1 19321
python3 CVE-2026-9256-poc.py http://127.0.0.1:19321

Если пользователь вводит только host:port без схемы, скрипт автоматически добавляет http://host:port. Затем с помощью urllib.parse.urlparse извлекаются hostname и port, и формируется base, например:

root@kitploit:~
host = 127.0.0.1
port = 19321
base = http://127.0.0.1:19321

Текущая реализация в основном ориентирована на HTTP-полигоны с открытым текстом. Хотя normalize_target принимает https://, последующая проверка keep-alive использует обычный TCP-сокет без TLS, поэтому в сценарии HTTPS проверка сбоя будет неточной. Для поддержки HTTPS необходимо добавить ssl.wrap_socket или ssl.create_default_context().wrap_socket() в сокет.

5. Проверка активности и обнаружение rewrite

Сначала PoC вызывает check_alive(base) для обращения к корневому пути /:

root@kitploit:~
GET /

Если цель возвращает любой код состояния HTTP, это означает, что сервис в основном активен, и можно продолжать. При неудачном соединении скрипт завершается, чтобы не ошибочно интерпретировать недоступную цель как неудачный триггер уязвимости.

Затем вызывается check_rewrite(base) для обращения:

root@kitploit:~
GET /api/test

Этот запрос нужен, чтобы проверить, может ли /api/* попасть в логику rewrite в текущем полигоне. Если возвращаются коды перенаправления 301, 302, 303, 307, 308, это указывает на явное поведение редиректа rewrite, и PoC выводит заголовок Location как вспомогательное свидетельство.

Однако этот шаг не является обязательным условием успеха. В некоторых конфигурациях воспроизведения сам путь /api/* может войти в проблемный путь rewrite, и даже обычный пробный запрос может вызвать тайм-аут или аномальную обработку. Поэтому скрипт продолжает фазу триггера, даже если не получил нормального ответа rewrite.

6. Разработка триггерного запроса переполнения

Функция триггера: send_trigger(base, plus_count=4096). Основная логика склейки:

root@kitploit:~
payload = "/api/" + ("+" * plus_count)

По умолчанию конечный путь запроса выглядит так:

root@kitploit:~
/api/++++++++++++++++++++++++++++++++... всего 4096 символов +

Затем запрос отправляется через requests.get(base + payload, timeout=10, allow_redirects=False).

Здесь отключено автоматическое перенаправление по двум причинам.

Во-первых, сам rewrite может возвращать редирект. Если HTTP-клиент автоматически следует перенаправлениям, исходный триггерный запрос и последующий редирект смешаются, что затруднит анализ того, что произошло с первым запросом.

Во-вторых, PoC интересует состояние соединения на этапе триггера, а не бизнес-страница после перенаправления. Сохранение исходного ответа упрощает анализ.

Результат триггера делится на несколько категорий:

Если перехвачено ConnectionError, это означает аномальное закрытие соединения во время триггерного запроса — возможно, проявление аварийного завершения worker.

Если перехвачено ReadTimeout, это означает, что запрос был отправлен, но в течение длительного времени не получен нормальный ответ; возможно, worker завис, не вернулся нормально до аварийного завершения или тайм-аут вызван сетевыми условиями.

Если получен нормальный ответ HTTP, выводится код состояния и длина тела ответа, но на основе только нормального ответа нельзя отрицать уязвимость, поскольку в некоторых средах условие триггера может быть не полностью выполнено или длина полезной нагрузки недостаточна.

7. Зачем нужна проверка восстановления (follow-up)?

После триггерного запроса PoC ждет 1 секунду, затем вызывает follow_up(base) для повторного обращения к корневому пути /.

Цель этого шага — не доказательство самого переполнения, а оценка того, проявляется ли у NGINX признак «перезапуск worker после аварийного завершения мастером».

Если соединение триггерного запроса аномально оборвалось, но последующий запрос к / снова возвращает 200 или другой нормальный код состояния HTTP, это означает, что сервис не полностью вышел из строя, а скорее всего упал только один worker-процесс и был восстановлен.

Если после триггера сервис долгое время недоступен, это может быть остановка всего сервиса, падение контейнера или сетевая аномалия; такой результат не может быть напрямую приравнен к успешному срабатыванию CVE-2026-9256.

Таким образом, текущий критерий PoC: удаленно наблюдаемое аварийное завершение worker, а не просто «сервис недоступен».

8. Разработка keep-alive зонда (crash probe)

Наиболее важная проверка стабильности в PoC — keepalive_probe(host, port, rounds=5, plus_count=4096).

Она не использует requests, а напрямую устанавливает TCP-соединение через socket.create_connection и в рамках одного keep-alive соединения последовательно отправляет три запроса.

Первый запрос — обычный:

root@kitploit:~
GET / HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive

Этот запрос нужен, чтобы убедиться, что текущее соединение работоспособно, и по возможности заставить триггерный запрос упасть на то же соединение.

Второй запрос — триггерный:

root@kitploit:~
GET /api/++++++++++++++++++++++++++++++++... HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive

Если этот запрос вызывает аварийное завершение worker, то поддерживаемое им keep-alive соединение, скорее всего, будет разорвано напрямую.

Третий запрос — снова обычный:

root@kitploit:~
GET / HTTP/1.1
Host: 127.0.0.1
Connection: close

Если на третий запрос все еще получен ответ, значит, соединение не прервалось из-за триггерного запроса, и в этом раунде аварийное завершение worker не засчитывается.

Если третий запрос не удалось отправить, данные не получены или соединение уже закрыто, записывается:

root@kitploit:~
keepalive connection dropped

По умолчанию PoC повторяет 5 раундов. Смысл многократных повторений — снизить ложные срабатывания из-за случайных сетевых ошибок. Если в 5 раундах несколько раз происходит разрыв keep-alive, и при этом сервис все еще восстанавливается, то удаленные свидетельства становятся более убедительными.

9. Логика определения успеха

PoC делит конечный результат на три категории.

Первая категория: подтверждение уязвимости.

Условие:

root@kitploit:~
crash_count > 0 и recovered == True

То есть как минимум в одном раунде keep-alive зонда зафиксирован разрыв соединения, и последующий обычный запрос (follow-up) доказывает восстановление сервиса. Скрипт выводит:

root@kitploit:~
VULNERABILITY CONFIRMED - CVE-2026-9256 style crash behavior
Impact confirmed: worker crash / denial of service
RCE is not proven by this script

Это означает, что текущая среда демонстрирует поведение аварийного завершения worker, характерное для CVE-2026-9256, но удаленное выполнение кода не доказано.

Вторая категория: подозрение на уязвимость.

Условие:

root@kitploit:~
kind == "connection_error" and recovered == True

То есть основной триггерный запрос вызвал разрыв соединения, и сервис восстановился, но keep-alive зонд не подтвердил стабильно аварийное завершение worker. Скрипт выводит VULNERABILITY SUSPECTED.

Такая ситуация указывает на аномалию, но свидетельства недостаточно стабильны; требуется дополнительная проверка с помощью server-side error.log, core dump, контейнерных логов или отладчика.

Третья категория: не подтверждено.

Если нет ни надежного разрыва keep-alive, ни комбинации аномалии соединения при триггере + восстановление, скрипт выводит:

root@kitploit:~
VULNERABILITY NOT CONFIRMED

Это не обязательно означает, что цель абсолютно не уязвима. Возможные причины: путь не попал в rewrite, длина полезной нагрузки недостаточна, не подходящий выбор символов, целевая версия исправлена, промежуточный прокси изменил URI, или текущий скрипт не адаптирован для HTTPS.

10. Полный процесс выполнения текущего PoC

Процесс выполнения скрипта можно обобщить следующим образом:

  1. Разбор целевого адреса, получение host, port, base.
  2. Вывод базовой информации PoC с четким указанием, что проверяется только аварийное завершение worker, а не RCE.
  3. Запрос к /, подтверждение активности службы.
  4. Запрос к /api/test, попытка определить, активен ли примерный путь rewrite.
  5. Отправка длинного URI /api/ + 4096 символов + в качестве триггерного запроса.
  6. Фиксация первого результата триггера в зависимости от разрыва соединения, тайм-аута или кода HTTP.
  7. Ожидание 1 секунды, затем повторный запрос к /, проверка, восстановился ли worker.
  8. Установка keep-alive соединения через сокет, последовательная отправка: обычный запрос, триггерный запрос, обычный запрос.
  9. Повторение keep-alive зонда 5 раундов, подсчет количества разрывов соединения.
  10. Вывод confirmed, suspected или not confirmed на основе crash_count, состояния триггерного соединения и восстановления.

11. Пример использования

Пример локального полигона:

root@kitploit:~
python3 CVE-2026-9256-poc.py http://127.0.0.1:19321

или:

root@kitploit:~
python3 CVE-2026-9256-poc.py 127.0.0.1 19321

При успешном срабатывании типичный вывод будет выглядеть так:

root@kitploit:~
[+] Connection dropped during trigger request
[+] Worker is responding after trigger (HTTP 200)
round 1: worker likely crashed (keepalive connection dropped)
round 2: worker likely crashed (keepalive connection dropped)
...
[+] VULNERABILITY CONFIRMED - CVE-2026-9256 style crash behavior
[+] Impact confirmed: worker crash / denial of service
[*] RCE is not proven by this script

Такой вывод указывает на то, что удаленно наблюдаются достаточно стабильные свидетельства аварийного завершения worker.

12. Границы безопасности в дизайне PoC

Границы безопасности этого PoC достаточно четкие:

Во-первых, он выполняет только проверку аварийного завершения, а не эксплуатацию RCE.

Во-вторых, он не содержит heap spray, ROP, обход ASLR, shellcode или логику выполнения команд.

В-третьих, его критерий успеха — разрыв соединения worker и восстановление сервиса, а не получение shell или чтение файлов.

В-четвертых, он подходит для локального воспроизведения, проверки уязвимости, создания правил IDS/IPS и сравнения до и после исправления.

Для дальнейшего повышения безопасности можно добавить следующие ограничения:

  1. Разрешить доступ только к 127.0.0.1, localhost, частным адресам или явно авторизованному сегменту сети.
  2. Добавить параметр --plus-count, чтобы по умолчанию не отправлять слишком большую полезную нагрузку.
  3. Добавить параметр --route, позволяющий пользователю явно указывать путь триггера вместо жестко заданного /api/.
  4. Добавить параметр --rounds для управления количеством раундов keep-alive зонда.
  5. Добавить поддержку HTTPS, иначе текущая логика keep-alive сокетов подходит только для HTTP с открытым текстом.
  6. Добавить отладочный параметр --print-request для вывода фактически отправленного HTTP-запроса, что облегчит сравнение с результатами захвата трафика.

13. Идеи для создания защитных правил

Исходя из анализа PoC, правила обнаружения не должны сосредотачиваться только на /api/, так как /api — не фиксированный путь уязвимости, а всего лишь пример текущего полигона. Действительно ценные точки обнаружения:

  1. Направление запроса: от клиента к серверу.
  2. Длина URI явно аномальная.
  3. В URI присутствует большое количество последовательных или с высокой плотностью символов, которые могут вызвать расширение/экранирование вывода rewrite, например: много символов +, или смесь специальных символов +, &, %, ?, # и т.д.
  4. Целевой сервис имеет поверхность NGINX rewrite, что повышает риск.

Если правило жестко привязано к /api/++++, оно покроет только текущий PoC и текущий полигон. Для покрытия более универсального атакующего трафика следует выделять признаки вокруг «длинный URI + большое количество специальных символов с высокой плотностью + направление HTTP запроса + рискованный путь NGINX rewrite».

В то же время, поскольку в легитимных бизнес-сценариях также могут быть длинные URL или много кодированных символов, правила должны снижать ложные срабатывания за счет порога длины, плотности символов, количества повторений и контекста пути. Более надежное направление обнаружения:

root@kitploit:~
длинный URI
+
большое количество специальных символов, которые могут быть расширены экранированием NGX_ESCAPE_ARGS
+
направление запроса to_server
+
поверхность NGINX rewrite

а не просто:

root@kitploit:~
/api/++++

Для правил Suricata / Snort, если требуется покрыть только текущий публичный PoC, можно использовать последовательность + как один из сильных признаков. Для покрытия вариантов необходимо включить диапазон специальных символов в PCRE, например +, %, #, &, ? и другие символы, потенциально расширяемые экранированием. Однако такие правила более подвержены ложным срабатываниям, поэтому их следует использовать в сочетании с urilen, порогом повторения символов, ограничениями пути и диапазоном NGINX-активов.

14. Заключение

Вывод PoC для CVE-2026-9256 заключается не в поиске фиксированного пути уязвимости, а в понимании условий триггера: уязвимая конфигурация rewrite, перекрывающиеся группы захвата, ссылки на несколько переменных захвата и специальный URI-ввод, который вызывает аномальное расширение при обработке результатов rewrite.

Текущий скрипт выбирает /api/ + 4096 символов +, потому что этот путь попадает в правило rewrite в текущей среде воспроизведения, а большое количество + стабильно создает длинное входное давление. Скрипт не реализует RCE, а доказывает аварийное завершение worker через разрывы соединения, восстановление сервиса и многократные разрывы keep-alive.

При этом + — только самый стабильный и удобный для отправки символ по умолчанию, но не единственный возможный триггер. Любые символы, которые в режиме NGX_ESCAPE_ARGS расширяются до %XX, должны быть учтены при анализе принципов и разработке защитных правил. Более точное понимание: в длинных URI плотное появление символов, подлежащих расширяемому экранированию, при попадании в уязвимый захват rewrite и обработку replacement приводит к несоответствию между рассчитанной длиной и реальной записью, что в конечном итоге вызывает аварийное завершение worker или более серьезное повреждение памяти.

Скачать инструмент