Java 审计之SSRF篇
Java 审计之SSRF篇
0x00 前言
本篇文章来记录一下Java SSRF的审计学习相关内容。
0x01 SSRF漏洞详解
原理:
服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。
大部分的web服务器架构中,web服务器自身都可以访问互联网和服务器所在的内网。
ssrf作用:
对外网服务器所在的内网、本地进行端口扫描,获取一些服务的banner信息 。
攻击运行在内网或者本地的应用程序。
对内网web应用进行指纹识别,通过访问默认文件实现 。
攻击内外网的web应用。sql注入、struct2、redis等。
利用file协议读取本地文件等。
php ssrf中的伪协议:
file dict sftp ldap tftp gopher
Java ssrf 中的伪协议:
file ftp mailto http https jar netdoc
0x02 SSRF产生过程
在java中ssrf会分比较多的场景,不像PHP中那样支持各种伪协议都可以去直接使用。
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, HttpServletResponse response) throws ServletException, 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();
}
}
在代码中HttpURLConnection httpUrl = (HttpURLConnection) urlConnection;,这个地方进行了强制转换,去某度搜索了一下具体用意。得出结论:
URLConnection:可以走邮件、文件传输协议。
HttpURLConnection 只能走浏览器的HTTP协议
也就是说使用了强转为HttpURLConnection后,利用中只能使用http协议去探测该服务器内网的其他应用。
http://localhost:8080/ssrfServlet?url=http://www.baidu.com

这里用来百度来做一个演示,因为懒得自己再在内网中搭建一个环境了。
在代码中,我们未对接收过来的url进行校验,校验其url是否是白名单的url就直接进行了创建url对象进行访问和读取资源,导致了ssrf的产生。
尝试一下能不能读取文件

这里会发现根本读取不了,因为这里只支持http和https的协议。
下面来试试,在不强制转换成HttpURLConnection的情况下试试。
代码如下:
@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, HttpServletResponse response) throws ServletException, 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

可以成功读取到c:\windows\win.ini的文件。
SSRF中的读取文件
代码如下:
@WebServlet("/readfileServlet")
public class downloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 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, 0, len);
}
}
}
和上面的代码对比一下,发现其实都大致相同,唯一不同的地方是一个是用openStream方法获取对象,一个是用openConnection获取对象。两个方法类似。
官方说明文档:
openConnection():返回一个实例,该实例表示与所引用的远程对象的连接。 返回类型: URLConnection
openStream():打开与此连接,并返回一个值以从该连接读取。 返回类型: InputStream
详细说明:
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。
这里启动一下服务器,测试一下。
http://127.0.0.1:8080//downloadServlet?url=file:///C:%5c%5c1.txt
注意: 这里是三个斜杆,并且反斜杠需要url编码 否则就会报错

未经过url编码直接传入反斜杠

SSRF中的文件下载
漏洞代码:
@WebServlet("/downloadServlet")
public class downloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 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, 0, len);
}
}
}
输入:
http://localhost:8080/downloadServlet?url=file:///c:%5c%5c1.txt

这样就把文件给下载下来了,ssrf中的文件下载和文件读取不同点在于响应头。
response.setHeader("content-disposition", "attachment;fileName=" + filename);
这段代码,设置mime类型为文件类型,访问浏览器的时候就会被下载下来。
参考文章
https://xz.aliyun.com/t/2761#toc-1
https://xz.aliyun.com/t/206/
https://xz.aliyun.com/t/7186
0x03 结尾
SSRF的一些产生也不止文章里面写到的这么一点,包括一些第三方的组件,如果在未经过验证的情况下发起一个远程请求,那么都有可能存在SSRF漏洞。
后面打算找套源码专门审计一下SSRF。
Java 审计之SSRF篇的更多相关文章
- Java审计之XSS篇
Java审计之XSS篇 0x00 前言 继续 学习一波Java审计的XSS漏洞的产生过程和代码. 0x01 Java 中XSS漏洞代码分析 xss原理 xss产生过程: 后台未对用户输入进行检查或过滤 ...
- Java 审计之XXE篇
Java 审计之XXE篇 0x00 前言 在以前XXE漏洞了解得并不多,只是有一个初步的认识和靶机里面遇到过.下面来 深入了解一下该漏洞的产生和利用. 0x01 XXE漏洞 当程序在解析XML输入时, ...
- Java审计之SQL注入篇
Java审计之SQL注入篇 0x00 前言 本篇文章作为Java Web 审计的一个入门文,也是我的第一篇审计文,后面打算更新一个小系列,来记录一下我的审计学习的成长. 0x01 JDBC 注入分析 ...
- Java审计之命令执行篇
Java审计之命令执行篇 0x00 前言 在Java中能执行命令的类其实并不多,不像php那样各种的命令执行函数.在Java中目前所知的能执行命令的类也就两种,分别是Runtime和 ProcessB ...
- Java审计之文件操作漏洞
Java审计之文件操作漏洞篇 0x00 前言 本篇内容打算把Java审计中会遇到的一些文件操作的漏洞,都给叙述一遍.比如一些任意文件上传,文件下载,文件读取,文件删除,这些操作文件的漏洞. 0x01 ...
- 漏洞经验分享丨Java审计之XXE(下)
上篇内容我们介绍了XXE的基础概念和审计函数的相关内容,今天我们将继续分享Blind XXE与OOB-XXE的知识点以及XXE防御方法,希望对大家的学习有所帮助! 上期回顾 ◀漏洞经验分享丨Java ...
- 漏洞经验分享丨Java审计之XXE(上)
最近在审计公司的某个项目时(Java方面),发现了几个有意思的Blind XXE漏洞,我觉得有必要分享给大家,尤其是Java审计新手,了解这些内容可以让你少走一些弯路. Java总体常出现的审计漏洞如 ...
- Java多线程系列--“基础篇”11之 生产消费者问题
概要 本章,会对“生产/消费者问题”进行讨论.涉及到的内容包括:1. 生产/消费者模型2. 生产/消费者实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p ...
- Java多线程系列--“基础篇”04之 synchronized关键字
概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...
随机推荐
- 【POJ2976】Dropping tests - 01分数规划
Description In a certain course, you take n tests. If you get ai out of bi questions correct on test ...
- error PRJ0003 : 生成“cmd.exe”时出错 2010-01-19 22:26
今天用vs2005编译时代码时竟然出现了error PRJ0003 : 生成“cmd.exe”时出错这样的错误,这不是刺激我吗,我们先看msdn的解释吧. 错误消息 生成“command line”时 ...
- 在.NET Core中使用MongoDB明细教程(2):使用Filter语句检索文档
在上篇文章我们介绍了一些驱动程序相关的基础知识,以及如何将文档插入到集合中.在这篇文章中,我们将学习如何从数据库中检索文档. 作者:依乐祝 译文地址:https://www.cnblogs.com/y ...
- 虚拟化技术之kvm磁盘管理工具qemu-img
在前边的博客中,我们大致了解了virsh这个工具对kvm虚拟机的一些操作,回顾请参考https://www.cnblogs.com/qiuhom-1874/tag/virsh/:今天我们来了解下kvm ...
- CSS动画实例:太极图在旋转
利用CSS可以构造出图形,然后可以对构造的图形添加动画效果.下面我们通过旋转的太极图.放大的五角星.跳“双人舞”的弯月等实例来体会纯CSS实现动画的方法. 1.旋转的太极图 设页面中有<div ...
- 第2章 执行SparkSQL查询
第2章 执行SparkSQL查询 2.1 命令行查询流程 打开Spark shell 例子:查询大于30岁的用户 创建如下JSON文件,注意JSON的格式: {"name":&qu ...
- vscode下终端返回中文乱码
用python写个爬虫,配置个VScode环境,发现输出都是乱码,翻阅网站后发现一个简单有效的方法,在此谢过网络上的大牛们的无私分享,我也在此记录一下,以备后用: 文件---->首选项----& ...
- ImportError: No module named git
问题:ImportError: No module named git 解决:yum install GitPython
- 启用valgrind的MPI支持
TL;DR sudo apt install valgrind-mpi 内存泄漏和越界问题,是C/C++程序常见问题.有一些工具提供了检测内存泄漏的功能,如 valgrind 的 memchecker ...
- 【Flutter 实战】动画序列、共享动画、路由动画
老孟导读:此篇文章是 Flutter 动画系列文章第四篇,本文介绍动画序列.共享动画.路由动画. 动画序列 Flutter中组合动画使用Interval,Interval继承自Curve,用法如下: ...