Уязвимост в Nginx, останала скрита 18 години — CVE-2026-42945: пълен анализ на принципа, PoC и поправката

🚨 Високорискова уязвимост в Nginx, останала скрита 18 години: CVE-2026-42945 — принцип на действие, PoC и начини за отстраняване
На 13 май 2026 г. изследователската организация по сигурносттаdepthfirstсъвместно с F5 разкри тежка уязвимост от историята на NGINX —CVE-2026-42945:
- Оценка по CVSS v4.0 — 9.2: уязвимостта е с висок риск
- Препълване на буфера в heap-а: може да доведе до отдалечено изпълнение на код (RCE)
- Останала скрита 18 години: кодът е влязъл в хранилището още през 2008 г.
- Засегнати са 9,75 млн. сайта по света: над 2,54 млн. уебсайта в Китай също са засегнати
- PoC вече е публичен: QiAnXin успя да възпроизведе експлоатацията
Това еисторическа уязвимост в основния модул на NGINX, при която на нападателя е достатъчно да изпрати една специално изготвена HTTP заявка, за да превземе сървъра отдалечено.
🔍 Преглед на уязвимостта
Основна информация
| Характеристика на уязвимостта | Подробности |
|---|---|
| Идентификатор на уязвимостта | CVE-2026-42945 |
| Оценка по CVSS | v4.0: 9.2 | v3.1: 8.1 |
| Тип на уязвимостта | Препълване на буфера в heap-а (Heap-based Buffer Overflow) |
| Тип заплаха | Отдалечено изпълнение на код (RCE), отказ на услуга (DoS) |
| Условия за експлоатация | Без оторизация, необходимо е само да се конструира HTTP заявка |
| Засегнат компонент | ngx_http_rewrite_module (вграден основен модул на NGINX) |
| Открита от | depthfirst (автоматизираната система я откри за 6 часа) |
Обхват на въздействието
- 9,75 млн. сайта по светаса засегнати
- 2,54 млн. уебсайта в Китайса засегнати
- NGINX обслужва около една трета от сайтовете в света, обхватът на въздействие е огромен
- Кодът е написан през2008 г.и остава скрит18 години
⚠️ Условия за задействане
И трите условия трябва да са изпълнени едновременно
За задействането на уязвимостта е необходимаконфигурация, която отговаря на определена комбинация от условия:
| Условие | Описание | Пример |
|---|---|---|
| 1. Неименувани PCRE групи за залавяне | Директивата rewrite използва неименувани групи за залавяне | $1, $2, $3… |
| 2. Заместващият низ съдържа въпросителна | Заместващият низ съдържа символа ? | /profile.php?id=$1&tab=$2 |
| 3. Следва rewrite/if/set | Директивата rewrite е непосредствено последвана от друга директива | rewrite … last; if (…) { … } |
Пример за уязвима конфигурация
# 易受攻击配置
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
# 后跟其他指令
if ($arg_debug) {
set $debug_flag 1;
}
Тази конфигурация едновременно отговаря на трите условия:неименувани групи за залавяне $1/$2、заместващият низ съдържа ?、следва директива if.
🔬 Принцип на уязвимостта
Несъответствие в състоянието между двата етапа на обработка
Скриптовият двигател на NGINXизползва двуетапна обработка:
- Етап първи: изчисляване на необходимия размер на буфера
- Етап втори: копиране на данните в буфера
Сърцевината на уязвимостта се крие вгрешното управление на флага is_args:
| Етап | Състояние на is_args | Логика на обработката | Резултат |
|---|---|---|---|
| Етап на изчисляване на дължината | is_args = 0 | Връща първоначалната дължина на залавянето | Размерът на буфера е подценен |
| Етап на копиране на данните | is_args = 1 | Извиква се ngx_escape_uri, всеки байт се разширява до 3 байта | Препълване на буфера в heap-а |
Конкретна последователност
- Директивата rewriteсъдържа неименувани групи за залавяне $1/$2
- Заместващият низсъдържа ?, което задейства is_args = 1
- Етап на изчисляване на дължината: използва се новоинициализиран подчинен двигател, is_args = 0
- Връщане на първоначалната дължина: заделя се твърде малък буфер в heap-а
- Етап на копиране на данните: използва се главният двигател, is_args = 1
- Извикване на ngx_escape_uri: байтовете се разширяват и буферът прелива
- Контролираните от нападателя данни от URIсе записват в областта на препълването
Начин на експлоатация
Подреждане на heap-а между отделни заявки (Heap Feng Shui):
- Тяло на POST заявкатасе използва за запълване на паметта в heap-а (тъй като URI не може да съдържа null байтове)
- Прелелите данниразвалят указателя cleanup на съседната структура ngx_pool_t
- Фалшифициране на структурата ngx_pool_cleanup_s, насочена към system()
- При унищожаване на pool-асе задейства извикване на system()
- Осъществява се RCE
Влияние на ASLR
- ASLR включено: води само до срив на Worker процеса (DoS)
- ASLR изключено: възможно е отдалечено изпълнение на код (RCE)
📊 Засегнати версии
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 |
Други засегнати компоненти
- NGINX Instance Manager: 2.16.0 – 2.21.1
- NGINX App Protect WAF: 4.9.0 – 5.8.0
- NGINX Ingress Controller: 3.5.0 – 5.4.1
- NGINX Gateway Fabric: 1.3.0 – 2.5.1
- F5 DoS for NGINX: 4.8.0
🔥 Състояние на PoC
PoC вече е публичен
- Хранилище в GitHub:https://github.com/DepthFirstDisclosures/Nginx-Rift
- QiAnXin вече я възпроизведе: изследовател по сигурността от центъра за анализ на заплахите успя да възпроизведе експлоатацията
- Техническите подробности са публични: depthfirst публикува технически анализ
- Експлоатация в реални условия: засега не е установена
Начин на използване на PoC
# 构建容器 ./setup.sh # 启动易受攻击的 NGINX 服务器 docker compose -f env/docker-compose.yml up # 执行 PoC 获取 Shell python3 poc.py --shell
✅ Начини за отстраняване
Метод 1: обновяване на версията
# 升级到修复版本 NGINX Open Source >= 1.31.0 NGINX Open Source >= 1.30.1 NGINX Plus >= R32 P6 NGINX Plus >= R36 P4 # 升级后重启 NGINX nginx -s reload
Метод 2: промяна на конфигурацията (смекчаваща мярка)
Заменетенеименуваните групи за залавянесименувани групи за залавяне:
# 易受攻击配置(未命名捕获) rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last; # 修复后配置(命名捕获) rewrite ^/users/(?[0-9]+)/profile/(?.*)$ /profile.php?id=$user_id&tab=$section last;
Именуваните групи за залавянене задействат уязвимостта.
Метод 3: проверка на конфигурацията
Проверете дали съществува уязвима конфигурация:
# 搜索易受攻击的 rewrite 指令 grep -E "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/nginx.conf grep -rE "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/conf.d/
🔍 Как беше открита
Открита от автоматизирана система
depthfirstи нейната система за анализ на сигурността:
- за 6 часабяха открити 5 проблема
- 4 от тях потвърдени от NGINX
- CVE-2026-42945е най-тежката уязвимост
- и води началото си от 2008 г., присъства в почти всички стандартни сборки
Други свързани уязвимости
- CVE-2026-42946: проблеми с разрушаване на паметта
- CVE-2026-40701: проблеми с разрушаване на паметта
- CVE-2026-42934: проблеми с разрушаване на паметта
📝 Обобщение
CVE-2026-42945е най-тежката уязвимост в историята на NGINX:
- Останала скрита 18 години: кодът е влязъл в хранилището още през 2008 г.
- CVSS 9.2: препълване на буфера в heap-а, което може да доведе до RCE
- Условия за задействане: директива rewrite с неименувани групи за залавяне + заместващ низ, съдържащ ? + следваща директива
- Обхват на въздействието: 9,75 млн. сайта по света, 2,54 млн. уебсайта в Китай
- PoC вече е публичен: хранилище в GitHub + QiAnXin вече възпроизведе експлоатацията
- Решение: обновяване на версията или използване на именувани групи за залавяне
Уязвимост, останала скрита 18 години — препоръчва се възможно най-бързо обновяване или промяна на конфигурацията.
Официално съобщение:https://my.f5.com/manage/s/article/K000161019
Хранилище с PoC:https://github.com/DepthFirstDisclosures/Nginx-Rift
Технически анализ:https://depthfirst.com/research/nginx-rift