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

    image-20220502150630492

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

    选择第二项,导入 Eclipse 项目

    image-20220502150723862

    然后一路 next 即可

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

  2. 配置项目

    打开 Project Structure 窗口

    image-20220502150810832

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

    image-20220502150944208

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

    image-20220502155535586

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

    image-20220502151428716

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

    image-20220502151921221

  3. 配置 tomcat

    image-20211101193508748

  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. 最后一行行输出到浏览器

image-20220502160457888

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

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

其他利用方式

任意文件读取/下载

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

image-20220502161626745

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 代码审计入门篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OceanSec

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值