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 ...
随机推荐
- Mybatis如何在插入(ID是后台生成的)后返回ID?
获得ID方法:
- IE9知识点汇总
1.首先ie9不支持flex布局,只能使用float,要想支持ie低版本,两者要同时使用. 2.input框不支持placeholder属性,只能自己加span标签模拟出来,调整样式. 3.单个css ...
- 数据隐私和GDPR
近十几年来,随着大数据给各行各业带来的变化,以及数据时代不断强调的数据就是燃料,谁掌握数据谁就掌握未来的各种论调,大家纷纷开始收集数据,挖掘数据,转卖数据.而个人,作为数据真正拥有者的利益早就在商业利 ...
- muduo源码解析11-logger类
logger: class logger { }; 在说这个logger类之前,先看1个关键的内部类 Impl private: //logger内部数据实现类Impl,内部含有以下成员变量 //时间 ...
- 标准git请求
initCate() // 定义加载文章分类的方法 function initCate() { $.ajax({ method: 'GET', url: '/my/article/cates', su ...
- 焦大:seo思维光年(下)seo操作如何度量化
http://www.wocaoseo.com/thread-57-1-1.html 如果不能度量就无法进行改进,所以度量化或数据化是网站分析和网站研究必须进行的一个方面,seo也不能例外.我在上篇文 ...
- CSP 201312-1 出现次数最多的数
思路 由于输入的数组元素是 1 ≤ si ≤ 10000,所以开一个 10001 的数组.输入的过程中使用 num 记录出现的最大次数: 在所有输入结束后,遍历数组元素,由于题目要求出现多个众数输出最 ...
- C语言如何动态分配二维数组
C语言如何动态分配二维数组(转载) 原文链接:https://www.cnblogs.com/0xWitch/p/9314621.html 使用malloc().free()函数进行动态分配,这两个函 ...
- Qt QString字符串分割、截取
在做项目中不可避免的会使用到一串字符串中的一段字符,因此常常需要截取字符串. 有两种方式可以解决这个问题: 方法一:QString分割字符串: QString date=dateEdit.toStri ...
- 创建一个springbootcloud项目
nacos:服务治理 fegin:负载均衡 sentinel:分布式系统的流量防卫兵 sleuth+zipkin:链路追踪 前提软件安装 nacos: github下载地址:https://githu ...