返回首页 >

18年积弊:NGINX脚本引擎堆缓冲区溢出可致远程代码执行

2026-05-15 11:00   奇安信威胁情报中心

  is_args标志传播失效

  漏洞根因位于src/http/ngx_http_script.c。当rewrite指令的替换字符串包含问号时,函数ngx_http_script_start_args_code会将主引擎的e->is_args标志设置为1:

  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指令引用正则捕获组时,触发ngx_http_script_complex_value_code函数执行长度计算。此时,该函数创建一个完全清零的子引擎

  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.ip = code->lengths->elts;

      // ...

  }

  由于子引擎被初始化为全零,le.is_args为0。长度计算函数ngx_http_script_copy_capture_len_code据此判断不需要进行URL转义,计算出的长度是原始捕获字节数。然而在实际复制阶段,主引擎的e->is_args仍为1,复制函数调用ngx_escape_uri进行URL转义,每个可转义字节扩展为3字节(%XX格式)。长度计算与实际写入数据量之间的不匹配,导致堆缓冲区溢出。

  攻击向量与利用链

  漏洞触发需要同时满足两个条件:rewrite指令的替换字符串包含问号,且后续存在引用捕获组的set指令。攻击者可通过构造恶意请求路径,利用截断的正则表达式捕获未转义的路径字符。

  depthfirst已公开完整的概念验证代码,验证了以下攻击路径:

  攻击者通过跨请求堆风水(heap feng shui)技术操控堆布局

  利用POST body喷洒(spraying)破坏相邻的ngx_pool_t结构

猜你喜欢

热点新闻

{$loop_num=0}