
NGINX Rift 漏洞分析与复现
CVE-2026-42945 (Codename „NGINX Rift“) ist eine Heap-basierte Pufferüberlauf-Schwachstelle im NGINX ngx_http_rewrite_module mit einem CVSS v4 Score von 9.2 (Critical).
Die Schwachstelle wurde im April 2026 vom Sicherheitsforschungsteam depthfirst entdeckt und lag seit ihrer Einführung in NGINX 0.6.27 im Jahr 2008 18 Jahre lang verborgen.
Die Schwachstelle erfordert die folgende NGINX-Konfiguration, um ausgelöst zu werden:
location ~ ^/api/(.*)$ {
rewrite ^/api/(.*)$ /internal?migrated=true;
set $original_endpoint $1;
}
Wichtige Bedingungen:
rewrite-Direktive enthält ein ? (Fragezeichen)set-Direktive verweist auf eine Regex-Erfassungsgruppe (z. B. $1)+, &, % usw.)Die Skript-Engine von NGINX verwendet eine Zweiphasenverarbeitung zur Ausführung von rewrite/set-Direktiven:
Der Kern der Schwachstelle liegt in der Zustandsinkonsistenz der Engine zwischen den beiden Phasen:
rewrite setzt das is_args-FlagWenn der Ersetzungsstring der rewrite-Direktive ein ? enthält, setzt die Funktion ngx_http_script_start_args_code:
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-Direktive verwendet eine völlig neue Unter-EngineWenn eine nachfolgende set-Direktive auf eine Erfassungsgruppe verweist, erstellt ngx_http_script_complex_value_code eine vollständig nullgesetzte Unter-Engine:
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;
Längenberechnung (mit Unter-Engine 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]; // 返回原始长度(未转义)
}
Tatsächliches Kopieren (mit Haupt-Engine 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 (ursprüngliche Erfassungslänge)raw_size + 2 * N (N = Anzahl der escape-fähigen Zeichen)Zum Beispiel: Wenn die URI 100 +-Zeichen enthält, beträgt der Überlauf 200 Bytes.
Die einfachste Ausnutzungsmethode – das Senden einer Anfrage mit vielen escape-fähigen Zeichen führt zum Absturz des Worker-Prozesses:
GET /api/+++++++++++++++++++++++++++++++++++ HTTP/1.1
Host: target.com
Vollständige RCE-Ausnutzungskette (erfordert deaktiviertes oder umgangenes ASLR):
ngx_pool_t über die Verbindungsreihenfolgecleanup-Zeiger: Überlauf in die benachbarte Speicherpool-Strukturcleanup-Strukturen: Injizieren gefälschter Strukturen mit der Adresse von system() über den POST-Request-Bodyngx_destroy_pool die cleanup-Liste durchläuftDie Multi-Prozess-Architektur von NGINX macht die Ausnutzung zuverlässiger – nach einem Worker-Absturz fork'd der Master einen neuen Worker mit identischem Speicherlayout.
README.md - Diese Datei, Schwachstellenanalyse-DokumentDockerfile - Erstellt eine verwundbare NGINX-Umgebungnginx.conf - NGINX-Konfiguration zum Auslösen der Schwachstellepoc_crash.py - DoS PoC (löst Worker-Absturz aus)docker-compose.yml - Testumgebung mit einem Befehl starten# 1. 构建并启动易受攻击的 NGINX
docker-compose up -d
# 2. 运行 DoS PoC
python3 poc_crash.py
# 3. 查看 NGINX 错误日志确认崩溃
docker-compose logs nginx
Dieses Material dient ausschließlich Sicherheitsforschungs- und Bildungszwecken. Verwenden Sie diese Informationen nicht für unbefugte Angriffe.