URLConnection()和openStream()两个方法产生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协议读文件
使用http协议访问百度
修复方法:
这里先是对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的各种绕过姿势及攻击思路


供热锅炉能源审计物联网云管理系统
虹科Safran与安立Anritsu合作推出C-V2X PC5通信功能验证方案
Nvidia 通过开源库提升 LLM 推理性能
如何设计出一种可以自我调整的共识协议
电压比较器能替代运算放大器用吗
URLConnection()和openStream()两个方法产生SSRF的原理和修复方法
阻碍区块链技术发展的因素有哪些
中国移动将全面排查骚扰电话等问题并实施整改
SiC MOSFET相对于Si MOSFET和IGBT的优势
输电线路安装导线耐张线夹在线测温装置的重要性
华大HC32F460 HC32F4A0加速程序运行速度
中国实现自给自足,多晶硅厂商瓦克化学销量跌至历史新低
CQC认证如何询价?
如何选购蓝光芯片
手机行业正在酝酿着一场防水技术革新风暴
光子集成电路的发展方向解读
我们常用的电阻器和电容器的标称值有哪些
印度智能手机“M-6700”与安卓手机“Racer”的基板比较分析
区块链中常见的10种共识机制介绍
安规电容炸裂的原因有哪些