Nginx_lua 100参数绕过原理详解
字数 619 2025-08-10 08:29:04

Nginx_lua 100参数绕过原理详解

一、环境搭建

Nginx_lua 安装步骤

  1. 下载并解压Nginx源码:
wget 'https://openresty.org/download/nginx-1.19.3.tar.gz'
tar -xzvf nginx-1.19.3.tar.gz
cd nginx-1.19.3/
  1. 设置LuaJIT环境变量(根据版本选择):
# LuaJIT 2.0
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.0

# 或 LuaJIT 2.1
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.1
  1. 配置编译选项:
./configure --prefix=/opt/nginx \
    --with-ld-opt="-Wl,-rpath,/path/to/luajit/lib" \
    --add-module=/path/to/ngx_devel_kit \
    --add-module=/path/to/lua-nginx-module
  1. 编译并安装:
make -j2
make install

示例Nginx配置

location = /api2 {
    content_by_lua_block {
        tmp=''
        for i,v in pairs(ngx.req.get_uri_args()) do
            if type(i)=='string' then
                tmp=tmp..i..' '
            end
        end
        ngx.header.content_type = "application/json;"
        ngx.status = 200
        ngx.say(tmp)
        ngx.exit(200)
    }
}

二、漏洞原理分析

参数限制问题

  1. ngx.req.get_uri_args() 默认最多处理100个参数
  2. 当参数超过100个时,超出的参数会被忽略
  3. 攻击者可以利用这个特性绕过某些安全检测

漏洞演示

  1. 生成测试参数(Python示例):
a=''
for i in range(1,102):
    a=a+'id'+str(i)+'=11&'
print(a)
  1. 发送101个参数的请求:
GET /api2?id1=11&id2=11&...&id100=11&id101=11 HTTP/1.1
  1. 响应结果:
  • 只返回前100个参数名(id1-id100)
  • id101被忽略

三、源码分析

关键函数调用链

  1. 注册流程:
ngx_http_lua_inject_ngx_api
    └── ngx_http_lua_inject_req_api
        ├── ngx_http_lua_inject_req_uri_api
        └── ngx_http_lua_inject_req_args_api
  1. 实际处理函数:
  • ngx_http_lua_ffi_req_get_uri_args(在src/ngx_http_lua_args.c中)

参数处理逻辑

  1. 关键代码片段:
if (i == count) {
    return i;
}
  1. 默认限制定义:
#ifndef NGX_HTTP_LUA_MAX_ARGS
#define NGX_HTTP_LUA_MAX_ARGS 100
#endif
  1. 参数解析过程:
  • =&分割键值对
  • 对键和值进行URI解码
  • 计数并限制最大处理数量

四、防御建议

  1. 修改默认限制:
# 在nginx.conf中增加
http {
    lua_max_uri_args 200; # 设置为更大的值
}
  1. 自定义参数处理:
local args = ngx.req.get_uri_args(0) -- 0表示不限制参数数量
  1. 参数数量检查:
local args = ngx.req.get_uri_args()
local arg_count = 0
for _ in pairs(args) do
    arg_count = arg_count + 1
end
if arg_count > 100 then
    ngx.exit(ngx.HTTP_BAD_REQUEST)
end
  1. 更新OpenResty版本(新版本可能已修复此问题)

五、总结

  1. 漏洞本质:Nginx_lua模块对URI参数数量的硬编码限制
  2. 影响:可能导致安全检测绕过(如WAF规则绕过)
  3. 修复:调整参数限制或实现自定义参数处理逻辑

通过深入分析源码,我们可以更好地理解这一限制的实现机制,并采取适当的防御措施。

Nginx_ lua 100参数绕过原理详解 一、环境搭建 Nginx_ lua 安装步骤 下载并解压Nginx源码: 设置LuaJIT环境变量(根据版本选择): 配置编译选项: 编译并安装: 示例Nginx配置 二、漏洞原理分析 参数限制问题 ngx.req.get_uri_args() 默认最多处理100个参数 当参数超过100个时,超出的参数会被忽略 攻击者可以利用这个特性绕过某些安全检测 漏洞演示 生成测试参数(Python示例): 发送101个参数的请求: 响应结果: 只返回前100个参数名(id1-id100) id101被忽略 三、源码分析 关键函数调用链 注册流程: 实际处理函数: ngx_http_lua_ffi_req_get_uri_args (在 src/ngx_http_lua_args.c 中) 参数处理逻辑 关键代码片段: 默认限制定义: 参数解析过程: 按 = 和 & 分割键值对 对键和值进行URI解码 计数并限制最大处理数量 四、防御建议 修改默认限制: 自定义参数处理: 参数数量检查: 更新OpenResty版本(新版本可能已修复此问题) 五、总结 漏洞本质:Nginx_ lua模块对URI参数数量的硬编码限制 影响:可能导致安全检测绕过(如WAF规则绕过) 修复:调整参数限制或实现自定义参数处理逻辑 通过深入分析源码,我们可以更好地理解这一限制的实现机制,并采取适当的防御措施。