Java 审计之SSRF篇

Java审计之SSRF篇0x00前言本篇文章来记录一下JavaSSRF的审计学习相关内容。0x01SSRF漏洞详解原理:服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

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

Java 审计之SSRF篇

这里用来百度来做一个演示,因为懒得自己再在内网中搭建一个环境了。

在代码中,我们未对接收过来的url进行校验,校验其url是否是白名单的url就直接进行了创建url对象进行访问和读取资源,导致了ssrf的产生。

尝试一下能不能读取文件

Java 审计之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

Java 审计之SSRF篇

可以成功读取到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编码 否则就会报错

Java 审计之SSRF篇

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

Java 审计之SSRF篇

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

Java 审计之SSRF篇

这样就把文件给下载下来了,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。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119921.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm中使用anaconda部署python环境_anaconda pycharm环境配置

    pycharm中使用anaconda部署python环境_anaconda pycharm环境配置Pycharm使用anaconda环境(原环境base)注意本教程是针对使用anaconda的新手,添加的是anaconda自带的base环境!首先打开或者新建一个Python项目File->Settings->Project->PythonInterpreter,然后在右边PythonInterpreter看一下又没有anaconde的选项,如果有,就直接选中,然后就可以了,如果没有那就继续看下去.如果没有默认读取anaconda的选项,那

    2022年8月25日
    6
  • 手把手用keras分类mnist数据集

    实战流程获得数据,并将数据处理成合适的格式按照自己的设计搭建神经网络设定合适的参数训练神经网络在测试集上评价训练效果一、认识mnist数据集fromkeras.utilsimportto_categoricalfromkerasimportmodels,layers,regularizersfromkeras.optimizersimportRMSprop…

    2022年4月7日
    31
  • 教你用Python自制一张好看的指数估值图!这招很好用!

    教你用Python自制一张好看的指数估值图!这招很好用!对于以定投指数的方式理财的朋友 最需要关注的指标便是各个指数的估值 在指数低估时买入 高估时卖出 那如何制作一张估值图来跟踪指数的估值情况呢 本文就从 0 到 1 介绍如何用 Matplotlib 画一张漂亮的指数估值图 准备数据首先 准备我们需要的数据 一般来说 经历了一轮牛熊周期的历史估值更具比较意义 所以 这里以上证指数 2013 年到目前为止的行情数据为例进行演示 同时 采用滚动市盈率为估值指标 数据来源为 tushare importpandas

    2025年6月1日
    0
  • linux思维图集「建议收藏」

    linux思维图集「建议收藏」linux思维图集

    2022年4月22日
    30
  • RxJava(七) 使用 debounce 操作符优化 App 搜索功能[通俗易懂]

    RxJava(七) 使用 debounce 操作符优化 App 搜索功能[通俗易懂]RxJava系列文章目录导读:一、RxJavacreate操作符的用法和源码分析二、RxJavamap操作符用法详解三、RxJavaflatMap操作符用法详解四、RxJavaconcatMap操作符用法详解五、RxJavaonErrorResumeNext操作符实现app与服务器间token机制六、RxJavaretryWhen操作符…

    2022年6月20日
    34
  • python提取字符串中的数字「建议收藏」

    python提取字符串中的数字「建议收藏」一、isdigit()函数isdigit()函数是检测输入字符串是否只由数字组成。如果字符串只包含数字则返回True否则返回False。dream=”123456″print(dream.isdigit())#返回:Truedream=”123abc456″print(dream.isdigit())#返回:Falsedream=’abcd’print(dream.isdigit())#返回:False二、filter()函数说明:filter()函

    2022年10月10日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号