Java代码审计之路二(SSRF漏洞审计)

Posted OceanSec

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java代码审计之路二(SSRF漏洞审计)相关的知识,希望对你有一定的参考价值。


文章目录

SSRF

Java 网络请求支持的协议,包括:http、https、file、mailto、jar、netdoc,但是相对 php 可以利用很多伪协议来说 Java SSRF 还是略显单调

补充:

mailto:是一个用于发送邮件的 URL 协议

jar:Jar URL协议解析,协议可以用来读取 zip 格式文件(包括 jar 包)中的内容

netdoc 协议:在大部分情况下可代替 file

虽然支持多种协议,但是 Java 的 SSRF 利用方式比较局限,一般只用以下两种方式

  • 利用 file 协议任意文件读取
  • 利用 http 协议端口探测

环境搭建

代码来自 Java 代码审计入门篇一书作者 panda https://github.com/cn-panda/JavaCodeAudit

因为 panda 师傅使用的是 eclipse,用 idea 的话需要稍微操作一下

  1. 使用 idea 导入项目

    File–>New–>Project from Existing sources

    选择 Eclispe 项目,然后点击 OK,进入下一步

    选择第二项,导入 Eclipse 项目

    然后一路 next 即可

    在 WEB-INF 目录下新建 lib 目录和 classes 目录

  2. 配置项目

    打开 Project Structure 窗口

    设置 Modules,Eclipse 导入的项目此处主要是将 Dependencies 中关于 Eclipse 的依赖移除即可,然后点击加号添加 lib 目录

    点击加号,选择 tomcat 所在的目录,在 lib 目录下找到 servlet-api.jar 这个 jar 包导入完成即可,不导入会提示 java: 程序包 javax.servlet 不存在

    然后设置 Libraries,选择之前新建的 lib 目录

    配置打包方式 Artifacts,点击 Artifacts 选项卡

  3. 配置 tomcat

  4. 启动访问 http://localhost:8080/ssrf_Web_exploded/

漏洞分析

程序一个简单利用代码 Demo

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException 
		
			request.setCharacterEncoding("utf-8");
			response.setContentType("text/html;charset=utf-8");

			PrintWriter print = response.getWriter();
			String url = request.getParameter("url");
			String htmlContent;
			try 
				URL u = new URL(url);
				URLConnection urlConnection = u.openConnection();
				HttpURLConnection httpUrl = (HttpURLConnection) urlConnection;
				BufferedReader base = new BufferedReader(new InputStreamReader(httpUrl.getInputStream(), "UTF-8"));
				StringBuffer html = new StringBuffer();
				while ((htmlContent = base.readLine()) != null) 
					html.append(htmlContent);
				
				base.close();
				print.println("<b>端口探测</b></br>");
				print.println("<b>url:" + url + "</b></br>");
				print.println(html.toString());
				print.flush();
			 catch (Exception e) 
				e.printStackTrace();
				print.println("ERROR!");
				print.flush();
			
		

  1. URL 对象用 openConnection 打开连接,获取 URLConnection 类对象
  2. 用 InputStream 获取字节流
  3. 然后用 InputStreamReader 将字节流转换成字符流
  4. BufferedReader 将字符流以缓存形式输出的方式来获取网络数据流,
  5. 最后一行行输出到浏览器

这样就通过发送 http 请求来发起内网 ssrf 攻击

如果端口没有开启 http/https 服务,则会返回ERROR字符,通过返回结果判断是否开放端口,特别注意的是不像 PHP 可以通过 dict 伪协议一样可以判断所有端口服务,这里只能判断 http 服务是否开启

其他利用方式

任意文件读取/下载

在刚才的代码基础上删除画框的行

HttpURLconnection() 是基于 http 协议的,删除后可以使用 file 协议去读取文件,文件下载也一样不过是将数据流写入了文件中

敏感函数

Java 代码审计中要注意的可能会触发 ssrf 的敏感函数如下

HttpClient.execute()
HttpClient.executeMethod()
HttpURLConnection.connect()
HttpURLConnection.getInputStream()
URL.openStream()
HttpServletRequest()
getParameter()
URL
HttpClient()
Request(HttpClient封装后的类)
HttpURLConnection()
URLConnection()
okhttp()
BasicHttpEntityEnclosingRequest()
DefaultBHttpClientConnection()
BasicHttpRequest()

参考

panda 师傅博客

Java 代码审计入门篇

以上是关于Java代码审计之路二(SSRF漏洞审计)的主要内容,如果未能解决你的问题,请参考以下文章

JAVA代码审计之SSRF

Java代码审计之路一(OFCMS)

Java代码审计之路一(OFCMS)

JAVA代码审计之WebGoat靶场SQL注入

kali系统之复现漏洞分析与审计

PHP代码审计18—PHP代码审计小结