0x01 漏洞描述
服务端请求伪造 (Server-Side Request Forgery)。
由攻击者构造带有攻击的请求传给服务器执行造成的漏洞。
0x02 SSRF 漏洞作用
- 内网ip/端口扫描
- 服务器敏感数据读取
- 内网主机应用程序漏洞利用
-
0x03 SSRF漏洞的常见的位置
社交分享功能:获取超链接的标题等内容进行显示
- 图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
- 图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验
- 开发平台接口测试工具:一些公司会把自己的一些接口开放出来,形成第三方接口。这个时候他们通常会开发一个用于测试自己接口是否连通的web,给这些程序员测试接口,如果没有过滤好,就会造成ssrf
0x05 相关类
// 代码审计中想找ssrf
// 有一个简单的方法
// 搜索这个类,或是继承该类的,在或是与该类功能类似的就对了
java.net.URLConnection
0x06 查看谁继承了 URLConnection 的方法
mac下的idea: control + h
0x07 Java ssrf 中支持的伪协议
支持的伪协议 |
---|
file |
ftp |
http |
https |
jar |
mailto |
netdoc |
0x08 SSRF 漏洞基本利用例子
URLConnection: 可以走java中支持的各种协议,例如 file
HttpURLConnection: 只能走HTTP或是HTTPS协议
0x08.1 URLConnection-读取文件
import java.net.URL;
import java.net.URLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SsrfTest {
public static void main(String[] args) {
try {
// 漏洞利用点
String url = "https://www.baidu.com";
// 实例化url的对象
URL u = new URL(url);
//打开一个URL连接,并运行客户端访问资源。
URLConnection connection = u.openConnection();
connection.connect();
connection.getInputStream();
StringBuilder response = new StringBuilder();
//获取url中的资源
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
response.append(line + "\n");
}
in.close();
System.out.print(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 利用方式:
//
// 利用http/https访问站点
// 如果访问成功就会返回数据
// 例如:
// String url = "https://www.baidu.com";
// 利用http/https探测端口
// 开启访问的端口时会返回很快,如果没开启就会延迟一下
// 例如:
// String url = "https://127.0.0.1:8080";
// String url = "https://127.0.0.1:6379";
// 利用file协议查看文件
// 如果访问成功就会返回数据
// 例如:
// String url = "file://C:/Windows/win.ini";
// String url = "file:///etc/passwd";
0x08.2 HttpURLConnection-内网探测
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SsrfTest {
public static void main(String[] args) {
try {
// 漏洞利用点
String url = "https://www.baidu.com";
//实例化url的对象
URL u = new URL(url);
// 打开一个URL连接,并运行客户端访问资源。
URLConnection urlConnection = u.openConnection();
// 强转为HttpURLConnection
HttpURLConnection httpUrl = (HttpURLConnection) urlConnection;
StringBuilder response = new StringBuilder();
// 获取url中的资源
BufferedReader in = new BufferedReader(
new InputStreamReader(httpUrl.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 利用方式:
//
// 利用http/https访问站点
// 如果访问成功就会返回数据
// 例如:
// String url = "https://www.baidu.com";
// 利用http/https探测端口
// 开启访问的端口时会返回很快,如果没开启就会延迟一下
// 例如:
// String url = "https://127.0.0.1:8080";
// String url = "https://127.0.0.1:6379";
0x09 实战中可以拿来ssrf的类
想找ssrf的时候可以找找这些类的 输入点 是否外部可控
URL.openStream
URLConnection
HttpURLConnection
HttpURLConnection.connect
HttpURLConnection.getInputStream
HttpClient
HttpClient.execute
HttpClient.executeMethod
HttpRequest
HttpRequest.get
HttpRequest.post
HttpRequest.put
HttpRequest.delete
HttpRequest.head
HttpRequest.options
HttpRequest.trace
okhttp = Request request = new Request.Builder().url([触发点]).build();
0x10 总结
在挖掘的时候,一定请记住,如果可以在未经过验证的情况下发起一个远程请求,那么就有可能存在SSRF漏洞!!!!
只要记住这句话,SSRF漏洞挖掘起来就不难