Nginx的负载均衡与反向代理、docker复现Nginx错误配置漏洞

目录

一、Nginx的负载均衡与反向代理

1.Nginx环境搭建

1.1.安装步骤

2.负载均衡与反向代理实现

2.1.环境需求

2.2.配置与实现过程

二、docker复现Nginx配置漏洞

1.docker环境搭建

2.复现过程

2.1CRLF(carriage return/line feed)注入漏洞

2.2.目录穿越

​2.3.add_header覆盖


一、Nginx的负载均衡与反向代理

1.Nginx环境搭建

这里我选择的是CentOS7源码安装

1.1.安装步骤

1.首先创建Nginx的目录并进入:

mkdir /soft && mkdir /soft/nginx/
cd /soft/nginx/

2.下载Nginx的安装包,可以通过FTP工具上传离线环境包,也可通过wget命令在线获取安装包:

wget https://nginx.org/download/nginx-1.21.6.tar.gz

3.解压Nginx的压缩包:

tar -xvzf nginx-1.21.6.tar.gz

4.下载并安装Nginx所需的依赖库和包:

yum install --downloadonly --downloaddir=/soft/nginx/ gcc-c++
yum install --downloadonly --downloaddir=/soft/nginx/ pcre pcre-devel4
yum install --downloadonly --downloaddir=/soft/nginx/ zlib zlib-devel
yum install --downloadonly --downloaddir=/soft/nginx/ openssl openssl-devel

5.通过rpm命令安装所有依赖包:

rpm -ivh --nodeps *.rpm

6.进入解压后的nginx目录,安装其他依赖库,然后执行Nginx的配置脚本,为后续的安装提前配置好环境,默认位于/usr/local/nginx/目录下(可自定义目录):

cd nginx-1.21.6
yum install pcre-devel
yum install zlib-devel
./configure --prefix=/soft/nginx/

7.编译并安装Nginx:(安装完成后可以删除rpm包和其他压缩包了)

make && make install

8.修改安装后生成的conf目录下的nginx.conf配置文件:

server_name改成自己的ip 

9.制定配置文件并启动Nginx

sbin/nginx -c conf/nginx.conf

2.负载均衡与反向代理实现

2.1.环境需求

要实现这个效果,需要3台安装了Nginx的服务器才行,并且都可以互相访问(也可以一台,代理到不同的端口上)

这里我使用CentOS7作为Nginx的代理服务器:

CentOS7_IP:192.168.239.141

使用Ubuntu和物理机也就是本机作为web服务器:

Ubuntu_IP:192.168.239.138

Windows10_IP:192.168.239.1

2.2.配置与实现过程

1.首先需要两台web服务器都正常运行了web服务且Nginx反向代理服务器能够访问它们

我这里就都使用phpinfo,Ubuntu的php版本为8.1.2,Windows10的php版本为5.6.9

Ubuntu正常访问

win10正常访问

 2.配置反向代理

upstream nginx_boot{
   # 30s内检查心跳发送两次包,未回复就代表该机器宕机,请求分发权重比为1:2
       server 192.168.239.1:80 weight=100 max_fails=2 fail_timeout=30s;
       server 192.168.239.138:80 weight=200 max_fails=2 fail_timeout=30s;
   # 这里的IP请配置成你WEB服务所在的机器IP以及端口
             }

    server {
        listen       80;
        server_name  192.168.239.141;


        location / {
            proxy_set_header Host $host;    
            #将原始请求的Host头信息传递给后端服务器
            proxy_set_header X-Real-IP $remote_addr;
            #将客户端的真实 IP 地址传递给后端服务器
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #这个配置指令用于构建一个包含了客户端 IP 地址的 HTTP 头部。每经过一个代理服务器,代 
            #理服务器会将自己的 IP 地址添加到这个头部的值中,以表示请求经过的路径。
            proxy_pass http://nginx_boot/test/index.php;
            #请求交给名为nginx_boot的upstream上
            #这里注意我添加test目录是因为web服务器的web页面在test目录下
        }

3.重启服务,浏览器访问

sbin/nginx -c conf/nginx.conf
#cd 到/soft/nginx目录下运行
#如果出现端口占用,杀掉进程再运行命令

效果图

可以看到虽然我们访问的是Nginx反向代理服务器的ip,但是它给我们代理到了另外两台服务器的web服务上,所以成功实现啦

二、docker复现Nginx配置漏洞

1.docker环境搭建

1.安装docker

Debian系列

apt-get update
apt-get install docker.io

Redhat系列

yum install docker.io

2.下载并解压docker环境Nginx配置漏洞安装包

链接:https://pan.baidu.com/s/1gL4_ZUbY5mA-qo6sG5-yWQ?pwd=s6l9 
提取码:s6l9

cd到对应目录下,docker启容器

unzip vulhub-master.zip
cd /root/vulhub-master/nginx/insecure-configuration
docker-compose up -d

这里主要注意两个问题:

  • 没有docker-compose命令,较新版本的docker应该自带compose,没有的可以apt或者yum下载
apt-get install docker-compose
  • 可能会报与官方镜像源连接超时的问题,切换阿里云的docker镜像源就好
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://t6mxxtn9.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

如果还有其他报错,可以去找docker的官方文档解决

Docker Desktop | Docker Documentation

安装好后,用docker ps -a查看容器运行情况

root@localhost:~/vulhub-master/nginx/insecure-configuration# docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS                                                                   NAMES
797f6975a01e   vulhub/nginx:1   "nginx -g 'daemon of…"   59 minutes ago   Up 59 minutes   80/tcp, 0.0.0.0:8080-8082->8080-8082/tcp, :::8080-8082->8080-8082/tcp   insecure-configuration_nginx_1

 STATUS为up状态就表示容器正在运行

如果要进入容器,键入docker exec -it 797f6975a01e(这里写你的容器ID) /bin/bash命令

2.复现过程

2.1CRLF(carriage return/line feed)注入漏洞

这个漏洞产生的原因是请求重定向的错误配置,导致在url中输入回车换行符可以控制http响应头部

比如:

location / {
    return 302 https://$host$uri;
}

原本的目的是为了让http的请求跳转到https上

但是$uri参数是不包含查询参数的,于是当我们在url中输入%0d%0a时,$uri参数不会将回车换行符传入,这就导致用户可以控制http响应头部

访问http://ip:8080,使用bp抓包,构造反射性xss

%0d%0a%0d%0a<img src=1 onerror=alert(1)>

修复方法:把$url改为$request-uri,这个参数会传入完整的原始url请求,也就是说用户输入的所有内容都会被当做参数传入Location字段

 2.2.目录穿越

这个漏洞产生的原因是alias别名配置错误,导致在url中拼接目录获取敏感数据

location /files {
        alias /home/;
    }

原本的目的是想用户输入/files会跳转到/home目录下,但是/files并没有以"/"结尾,所以我们可以输入/files../,此时/files匹配上了,替换为/home/..,造成目录穿越

修复方法:将/files改为/files/,这样就算输入/files../也不会匹配上/files/

 2.3.add_header覆盖

这个漏洞产生的原因是Location子块中又添加了add_header参数,覆盖了父块中的参数,导致失效

    add_header Content-Security-Policy "default-src 'self'";
    #这个头部用于配置浏览器加载和执行内容的安全策略。在这里,设置为 "default-src 'self'" 表示只        
    #允许从同源(即当前域名)加载内容,其他来源的内容被禁止加载。
    add_header X-Frame-Options DENY;
    #防止页面被嵌入到 <frame>、<iframe> 或其他框架中。设置为 DENY 表示不允许任何形式的嵌入。
        location = /test1 {
                rewrite ^(.*)$ /xss.html break;
        }

    location = /test2 {
        add_header X-Content-Type-Options nosniff;
        #该头部防止浏览器尝试嗅探未知 MIME 类型的响应内容
        rewrite ^(.*)$ /xss.html break;
    }

这个配置本意是想在子块中再添加一个参数,结果覆盖父块,导致父块参数全部失效

bp抓包发现父块添加的参数消失,只有子块里的参数

 修复方法:删除子块中的add_header参数,或者添加到父块中

猜你喜欢

转载自blog.csdn.net/CQ17743254852/article/details/132151549