案例一:Discuz论坛SSRF漏洞
复现版本:Discuz! X3.1 Release 20150609
discuz有一个下载远程图片的ajax接口,该接口对用户传入的图片URL校验不严格导致SSRF漏洞。
将远程图片的URL构造为:http://45.xx.xx.60:8080/ssrf.php?765.jpg,当网站服务器访问ssrf.php时被302重定向到内网服务器,从而导致SSRF漏洞。
漏洞证明:
漏洞触发点在/source/module/forum/forum_ajax.php文件中,开发者使用dfsockopen()函数加载远程图片,但没有对图片URL严格检查。
dfsockopen()函数优先使用curl库加载图片,并且设置了CURLOPT_FOLLOWLOCATION,可利用http 302跳转绕过“http://”前缀限制。
修复方法
1、取消curl的CURLOPT_FOLLOWLOCATION选项,禁止302跳转。
2、利用curl加载图片前对URL进行严格判断,具体来说就是先利用parse_url()函数解析图片URL,然后判断是否是http协议或https协议,如果不是这两种被允许的协议则终止程序;再判断URL中域名部分是IP形式还是域名形式,如果是IP形式,则不允许内网IP;如果是域名,则通过gethostbyname()函数获取DNS解析记录,然后判断DNS解析记录是否是内网IP。最后在设置CURLOPT_URL时要优先设置成IP形式的URL,并且要把http请求头中的Host字段设置为刚才parse_url()函数解析出来的host,这样可以避免DNS重绑定(DNS ReBinding)攻击。
3、限制http协议和https协议的端口,如:只允许80、443、8080等端口。
案例二:UEditor编辑器SSRF漏洞
复现版本:UEditor 1.4.3 JSP版
UEditor有个catchimage的接口,通过这个接口可下载远程图片,但开发者没有对用户传入的图片URL进行严格检查导致SSRF漏洞。
漏洞证明:
漏洞触发的入口在srccomaiduueditorActionEnter.java文件中,当action=catchimage时开始捕获远程图片。
list是用户传入的图片URL,capture()方法实际上是调用了captureRemoteData()方法,具体代码如下:
开发者先用validHost()方法检测图片URL中的host是否合法,然后再通过HttpURLConnection加载URL,validHost()方法具体代码如下:
validHost()方法只判断hostname是否是127.0.0.1、localhost或img.baidu.com,如果不是这三者则返回true。
此处对图片URL的检测过于宽松,可对内网192.168.x.x网段、172.16.x.x网段等进行信息刺探。
修复方法
在UEditor 1.4.3.1版本中开发者修改了validHost()方法,加强了对图片URL的检测,但可通过http 302跳转的方式绕过检测。