目录
1.SSRF简介
SSRF概念
SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,利用服务器端发起的安全漏洞。
SRF的类型
显示攻击者的响应(Basic)
不显示响应(Blind)
SSRF攻击目标
一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务器端发起的,所以服务器能请求到与自身相连,而与外网隔离的内部系统)。
SSRF漏洞产生的原因
由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址进行过滤和限制。
举例:
SSRF漏洞危害
- 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息;
- 攻击运行在内网或本地的应用程序(比如溢出);
- 对内网web应用进行指纹识别,通过访问默认文件实现(Readme等文件);
- 攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sql注入等);
- 下载内网资源,如利用file协议读取本地文件等。
- 利用Redis未授权访问,HTTP CRLF注入达到getshell
- wooyun峰会猪猪侠的ppt
- 进行跳板
- 无视cdn
2.漏洞寻找
- 分享:通过URL分享网页内容
- 转码服务:通过url地址把原地址的网页内容调优使得适合手机屏幕浏览
- 在线翻译:通过url地址翻译对应的文本内容,例如 百度 有道
- 图片加载与下载 通过url地址加载或者下载图片
- 图片、文章的收藏功能
- 未公开的api实现以及其他调用url的功能
- 从url关键字中寻找:share、wap、url、link、src、source、target、u、3g、dispaly、sourceURI、ImageURL、domain......
注:Google hacking: inurl:imageURL=所有需要你输入网址的地方、可以输入ip的都放,都是ssrf的天下。
3.漏洞产生
- curl_exec()函数造成的ssrf漏洞
<?php
function curl($url){
$ch = curl_init();//初始化一个新的curl会话,返回一个curl句柄
curl_setopt($ch, CURLOPT_URL,$url);//设置一个curl传输选项,需要获取的url地址
curl_setopt($ch, CURLOPT_HEADER,0);//启动时候将头文件的信息作为数据流输出
curl_exec($ch);//执行一个curl会话
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
?>
- file_get_contents()函数造成的ssrf
<?php
$url = $_GET['url'];
echo file_get_contents($url);
?>
file_get_contents:文件写入字符串,当url是内网文件的时候,会先去把这个文件的内容读出来再写入,导致了文件读取。
- fsockopen()函数造成的ssrf
<?php
function getfile($host,$port,$link){
$fp = fsockopen($host,intval($port),$errno,$errstr,30);//打开一个网络连接或者一个unix套接字连接
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);
# code...
}
fclose($fp)mianshiti
return $contents;
}
}
echo(getfile("127.0.0.1","80","index.php"));
?>
4.漏洞利用
查看curl支持的协议
本地利用 (注:在windows环境下使用curl命令需要将单引号改为双引号)
利用file协议查看文件:curl -v 'file:///etc/passwd' 可用于任意文件读取
利用dict协议探测端口:curl -v 'dict://127.0.0.1:6389/info' redis漏洞
探测目标机的80端口,可以看到相关服务和版本号,找到对应的漏洞
利用gopher协议反弹shell:curl -v "gopher://127.0.0.1:80/_info"
漏洞利用小结:
- 让服务器端访问相应的网址
- 让服务器去访问自己所处内网的一些指纹文件来判断
- 可以通过使用file、dict、gopher、ftp协议进行请求访问相应的文件
- 攻击web应用程序 struts2漏洞
- 攻击内网应用程序 如redis
- 判断内网主机是否存活:查看相对应的端口
- DOS攻击(请求大文件、始终保持keep-alive always) https://blog.chaitin.cn/gopher-attack-surfaces/
远程利用
ssrf.php:未做任何过滤和防御机制
file、http/https、dict、gopher等协议均可使用
ssrf01.php:限制只能使用http/https协议,设置跳转重定向为True(即默认不跳转)
此时使用file、dict等
协议已经无法使用,可以利用302跳转
的方式来绕过http/https协议限制
5.漏洞绕过
- 利用@:http://[email protected]
例如:http://[email protected]与http://10.10.10.10 请求是相同的
- 添加端口号:http://127.0.0.1:8080
- 利用短地址:http://dwz.cn/11SMa
- ip 地址进制转换:以192.168.109.150为例
首先,转换为十六进制:c0.a8.6d.96
接着,转换为八进制:300.250.155.226
即192.168.109.150 = 300250155226 访问:http://00300250155226
- 可以指向任意ip的域名:xip.io
6.漏洞防御
- 将回显的报错信息进行统一,或者采用报错不回显,防止用户可以报错信息判断远端服务器的端口状态。
- 限制请求的端口只能为web端口,禁用类似于file、gopher等不需要的协议,只允许访问http和https的请求,其中常用的端口有:80,443,8080……
- 采用黑名单机制,限制不能访问内网的IP地址,防止应用被用来获取内网信息而对内网进行攻击
- 屏蔽返回的详细信息,或者过滤返回信息,验证远程服务器对请求的响应,例如:如果web应用是去获取某一种类型的文件,那么在把返回结果展示给用户之前,先验证返回的信息是否符合标准。
7.验证SSRF
- 排除法:浏览器f12查看源代码是否在本地进行了请求
- 利用ceye等平台测试、查看访问的回显
- 抓包分析发送的请求是不是由服务器发送的、如果不是客户端发送的请求则有可能是 接着找存在http服务的内网地址
从漏洞平台中的历史漏洞寻找泄露存在的web应用内网地址
通过二级域名爆破破解工具猜测内网地址
留意直接返回的banner title content等信息
留意bool型的ssrf