浅析SSRF漏洞

发布于 2021-08-06  105 次阅读


SSRF(Server-side Request Forge, 服务端请求伪造)

什么是 SSRF

他是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

SSRF 形成的原因

​ 大多数SSRF产生的原因是服务端提供了从其他服务器获取数据的功能,并且没有对目的地址做过滤和限制.比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载

代码案例

//curl造成的SSRF
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}

$url = $_GET['url'];
curl($url);

//file_get_contents造成的SSRF
$url = $_GET['url'];
echo file_get_contents($url);

//fsockopen造成的SSRF
<?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;
}
}

SSRF攻击流程

假定 A 为一个公司的主站,所有人都可以访问, B 是该公司内部的一个网站,只有公司能为能够访问,且与 A 能够相互访问。

正常用户:

输入A网站URL –> 发送请求 –> A服务器接受请求,并处理 –>返回用户响应

此时如果A服务器接受请求是没有经过严格的过滤,导致A能够在B上获取数据,就会产生SSRF

例如:

正常用户输入的URL:http://www.123.com/index.php?img=www.aaa.com/1.jpg

攻击者将www.aaa.com换成B的内网地址,如果存在就返回1XX | 2XX的状态码,不存在就会出现其他的状态码

因此,SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有检测这个请求是否合法的,然后服务器以他的身份来访问其他服务器的资源。

SSRF可能出现的地方(核心就是调用外部资源的所有参数都有可能)

  1. 社交分享功能:获取超链接的标题等内容进行显示
  2. 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
  3. 在线翻译:给网址翻译对应网页的内容
  4. 图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
  5. 图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用户体验
  6. 网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
  7. 数据库内置功能:数据库的比如mongodbcopyDatabase函数
  8. 邮件系统:比如接收邮件服务器地址
  9. 编码处理, 属性信息处理,文件处理:比如fpmg,ImageMagick,docx,pdf,xml处理器等
  10. 从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php
  11. 将url换成我们的DNS服务器,通过查看DNFlog平台日志看是否有服务器ip判断是否有SSRF漏洞

SSRF的危害

  1. 让服务端去访问相应的网址
  2. 让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms
  3. 可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件
  4. 攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包payload
  5. 判断内网主机是否存活:方法是访问看是否有端口开放
  6. DoS攻击(请求大文件,始终保持连接keep-alive always

SSRF漏洞利用

  • dict协议,操作redis服务,例如:dict://127.0.0.1:6379/info
  • file协议,任意文件读取,例如:file:///etc/passwd
  • gopher,反弹shell,例如gopher://127.0.0.1:6379/xxxxxxx
  • http,结合burpsuite探测内网存活主机

SSRF利用小技巧

  1. http://baidu.com@www.baidu.com/与http://www.baidu.com/请求时是相同的
  2. 各种IP地址的进制转换
  3. URL跳转绕过:http://www.hackersb.cn/redirect.php?url=http://192.168.0.1/
  4. 短网址绕过 http://t.cn/RwbLKDx
  5. xip.io来绕过:http://xxx.192.168.0.1.xip.io/ == 192.168.0.1 (xxx 任意,利用重定向)
  6. 限制了子网段,可以加 :80 端口绕过。http://tieba.baidu.com/f/commit/share/openShareApi?url=http://10.42.7.78:80
  7. 例如 http://10.153.138.81/ts.php , 修复时容易出现的获取host时以/分割来确定host,但这样可以用 http://abc@10.153.138.81/ 绕过

SSRF如何防护

  • 黑名单
    1. 过滤10.0.0.0/8 、172.16.0.0/12、192.168.0.0/16、localhost私有地址、IPv6地址
    2. 过滤file:///、dict://、gopher://、ftp:// 危险协议
    3. 对返回的内容进行识别
  • 白名单
    1. 使用地址白名单
    2. 对返回内容进行识别
    3. 需要使用互联网资源(比如贴吧使用网络图片)而无法使用白名单的情况:首先禁用 CURLOPT_FOLLOWLOCATION;然后通过域名获取目标ip,并过滤内部ip;最后识别返回的内容是否与假定内容一致