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)之前的都是越界内容
相关推荐
forestsea13 小时前
深入理解Redisson RLocalCachedMap:本地缓存过期策略全解析
redis·缓存·redisson
全栈工程师修炼指南14 小时前
Nginx | stream 四层反向代理:SSL、PREREAD 阶段模块指令浅析与实践
运维·网络·网络协议·nginx·ssl
啦啦啦_999915 小时前
Redis-0-业务逻辑
数据库·redis·缓存
自不量力的A同学16 小时前
Redisson 4.2.0 发布,官方推荐的 Redis 客户端
数据库·redis·缓存
fengxin_rou16 小时前
[Redis从零到精通|第四篇]:缓存穿透、雪崩、击穿
java·redis·缓存·mybatis·idea·多线程
fengxin_rou16 小时前
黑马点评实战篇|第二篇:商户查询缓存
缓存
笨蛋不要掉眼泪17 小时前
Redis哨兵机制全解析:原理、配置与实战故障转移演示
java·数据库·redis·缓存·bootstrap
脏脏a17 小时前
告别物理出勤:Nginx 搭配 cpolar 实现远程开发无缝协作
运维·nginx
Dxy12393102161 天前
413 Request Entity Too Large 原因与解决方案
nginx
CYpdpjRnUE1 天前
光储一体机仿真模型搭建之旅
nginx