文章目录
- 一、SSRF漏洞描述
- 二、漏洞危害
- 三、可能存在SSRF漏洞的地方
- 四、常见漏洞函数
- Java中的SSRF
- Python中的SSRF
- PHP中的SSRF
- 五、可利用的协议
- 六、SSRF过滤绕过方法
- 七、漏洞修复建议
一、SSRF漏洞描述
SSRF(全称Server-Side Request Forgery
),即服务器端请求伪造
。SSRF是一种由攻击者构造请求,服务端发起请求的漏洞。SSRF攻击的目标是外网无法访问的内部系统(服务端可以请求到与自身相连而与外网隔离的内部系统)。SSRF形成的原因是服务端提供了从其他服务器获取数据的功能,但没有对目标地址做过滤与限制,导致攻击者在服务端从指定URL地址获取内部系统的数据(文件、图片等)。
二、漏洞危害
1、利用漏洞探测其他应用,如对服务器所在的内网环境进行端口扫描、指纹识别、资源访问等。
2、利用漏洞攻击其它内网应用(如内网web应用、redis服务等),特定情况可结合内网RCE等漏洞突破互联网边界。
3、利用file协议读取服务器本地文件,造成信息泄露风险。
4、云上SSRF漏洞可读取云主机的元数据信息。
三、可能存在SSRF漏洞的地方
- 转码服务
- 在线翻译
- 获取超链接的标题等内容进行显示
- 请求远程服务器资源的地方,图片加载与下载(通过URL地址加载或下载图片)
- 图片、文章收藏功能
- 对外发起网络请求的地方、网站采集、网页抓取的地方
- 一切要你输入网址的地方和可以输入ip的地方
- 数据库内置功能(Mongodb的copyDatabase函数)
- 从URL关键字中寻找:share、wap、url、link、src、source、target、u、3g、display、sourceURL、imageURL、domain
四、常见漏洞函数
Java中的SSRF
- HttpURLConnection
当使用HttpURLConnection发起HTTP请求时,当没有对url参数进行限制,此时就可能存在SSRF漏洞,可以通过修改url参数来探测、攻击其他应用,漏洞代码示例如下:
String url = request.getParameter("url");
StringBuffer response = new StringBuffer();
URL pic = new URL(url);
HttpURLConnection con = (HttpURLConnection)pic.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
- httpClient
当使用httpClient获取图片二进制流时,如果url参数可控且没有对url参数进行校验,此时就可能存在SSRF漏洞,可以通过修改url参数来探测、攻击其他应用,漏洞代码示例如下:
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet getRequest = new HttpGet(url);
HttpResponse response = httpClient.execute(getRequest);
- Socket
当使用Socket建立链接判断ip对应端口的联通性,如果host和port参数是由用户输入,且没有对可访问的host和port进行限制,此时就会存在SSRF漏洞,利用SSRF进行端口扫描,漏洞代码示例如下:
String host = request.getParameter("host");
String port = request.getParameter("port");
socket = new Socket(host, port);
- OkHttpClient
当使用OkHttpClient发起http请求时,如果url参数可控且没有对url参数进行校验,此时就可能存在SSRF漏洞,可以通过修改url参数来探测、攻击其他应用,漏洞代码示例如下:
String url = request.getParameter("url");
OkHttpClient httpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response = httpClient.newCall(request).execute();
return response.body().string();
- ImageIO
当使用ImageIO读取远程图片时,如果url参数可控且没有对url参数进行校验,此时就可能存在SSRF漏洞,可以通过修改url参数来探测、攻击其他应用,漏洞代码示例如下:
String imgurl = request.getParameter("url");
URL url = new URL(imgurl);
Image image = ImageIO.read(url);
return image;
Python中的SSRF
python中可以造成SSRF漏洞的库有pycurl、urllib、urllib3、requests等,如urllib库请求一个url,如果url参数可控且没有对url参数进行校验,此时就可能存在SSRF漏洞,可以通过修改url参数来探测、攻击其他应用,漏洞代码示例如下:
import urllib.request
req = urllib.request.urlopen("url")
print(req.read())
PHP中的SSRF
- curl_exec()
通过get传参变量url,然后再把这个变量url代入curl函数,通过curl_exec发起一个请求,如果url参数可控且没有对url参数进行校验,此时就可能存在SSRF漏洞,可以通过修改url参数来探测、攻击其他应用,漏洞代码示例如下:
<?php
function curl($url){
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
#curl_setopt($ch,CUPLOPT_HEADER,1);
curl_exec($ch);
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
?>
- file_get_contents()
file_get_content函数从用户指定的url获取内容,并展示给用户。当url参数可控就可能存在SSRF漏洞,此时可以利用file协议读取服务器上任意文件,漏洞代码示例如下:
<?php
$url = $_GET['url'];
echo file_get_contents($url);
?>
- fsockopen()
fsockopen 函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。变量host为主机名,port为端口,当host和port可控时就可能存在SSRF漏洞,通过遍历host和port进行内网端口扫描,漏洞代码示例如下:
<?php
$host=$_GET['url'];
$port=$_GET['port'];
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}?>
五、可利用的协议
http/https
,发起HTTP请求file
,如果会回显数据的话,那么我们可以使用file协议读取目标本地文件dict
,可以用来探测目标端口gopher
,可以发送get/post请求ftp
,文件传输协议- ………
六、SSRF过滤绕过方法
0.0.0.0
这个IP地址可以直接访问到本地- 把IP地址的格式进行转换从而绕过
(通常我们用的是127.0.0.1
,但事实上127这个段的地址都用来表示本机地址了,所以像127.155.155.155
这样的也是可以的,还可以进行进制转换也是可以的)
8进制
(把127转为八进制写的时候前面加个0):0177.0.0.1
16进制
(把127转为十六进制写的时候前面加个0x):0x7f.0.0.1
16进制整数格式
:0x7f000001
10进制证书格式
(把16整数转为10进制):2130706433
- Localhost
- 利用@绕过例如,www.baidu.com@127.0.0.1
- 利用非HTTP协议,例如上面说到的gopher或者dict
- 利用DNS解析(DNSlog)
- 利用IPv6
- 添加端口号
- [::]代替
127.0.0.1
,比如http://[::]:80
,这样也是可以访问到的。
七、漏洞修复建议
1、屏蔽或过滤返回的详细信息
2、仅允许HTTP和HTTPS请求,禁用高危协议如:file://
、gopher://
、ftp://
、dict://
等
3、限制请求的端口为http请求,如:80
、443
等
4、设置请求的URL白名单或者限制内网IP
5、统一错误信息,避免攻击者可以根据错误信息来判断远端服务器的端口状态
6、针对云上SSRF读取元数据可以设置元数据访问模式为加固模式,即通过token鉴权访问元数据接口