前情提要
某天上班的时候,群里发了份客户的漏洞通报,系统是NC
,漏洞类型写的是任意文件读取漏洞,漏洞url
为/uapws/service/nc.itf.bd.crm.IPsndocExportToCrmService
,参数为xsd
,传递了一个远程文件地址,文件类型为xml
。
虽然这里写的是任意文件读取,但是我一眼就看出这应该是xxe
漏洞,读取远程xml
文件进行文件读取。
在本地找一下有没有相关信息,发现之前提交过U8cloud
的该接口存在SQL
注入,如此看来这个可能是多个产品的通用漏洞,url
是相同的,是一个wsdl
接口。
漏洞分析
先来看看这个远程xml
文件,内容如下,是一个简单的xxe
利用脚本,读取C:/Windows/win.ini
文件。
在源码中找一下接口相关代码,只有一个接口和一个wsdl
文件,解析下来也只有一个exportPsndocToCrm
操作,也看不出个所以然,尤其是这个xsd
参数,更是不知道在哪处理的。
那就来复现这个洞看看,我们传递参数xsd
,没有给出值,发现系统报错,同时将调用栈也泄露了出来,这样不就好分析多了嘛。
简单看了一下调用栈,那就按顺序来分析,从ServletController
开始
这里会判断是否存在wsdl
参数,然后判断xsd
参数,进入不同的处理类,这里进入XSDQueryHandler
。
进入XSDQueryHandler#writeOutput
方法。
进入this.getDocument()
方法。
到这里就很明确了,这里的this.doc
就是创建XSDQueryHandler
对象时的第二个参数,即xsd
的值,然后调用rml.resolve(uri)
进行解析。
这里的rml
,经过分析,为URLISResolver
,该类的resolve
方法就是发起http
请求获取响应。再回到getDocument()
,就是发起远程http
请求获取响应,然后调用XMLs.getParser().parse()
进行解析,就造成了xxe
漏洞。
自此,分析结束。如此看来,该漏洞与IPsndocExportToCrmService
并无关系,该类只是调用wsdl
解析的一条路径,只要是wsdl
都存在该漏洞,问题是出在底层的工具处理类。
例如,我们随机挑选另一个wsdl
接口进行利用,同样也存在该漏洞。
漏洞修复
按理说,修复该漏洞,应该修改nc.uap.ws.query.XSDQueryHandler#getDocument()
方法,换为安全的xml
解析类。
但是厂商修复该漏洞,进行复测的时候发现,当我们传入http://url/win.xml
的时候,报错空指针,最后调用的方法为ServletController.invoke(ServletController.java:71)
但是当我们传入本地xsd
文件时,是可以正常解析的。
这里将xsd
路径改一下,ServletController
报错的行数为81
,而我们传入http
协议的报错行数为71
,也就是说在调用解析之前,就被拦截退出了,说明可能存在对http
的检测,经过测试发现只要以http
开头都不会进行后续的流程。
既然如此,那就说明可能仍然存在漏洞,只是有一个简单的拦截,那就来绕过补丁。
由于该系统为java
语言,这里发起请求的方式为new URL(resourceUri)
,那么我们可以在地址前面加上url:
来进行绕过。
成功绕过,读到了文件,这修复方式真的一言难尽。
原文始发于微信公众号(TERRA星环安全团队):一次漏洞通报下的某友xxe漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论