Java audit SSRF

Java audit SSRF

0x00 Preface

This article will record the audit learning related content of Java SSRF.

0x01 SSRF vulnerability details

Principle:

The server provides the function of obtaining data from other server applications without filtering and limiting the target address.

In most web server architectures, the web server itself can access the Internet and the intranet where the server is located.

SSRF function:

Scan the internal network and local port of the external network server to obtain the banner information of some services.

Attack applications running on the intranet or local.

Fingerprint identification of Intranet web application is realized by accessing the default file.

Attack web applications inside and outside the network. SQL injection, struct2, redis, etc.

Use File protocol to read local files, etc.

Pseudo protocol in PHP SSRF:

file dict sftp ldap tftp gopher

Pseudo protocol in Java SSRF:

file ftp mailto http https jar netdoc

0x02 SSRF generation process

In Java, SSRF can be divided into many scenarios. Unlike PHP, it supports various pseudo protocols and can be used directly.

Intranet detection in SSRF

@WebServlet("/ssrfServlet")
public class ssrfServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
    this.doGet(request,response);
    }

    protected void doGet(HttpServletRequest request,IOException {
        String url = request.getParameter("url");   //接收url的传参
        String htmlContent;
        PrintWriter writer = response.getWriter();  //获取响应的打印流对象
        URL u = new URL(url);   //实例化url的对象
        try {
            URLConnection urlConnection = u.openConnection();//打开一个URL连接,并运行客户端访问资源。
            HttpURLConnection httpUrl = (HttpURLConnection) urlConnection;  //强转为HttpURLConnection
            BufferedReader base = new BufferedReader(new InputStreamReader(httpUrl.getInputStream(),"UTF-8"));  //获取url中的资源
            StringBuffer html = new StringBuffer();
            while ((htmlContent = base.readLine()) != null) {
                html.append(htmlContent);  //htmlContent添加到html里面
            }
            base.close();

            writer.println(html);//响应中输出读取的资源
            writer.flush();

        } catch (Exception e) {
            e.printStackTrace();
            writer.println("请求失败");
            writer.flush();
        }
}

In the code, httpurlconnection httpurl = (httpurlconnection) urlconnection;, This place was forcibly converted, and I went to a certain degree to search for the specific purpose. come to conclusion:

URLConnection:可以走邮件、文件传输协议。
HttpURLConnection 只能走浏览器的HTTP协议

In other words, after the strong conversion to httpurlconnection is used, only HTTP protocol can be used to detect other applications in the server's intranet.

http://localhost:8080/ssrfServlet?url=http://www.baidu.com

Here we use Baidu to do a demonstration, because we are too lazy to build an environment in the intranet.

In the code, we did not verify the received URL. We directly created a URL object to access and read resources without verifying whether the URL is a whitelist URL, resulting in the generation of SSRF.

Try to read the file

You will find that you can't read it at all, because only HTTP and HTTPS protocols are supported here.

Let's try it. Try it without forcing it to httpurlconnection.

The code is as follows:

@WebServlet("/ssrfServlet")
public class ssrfServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,IOException {
        String url = request.getParameter("url");   //接收url的传参
        String htmlContent;
        PrintWriter writer = response.getWriter();  //获取响应的打印流对象
        URL u = new URL(url);   //实例化url的对象
        try {
            URLConnection urlConnection = u.openConnection();//打开一个URL连接,并运行客户端访问资源。
//            HttpURLConnection httpUrl = (HttpURLConnection) urlConnection;  //强转为HttpURLConnection
            BufferedReader base = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),"UTF-8"));  //获取url中的资源
            StringBuffer html = new StringBuffer();
            while ((htmlContent = base.readLine()) != null) {
                html.append(htmlContent);  //htmlContent添加到html里面
            }
            base.close();

            writer.println(html);//响应中输出读取的资源
            writer.flush();

        } catch (Exception e) {
            e.printStackTrace();
            writer.println("请求失败");
            writer.flush();
        }
http://localhost:8080/ssrfServlet?url=file:///c:%5c%5cwindows%5c%5cwin.ini

You can successfully read C: \ windows \ win INI file.

Read file in SSRF

The code is as follows:

@WebServlet("/readfileServlet")
public class downloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,IOException {


        String url = request.getParameter("url");
        int len;
        OutputStream outputStream = response.getOutputStream();
            URL file = new URL(url);
            byte[] bytes = new byte[1024];
        InputStream inputStream = file.openStream();

            while ((len = inputStream.read(bytes)) > 0) {
                outputStream.write(bytes,len);
            }
    }
}

Compared with the above code, it is found that they are basically the same. The only difference is that one is to obtain objects with openstream method and the other is to obtain objects with openconnection. The two methods are similar.

Official documentation:

openConnection():返回一个实例,该实例表示与所引用的远程对象的连接。 返回类型: URLConnection
openStream():打开与此连接,并返回一个值以从该连接读取。 			  返回类型:  InputStream 

detailed description:

openConnection:返回一个URLConnection对象,它表示到URL所引用的远程对象的连接。每次调用此URL的协议处理程序的openConnection方法都打开一个新的连接。如果URL的协议(例如,HTTP或JAR)存在属于以下包或其子包之一的公共、专用URLConnection子类:java.lang、java.io、java.util、java.net,返回的连接将为该子类的类型。例如,对于HTTP,将返回HttpURLConnection,对于JAR,将返回JarURLConnection。(返回到该URL的URLConnection!)

openStream():打开到此URL的连接并返回一个用于从该连接读入的InputStream。

Here, start the server and test it.

http://127.0.0.1:8080//downloadServlet?url=file:///C:%5c%5c1.txt

Note: here are three oblique bars, and the backslash needs URL code, otherwise an error will be reported

Pass in the backslash without URL encoding

File download in SSRF

Vulnerability Code:

@WebServlet("/downloadServlet")
public class downloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,IOException {
        String filename = "1.txt";

        String url = request.getParameter("url");
        response.setHeader("content-disposition","attachment;fileName=" + filename);
        int len;
        OutputStream outputStream = response.getOutputStream();
            URL file = new URL(url);
            byte[] bytes = new byte[1024];
        InputStream inputStream = file.openStream();

            while ((len = inputStream.read(bytes)) > 0) {
                outputStream.write(bytes,len);
            }
    }
}

Input:

http://localhost:8080/downloadServlet?url=file:///c:%5c%5c1.txt

In this way, the file is downloaded. The difference between file downloading and file reading in SSRF lies in the response header.

 response.setHeader("content-disposition","attachment;fileName=" + filename);

This code sets the MIME type to the file type and will be downloaded when accessing the browser.

Reference articles

https://xz.aliyun.com/t/2761#toc-1
https://xz.aliyun.com/t/206/
https://xz.aliyun.com/t/7186

0x03 end

Some of the generation of SSRF is not just as mentioned in the article, including some third-party components. If a remote request is initiated without verification, there may be SSRF vulnerabilities.

Later, I plan to find a set of source code to audit SSRF.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>