WEB安全之:SSRF
郑重声明:
本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关。倡导维护网络安全人人有责,共同维护网络文明和谐。
SSRF
1 SSRF 简介
SSRF( Server-Side Request Forgery : 服务器端请求伪造 ) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统,也就是把目标网站当中间人)
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,文档,等等。
2 SSRF 带来的危害
-
扫内网:内网外网的端口和服务扫描
获取 Web 应用可达服务器的banner信息(如软件开发商、软件名称等),以及收集内网 Web 应用的指纹识别(如开放的端口、中间件版本等),根据这些信息再进行进一步的渗透;
-
攻击运行在内网或本地的应用程序(比如溢出)
获取内网系统弱口令进行内网漫游,对有漏洞的内网 Web 应用实施攻击获取webshell
-
攻击内外网的 Web 应用,主要是使用 GET 方法就可以实现的攻击
-
利用 file 协议读取本地敏感文件等
利用有脆弱性的组件结合
ftp://,file:///,gopher://,dict://
等协议实施攻击(如 FFmpeg 任意文件读取,XXE攻击等)。
3 可能存在 SSRF 漏洞的地方
只要从远程服务器请求资源,就可能存在 SSRF 漏洞
-
分享:通过URL地址分享网页内容
-
转码服务
-
在线翻译
-
图片加载与下载:通过URL地址加载或下载图片
-
图片、文章收藏功能
-
未公开的 API 实现以及其他调用URL的功能
-
从 URL 关键字中寻找
-
share wap url link src source target u 3g display sourceURl imageURL domain
-
4 SSRF 漏洞验证
4.1 排除法验证
4.1.1 点击验证
或以图片为例:
-
在页面源码中查找访问的资源地址 ,如果该资源地址类型为
www.target.com/xxx.php?image=http://image_address.com
的就可能存在 SSRF 漏洞 -
你可以直接右键图片,在新窗口打开图片,如果是浏览器上 URL 地址栏是
http://image_address.com
说明不存在 SSRF 漏洞。
4.1.2 抓包分析
因为 SSRF 漏洞是让服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的请求是否是由服务器的发送的,从而来判断是否存在 SSRF 漏洞
GET /ssrf01.php?url=http://192.168.100.129/phpMyAdmin/favicon.ico HTTP/1.1
Host: ssrf.lab.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: PHPSESSID=bvp2vv845n0les2efk4hg5b445
Upgrade-Insecure-Requests: 1
DNT: 1
Sec-GPC: 1
# 此处存在 SSRF 漏洞
5 SSRF 利用方式
SSRF-php初探 - p0pl4r - 博客园 (cnblogs.com)
5.1 无限制
5.1.1 ssrf01.php
<?php
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
$data = $_GET['url'];
$ret = curl($url);
echo $ret;
?>
<?php
include 'init.php';
if ($_GET['url']) {
// Client
$url = $_GET['url'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);
if ($curl_errno > 0) {
echo "cURL Error ($curl_errno): $curl_error\n";
} else {
echo "$data\n";
}
} else {
// Server
sleep(10);
echo "Done.";
}
?>
5.1.2 利用 Payload
// 利用 http 协议查看内网主机
http://ssrf.lab.com/ssrf01.php?url=http://192.168.100.129
// 利用 file 协议任意文件读取
http://ssrf.lab.com/ssrf01.php?url=file:///etc/passwd
// # 利用 dict 协议查看端口
http://ssrf.lab.com/ssrf01.php?url=dict://192.168.100.129:80
6 绕过方式
-
http://www.baidu.com@10.10.10.10 与 http://10.10.10.10
请求是相同的,访问请求得到的内容都是10.10.10.10
的内容。 -
IP 地址转换成进制来访问
-
添加端口可能绕过匹配正则,
10.10.10.10:80
-
用短地址(302跳转)绕过
-
利用
Enclosed alphanumerics
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿