逛啊逛逛github,逛到1day分析下~最近发现几个有趣的java-xxe的cve,于是进行了一波研究
0x00 前言
这两天在github逛漏洞情报的时候,发现几个组件存在有趣的java-xxe漏洞,这些漏洞都存在相同的特点,就是在xml进行解析的过程中缺少了某些安全配置Feature
例:saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
以下内容便是对两个相关的漏洞进行分析
0x01 Hazelcast XXE漏洞(CVE-2022-0265)
漏洞描述
Hazelcast(Hazelcast IMDG)是美国Hazelcast公司的一套可扩展的开源数据分发平台。该平台支持多种分布式数据结构,支持分布式缓存等功能。
AbstractXmlConfigRootTagRecognizer()
函数使用从没有设置 FEATURE_SECURE_PROCESSING
的SAXParserFactory
生成的 SAXParser
,从而允许XXE攻击。
影响版本
Hazelcast < 5.1
环境搭建
首先通过漏洞描述和漏洞源码可以看到,该漏洞触发点是由于com.hazelcast.internal.config.AbstractXmlConfigRootTagRecognizer
类中存在直接调用jdk中默认存在的不安全的方法:
javax.xml.parsers.SAXParser
和javax.xml.parsers.SAXParserFactory
通过对以上不安全方法提取出来做poc验证,得到
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(new ByteArrayInputStream(xmlpoc.getBytes()), new HandlerBase());
以上该示例仅通过ssrf的方式去验证存在xxe漏洞
漏洞分析
poc中先是通过SAXParserFactory
实例化了个SAXParser
对象,接着在对象的parse
方法中执行了我们恶意的xxe语句,所以就从saxParser.parse
开始断点分析即可
这里的this
不再是saxParser
,而是将恶意xxe的byte流带入到SAXParserImpl.parse
方法中,而当中HandlerBase
相当于一个xml的解析器,其中以下setDTDHandler
方法向SAX解析器注册一个实例,是为了去解析咱们恶意xxe
继续跟踪到其父类的AbstractSAZParser.parse
方法中,先是将xxe的byte流等内容赋给新创建的XMLInputSource
对象,再调用XMLParser.parse
方法
跟踪,可以看到fFeatures
即XML解析器的安全配置。因为XML解析器有时需要去解析外部传入的XML文件,如果没有做特殊处理,大多会解析XML文件中的外部实体。 如果外部实体包含URI,那么XML解析器会访问URI指定的资源,例如本地或者远程系统上的文件。为了防止以上恶意操作,所以就有了xml解析器安全配置的存在
经过以上过滤,最后会来到XML11Configuration.parser
方法中准备开始xml解析操作
直到XMLDocumentScannerImpl.startEntity
才完成解析xml
调用栈如下:
startEntity:529, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
startEntity:1327, XMLEntityManager (com.sun.org.apache.xerces.internal.impl)
startEntity:1240, XMLEntityManager (com.sun.org.apache.xerces.internal.impl)
scanEntityReference:1908, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
next:3061, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
next:602, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanDocument:505, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
parse:841, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:770, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:1213, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
parse:643, SAXParserImpl$JAXPSAXParser (com.sun.org.apache.xerces.internal.jaxp)
parse:342, SAXParserImpl (com.sun.org.apache.xerces.internal.jaxp)
parse:139, SAXParser (javax.xml.parsers)
main:14, cve_2022_0265 (vultest)
补丁分析
补丁链接:https://github.com/hazelcast/hazelcast/commit/4d6b666cd0291abd618c3b95cdbb51aa4208e748
从补丁可以看到hazelcast换了个xml的解析器
并添加了FEATURES_DISALLOW_DOCTYPE
安全配置,不允许使用DOCTYPE
通过补丁,我们修改poc以进行验证
SAXParser saxParser = XmlUtil.getSAXParserFactory().newSAXParser();
saxParser.parse(new ByteArrayInputStream(xmlpoc.getBytes()), new HandlerBase());
可以看到已经不允许解析DOCTYPE
文档类型的内容了
0x02 Liquibase XXE 漏洞(CVE-2022-0839)
漏洞描述
Github liquibase是用于跟踪、版本和部署数据库架构更改。
liquibase 存在安全漏洞,该漏洞源于 XML 外部实体引用限制不当。
影响版本
Liquibase < 4.8.0
环境搭建
首先从漏洞描述先来看到漏洞源码处,可以看到在实例化解析日志XMLChangeLogSAXParser
所构造的SAXParser
解析器之后,在解析xml获取parser时并未设置安全Feature
,直接将inputStream流带入parse进行解析导致XXE
以下给出验证poc:
XMLChangeLogSAXParser xmlChangeLogSAXParser = new XMLChangeLogSAXParser();
HashMap hashMap = new HashMap<String, String>();
hashMap.put("com/test/cve_2022_0839.xml",POC);
MockResourceAccessor resourceAccessor = new MockResourceAccessor(hashMap);
xmlChangeLogSAXParser.parse("com/test/cve_2022_0839.xml", new ChangeLogParameters(),resourceAccessor);
poc验证效果如下:
漏洞分析
关于poc中所要传入的东西就不说明了,请看这儿~
ParsedNode parseToNode(String physicalChangeLogLocation, ChangeLogParameters changeLogParameters, ResourceAccessor resourceAccessor)
接着让我们看看它在解析xml的过程前是不是没有配置相应的安全配置Feature
在调试过程中我们发现,首先来到XMLChangeLogSAXParser
其父类AbstractChangeLogParser.parse
方法中,看到了我们传进去所需要的东西
this.parseToNode
将跳回XMLChangeLogSAXParser.parseToNode
方法中,进行解析器实例化,并且做了相关配置,在执行对poc解析过程中我们来看看现在的解析器有哪些features
从上述features
中我们可以看到,并没有存在相对于攻击者来说过分的安全配置,例如FEATURES_DISALLOW_DOCTYPE、FEATURE_SECURE_PROCESSING
等,这将极易导致存在xxe漏洞的出现和利用,既然漏洞原因和利用入口点是出自xml解析器缺少安全配置,那么后面xml的解析过程不做过多分析了,因为到这里也就可以发现后续调用栈和前一个漏洞是类似的了
该漏洞利用调用栈如下:
.....
parse:777, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:1213, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
parse:649, SAXParserImpl$JAXPSAXParser (com.sun.org.apache.xerces.internal.jaxp)
parseToNode:89, XMLChangeLogSAXParser (liquibase.parser.core.xml)
parse:15, AbstractChangeLogParser (liquibase.parser.core.xml)
main:30, cve_2022_0839 (vultest)
补丁分析
通过diff可以看到在XMLChangeLogSAXParser.java
处补充了feature
和property
等安全配置以进行过滤
现在我们将liquibase
换成更新后的版本,可以看到features
确实多了关于xml解析的安全配置FEATURE_SECURE_PROCESSING
0x03 总结
1、在java安全开发中若需要用到对xml进行解析的话,应考虑xml组件默认有没有禁用外部实体引用或者其他安全问题,针对补充安全配置以防止功能点在引用到不安全的xml解析器的时候引发一系列的安全问题
2、话说,这不就多了一种挖掘cve的道路吗
- 本文作者: w1nk1
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1419
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!