Nginx越界读取缓存漏洞CVE-2017-7529(参考peiqi文库以及gpt)

Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件。缓存的部分存储在文件中,每个缓存文件包括"文件头"+"HTTP返回包头"+"HTTP返回包体"。如果二次请求命中了该缓存文件,则Nginx会直接将该文件中的"HTTP返回包体"返回给用户。

脚本代码
这个headers['range']相当于在请求包中加了如下内容
Range: bytes=-1605,-9223372036854775808
headers本身就是一个请求包

如果我的请求中包含Range头,Nginx将会根据我指定的start和end位置,返回指定长度的内容。而如果我构造了两个负的位置,如(-600, -9223372036854774591),将可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于"HTTP返回包体"前的"文件头"、"HTTP返回包头"等内容。
bytes=-%d1,-%d1代表的是从文章末尾第d1个字节开始读,一直读到从文章末尾第d2个字节的位置,由于d2数字赋值较大,会越界读取服务器本不会加载的内容(这是我之前的理解,但是是错误的)
CVE-2017-7529 只能通过 bytes=-%d,-%d 这种"负数 + 多 Range"方式触发。
bytes=-%d1,-%d2
这个意思是两个范围从文章末往回数d1个字节读取后边的内容
第二个范围从文章末往回数d2个字节读取后边的内容
注意bytes=%d,%d并不会触发越界
只有"负数 + 多 Range"方式触发。
那这时候会想,多range为什么不返回多个内容,而只是返回了一个内容

二、那为什么 CVE-2017-7529 里你只看到"一坨数据"?❗

这是 这个漏洞最"反直觉"的地方

核心一句话:

漏洞发生在「缓存读取阶段」,而不是「HTTP Range 组包阶段」


三、Nginx 正常流程 vs 漏洞流程(非常关键)

✅ 正常情况(无漏洞)

流程是:
解析 Range 头 → 校验 Range 合法性 → 计算每个 range 的起止位置 → 生成 multipart/byteranges 响应


❌ CVE-2017-7529 的真实流程

流程变成了:
解析 Range 头 → 负数 Range 触发溢出 → 计算出一个错误的缓存偏移 → 直接从 cache 文件连续读取数据 → 当成"一个连续 buffer"返回
⚠️ 注意这里:
Nginx 根本没走到"multipart 组包"那一步


四、为什么它"退化成一个整体返回"?(重点)

因为:

  • 漏洞触发在:
    ngx_http_file_cache_read()
  • 这里是 底层缓存文件读取
  • 不是 HTTP 协议层
    结果是:
    它读的是"缓存文件中的连续内存/磁盘内容"
    而不是
    "两个逻辑上的 Range"

五、换成一句人话解释(超重要)

你可以这样理解:
本来你点了两样菜
厨师应该分盘给你
但因为后厨算错了位置
直接从冰箱里
把一整块乱七八糟的东西
倒你盘子里了

什么是组包

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=XYZ
--XYZ
Content-Range: bytes 2-4/20
234
--XYZ
Content-Range: bytes 7-8/20
78
--XYZ--
类似于这种

  • --XYZ 是分隔符
  • 每段都有 Content-Range
  • 每段的内容只包含客户端请求的那部分

三、CVE-2017-7529 里组包阶段为什么没生效?

在 CVE-2017-7529 里:

  1. 你发的 Range 是负数 + 多 Range:bytes=-1605,-9223372036854774203
  2. Nginx 在计算偏移量 的时候触发 整数溢出
  3. 结果:
  • 返回的数据不是逻辑上的两个区段
  • 而是 连续的缓存内容
  • 服务器根本没走"multipart 组包"的逻辑
    所以你看到的响应:
  • 没有 Content-Type: multipart/byteranges
  • 没有分段标记
  • 只是一坨连续数据

    最上边的content-type和content-range一直到key(包括key)之前的都是越界内容
相关推荐
serve the people6 小时前
滑块验证完整实现教程(前端 + 后端 + Nginx 集成)
运维·前端·nginx
大佐不会说日语~6 小时前
Spring AI Alibaba 对话记忆丢失问题:Redis 缓存过期后如何恢复 AI 上下文
java·人工智能·spring boot·redis·spring·缓存
武子康7 小时前
Java-197 消息队列应用场景:缓存预热+限流排队+Redis Lua 扣库存+MQ 削峰填谷
java·redis·缓存·性能优化·消息队列·rabbitmq·java-rabbitmq
小小8程序员18 小时前
Redis-10
数据库·redis·缓存
zwxu_19 小时前
Nginx NIO对比Java NIO
java·nginx·nio
FeelTouch Labs19 小时前
Nginx核心架构设计
运维·前端·nginx
MicoZone21 小时前
nginx(更新中)
nginx
Evan芙21 小时前
nginx+php部署walle,发布php站点
运维·nginx·php