SSRF总结

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

0x00 概念

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

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

注释:除了http/https等方式可以造成ssrf,类似tcp connect 方式也可以探测内网一些ip 的端口是否开发服务,只不过危害比较小而已。

0x01 可能出现的地方

1.社交分享功能:获取超链接的标题等内容进行显示

2.转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览

3.在线翻译:给网址翻译对应网页的内容

4.图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片

5.图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验

6.云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试

7.网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作

8.数据库内置功能:数据库的比如mongodbcopyDatabase函数

9.邮件系统:比如接收邮件服务器地址

10.编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等

11.未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞

一些的url中的关键字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……

12.从远程服务器请求资源(upload from url 如discuz!; import & expost rss feed 如web blog; 使用了xml引擎对象的地方 如wordpress xmlrpc.php)

13.WebHooks:寻找触发特定事件时发出http请求的服务。在大多数WebHooks的功能中,终端用户可以选择他们的终端点和主机名。尝试向内部服务发送http请求。

14.PDF生成器:试着注入指向内部服务的<iframe>,<img>,<base>或者<script>元素或者CSS的url()函数。

15.文档解析器:尝试了解文档是如何被解析的。如果是XML文档,那就是用了PDF生成器方法。对于其他文档,检查是否存在引用外部资源的方法然后通过服务器向内部服务发送请求。

16.链接扩展: 最近Mark Litchfield在推特扩展链接上发现了漏洞,名声大涨。

17.文件上传:与常规上传文件相反,尝试发送url请求然后检查是否下载了url的内容。例子

0x02 漏洞验证

1.排除法:浏览器f12查看源代码看是否是在本地进行了请求。

比如:该资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞。

2.dnslog等工具进行测试,看是否被访问。

  • 可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。

3.抓包分析发送的请求是不是由服务器的发送的,如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址。

  • 从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址

  • 通过二级域名暴力猜解工具模糊猜测内网地址。

4.直接返回的Banner、title、content等信息。

5.留意bool型SSRF

0x03 一些利用方式

1.让服务端去访问相应的网址 比如在自己的服务器上监听端口然后在url让他去请求我们的服务器

2.让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms

3.可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件

4.攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包{payload})

5.攻击内网应用程序(利用跨协议通信技术)

6.判断内网主机是否存活:方法是访问看是否有端口开放

某些时候SSRF漏洞可以用作局域网内的端口扫描。这有助于理清内网的基础设施轮廓和并为下一步其他漏洞的利用做铺垫。上述这种情况通常是最简单的blind SSRF了。如果之前的脚本无法建立连接或收不到服务器响应,异常将被抛出。利用这个特征可以识别端口是否开放(连接建立)或关闭(连接失败或超时)。

0x04 绕过小技巧

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://192.168.0.1.xip.io/ == 192.168.0.1

6.限制了子网段,可以加 :80 端口绕过。http://tieba.baidu.com/f/commit/share/openShareApi?url=http://10.42.7.78:80

7.探测内网域名,或者将自己的域名解析到内网ip

8.例如 http://10.153.138.81/ts.php , 修复时容易出现的获取host时以/分割来确定host,

但这样可以用 http://abc@10.153.138.81/ 绕过

0x05 漏洞修复

1.禁止跳转

2.过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。

3.禁用不需要的协议,仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp:// 等引起的问题

4.设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP)

5.限制请求的端口为http常用的端口,比如 80、443、8080、8090

6.统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

0x06 漏洞利用中牵涉的小技巧

crontab -l 显示当前计划任务

crontab -r 清除当前计划任务

端口转发工具 socat

在Apache配置文件中写入下面的内容,就可以将jpg文件当做PHP文件来执行

AddType application/x-httpd-php .jpg
……

常用的探测内网地址

1
10.0.0.0/8 127.0.0.1/32 172.16.0.0/12 192.168.0.0/16

常用的探测端口

1
21, 22, 23, 25, 53, 80, 110, 443, 1433, 3306, 3389, 8080, 8443

0x07 举一个栗子

先说一下关于SSRF的函数

curl造成的SSRF

1
2
3
4
5
6
7
8
9
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

1
2
$url = $_GET['url'];
echo file_get_contents($url);

fsockopen造成的SSRF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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;
}
}

这里我们直接使用docker搭建了Bwapp平台做测试 其实本地搭建php就可以

docker使用命令:

1
2
3
docker search bwapp
docker pull raesene/bwapp
docker run -d -p 8080:80 raesene/bwapp

这里我们选择文件包含测试 难度选择low 点击GO

html

html

这时候我们可以看到language参数的值是一个文件 这时候我们用内网探测脚本试一试

html

这里放出内网探测的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php


if(isset($_REQUEST["ip"]))
{

//list of port numbers to scan
$ports = array(21, 22, 23, 25, 53, 80, 110, 1433, 3306);

$results = array();

foreach($ports as $port)
{

if($pf = @fsockopen($_REQUEST["ip"], $port, $err, $err_string, 1))
{

$results[$port] = true;
fclose($pf);

}

else
{

$results[$port] = false;

}

}

foreach($results as $port=>$val)
{

$prot = getservbyport($port,"tcp");
echo "Port $port ($prot): ";

if($val)
{

echo "<span style=\"color:green\">OK</span><br/>";

}

else
{

echo "<span style=\"color:red\">Inaccessible</span><br/>";

}

}

}
?>

其实这里是有一个坑的 网上的一些教程说是在bwapp里选择ssrf会提供三个脚本 但是我去docker里找了根本没有这个文件夹 然后又去github上找了这个docker的文件 发现也没有emmm 最后在github上搜到了这个脚本 我把链接贴出来Bwapp 的POC

Redis getshll留坑 原先写过 找不到了等重新加到后面吧。