一、ssrf
SSRF (Server-Side Request Forgery:服务器端请求伪造)
其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制
导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流: 攻击者----->服务器---->目标地址
一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所以可以通过它攻击外网无法访问的内部系统,也就是把目标网站当中间人)
首先,我们要对目标网站的架构了解,脑子了要有一个架构图。比如 : A网站,是一个所有人都可以访问的外网网站,B网站是一个他们内部的OA网站。
所以,我们普通用户只可以访问a网站,不能访问b网站。但是我们可以同过a网站做中间人,访问b网站,从而达到攻击b网站需求。
终极简析: SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有检测这个请求是否合法的,然后服务器以他的身份来访问其他服务器的资源。
二、ssrf常见的代码实现
根据后台使用的函数的不同,对应的影响和利用方法又有不一样
PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
通过phpinfo()函数查看对curl扩展的支持,现在大部分wamp套件均支持curl扩展
如果一定要通过后台服务器远程去对用户指定(“或者预埋在前端的请求”)的地址进行资源请求,则请做好目标地址的过滤
- file_get_contents()
<?php
if (isset($_POST['url'])) {
$content = file_get_contents($_POST['url']);
$filename ='./images/'.rand().';img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";
}
echo $img;
?>
- 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);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
- curl_exec()
<?php
if (isset($_POST['url'])){
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($curlobj);
curl_close($curlobj);
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
三、协议
-
gopher协议
gopher协议在SSRF漏洞利用中号称万金油,比http协议更早出现的协议
利用此协议可以攻击内网的 FTP、Telnet、Redis、Memcache
也可以进行 GET、POST 请求
这样便可以解决漏洞点不在GET参数的问题了。
基本协议格式:URL:gopher://<host>:<port>/<gopher-path>
-
dict协议
dict协议是一个字典服务器协议,通常用于让客户端使用过程中能够访问更多的字典源
但是在SSRF中如果可以使用dict协议那么就可以轻易的获取目标服务器端口上运行的服务版本等信息。
如请求http://192.168.163.150/test.php?url=dict://192.168.163.1:3306/info
可以获取目标主机的3306端口上运行着mysq版本的应用 -
file协议
利用file协议可以任意读取系统本地文件
其他可支持的请求方式:ftp://
ssh://
telent://
php://
tftp://
四、ssrf的利用
SSRF的作用:
外和内网的端口和服务扫描
主机本地敏感数据的读取
外和内网主机应用程序漏洞的利用
外和内网Web站点漏洞的利用
-
访问正常文件
?url=http://www.baidu.com/robot.txt
-
端口扫描
当访问未开放端口,脚本会显示空白或者报错
?url=dict://127.0.0.1:1234
当访问开放端口,脚本会显示banner信息
?url=dict://127.0.0.1:22
-
读取系统本地文件
?url=file://c:\windows\system32\drivers\etc\hosts
-
内网web应用指纹识别
通过访问下列文件来判断phpmyadmin是否安装以及详细版本
?url=http://localhost/phpmyadmin/readme
-
攻击内网应用
内网的安全通常都很薄弱,溢出、弱口令等一般都是存在的
通过ssrf攻击,可以实现对内网的访问,从而可以攻击内网应用或者本地机器,获得shell
这里的应用包括服务、web应用等
五、SSRF漏洞的寻找(漏洞常见出没位置)
-
分享:通过URL地址分享网页内容
-
转码服务
-
在线翻译
-
图片加载与下载:通过URL地址加载或下载图片
-
图片、文章收藏功能
-
未公开的api实现以及其他调用URL的功能
-
从URL关键字中寻找:
share wap url link
src source target u
3g display sourceURl
imageURL domain
六、SSRF漏洞的验证方法
-
因为SSRF漏洞是让服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的请求是否是由服务器的发送的,从而来判断是否存在SSRF漏洞
-
在页面源码中查找访问的资源地址 ,如果该资源地址类型为 www.baidu.com/xxx.php?image=(地址)的就可能存在SSRF漏洞
七、ssrf的防御
- 限制协议
仅允许通过http和https请求 - 限制IP
避免被用来获取内网数据,攻击内网 - 限制端口
限制请求的端口为http常用的端口,比如:80,443,8080,8090 - 过滤返回信息
验证远程服务器对请求的响应是比较简单的方法 - 统一错误信息
免用户可以根据错误信息来判断远程服务器的端口状态
八、绕过方式
-
通过url只解析@符号后面的域名进行绕过
例如http://www.baidu.com@127.0.0.1
-
编码绕过
利用八进制IP地址绕过0177.0.0.1
利用十进制IP地址绕过2130706433
利用十六进制IP地址绕过0x7f000001