java代码审计-ssrf漏洞

华盟原创文章投稿奖励计划

java代码审计-ssrf漏洞

0x00 前言

SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定 URL 地址获取网页文本内容,加载指定地址的图片,下载等等。这里主要介绍java中URLConnection()和openStream()两个方法产生SSRF的原理和修复方法

0x01 URLConnection

@RequestMapping(value = "/urlConnection/vuln", method = {RequestMethod.POST, RequestMethod.GET}) public String URLConnectionVuln(String url) { return HttpUtils.URLConnection(url);
    }

这里调用的是HttpUtils.URLConnection(url)

public static String URLConnection(String url) { try { URL u = new URL(url); URLConnection urlConnection = u.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); //send request // BufferedReader in = new BufferedReader(new InputStreamReader(u.openConnection().getInputStream())); String inputLine; StringBuilder html = new StringBuilder(); while ((inputLine = in.readLine()) != null) {
                html.append(inputLine);
            }
            in.close(); return html.toString();
        } catch (Exception e) {
            logger.error(e.getMessage()); return e.getMessage();
        }
    }

跟进URLConnection方法,而URLConnection里又调用了URL.openConnection()来发起请求, 这个请求可以直接执行url协议(伪协议)
漏洞利用:
使用file协议读文件
java代码审计-ssrf漏洞
使用http协议访问百度
java代码审计-ssrf漏洞
修复方法:
这里先是对url调用了SecurityUtil.isHttp()来进行检查

@GetMapping("/urlConnection/sec") public String URLConnectionSec(String url) { // Decline not http/https protocol if (!SecurityUtil.isHttp(url)) { return "[-] SSRF check failed";
        } try {
            SecurityUtil.startSSRFHook(); return HttpUtils.URLConnection(url);
        } catch (SSRFException | IOException e) { return e.getMessage();
        } finally {
            SecurityUtil.stopSSRFHook();
        }

    }

SecurityUtil.isHttp()比较简单,就是判断url是否是以http://或https://开头

public static boolean isHttp(String url) { return url.startsWith("http://") || url.startsWith("https://");
    }

单纯的ban掉其他协议显然是不够的,还不能够防止对内网进行探测,于是在获取url内容之前,开启了一个hook来对用户行为进行监听,SecurityUtil.startSSRFHook(),就有效防止了ssrf攻击

0x02 openStream

openStream()方法的实现也是调用了openConnection生成一个URLConnection 对象,然后再通过这个对象调用的getInputStream()方法的

@GetMapping("/openStream") public void openStream(@RequestParam String url, HttpServletResponse response) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { String downLoadImgFileName = WebUtils.getNameWithoutExtension(url) + "." + WebUtils.getFileExtension(url); // download response.setHeader("content-disposition", "attachment;fileName=" + downLoadImgFileName); URL u = new URL(url); int length; byte[] bytes = new byte[1024];
            inputStream = u.openStream(); // send request outputStream = response.getOutputStream(); while ((length = inputStream.read(bytes)) > 0) {
                outputStream.write(bytes, 0, length);
            }

        } catch (Exception e) {
            logger.error(e.toString());
        } finally { if (inputStream != null) {
                inputStream.close();
            } if (outputStream != null) {
                outputStream.close();
            }
        }
    }

通过WebUtils.getNameWithoutExtension(url) + "." + WebUtils.getFileExtension(url)来获取下载文件名,然后执行inputStream = u.openStream(); 来看一下openStream(),也是调用了openConnection(),也会根据传入的协议的不同来进行处理

public final InputStream openStream() throws java.io.IOException { return openConnection().getInputStream();
    }

由此可以得知,openStream()方法同样也可以进行ssrf来探测内网以及文件下载,修复方案同上

0x03 总结

关键词:
URLConnection、openConnection、openStream
漏洞利用:
关于SSRF漏洞利用相关可以看这篇文章,总结的很详细!
从一文中了解SSRF的各种绕过姿势及攻击思路


原文地址:https://www.cnblogs.com/Ne2o1/p/17192112.html

黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!

如侵权请私聊我们删文


END

java代码审计-ssrf漏洞

本文来源https://www.cnblogs.com/Ne2o1/p/17192112.html,经授权后由华盟君发布,观点不代表华盟网的立场,转载请联系原作者。

发表回复