SSRF突破对file协议的限制
Yu9

首发先知社区

首发奇安信攻防社区

链接:https://forum.butian.net/share/2939

0x01 前言

这两天在网上看到一个在java中ssrf绕过的小trick,主要就是以黑名单过滤了file协议的情况下,如何绕过!

0x02 环境搭建

jdk:11.0.11

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RequestMapping("/ssrf")
public String ssrf(String url) {
String urlContent = "";
try {
// 检查URL是否以"file://"开头
if (url.startsWith("file://")) {
return "URL can't start with 'file://'";
}

// 读取URL内容
URL u = new URL(url);
BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
urlContent += inputLine + "\n";
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}

return urlContent;
}

0x03 复现

直接使用file协议,黑名单直接过滤,然后返回

image-20240418195507488

poc:

1
url:file://xxx

image-20240418195546961

成功读取到文件!

0x04 分析

可以看到我们传入的路径url:file:///D://flag在经过URL()处理之后返回了file:///D://flag

image-20240418200508778

new URL() 的作用是创建一个 URL 对象,该对象表示一个统一资源定位符(URL)。

在Java中,URL类提供了一种方便的方式来处理URL,可以用于定位到互联网上的各种资源,例如网页、图像、视频等。

通过 new URL(String spec) 构造函数,可以将一个字符串形式的URL转换为URL对象。

这个字符串通常包含了URL的各个组成部分,如协议、主机名、端口、路径等。

具体的绕过逻辑就在URL(String spec)中,Alt+Shift+F7跟进去瞅瞅,一路向下走到java.net.URL#URL(java.net.URL, java.lang.String, java.net.URLStreamHandler)

在593行这段代码是在检查 URL 字符串是否以 “url:” 开头,并在匹配成后start+4(此时start=4)

image-20240418202916816

在603行,截取从start开始到了字符串 spec (即我们输入的地址url:file://xxx)的结尾或者下一个 / 字符,最终我们输入的url:file://xxx之类的构造会被解析为file

image-20240418203612786

0x05 总结

在对ssrf使用黑名单过过滤,我们可以使用正则匹配等手段来防御,但黑名单终归是不稳妥的!

想在java中若发起的请求时只支持使用HTTP/HTTPS协议,则可以使用以下几种方法!

1
2
3
HttpURLConnection
HttpClient
OkHttpClient.newCall.execute
由 Hexo 驱动 & 主题 Keep
总字数 50.7k 访客数 访问量