关于SAXParser未做安全配置所引发的安全漏洞分析

逛啊逛逛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_PROCESSINGSAXParserFactory生成的 SAXParser,从而允许XXE攻击。

1.png

影响版本

Hazelcast < 5.1

环境搭建

首先通过漏洞描述和漏洞源码可以看到,该漏洞触发点是由于com.hazelcast.internal.config.AbstractXmlConfigRootTagRecognizer类中存在直接调用jdk中默认存在的不安全的方法:
javax.xml.parsers.SAXParserjavax.xml.parsers.SAXParserFactory

2.png

通过对以上不安全方法提取出来做poc验证,得到

SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(new ByteArrayInputStream(xmlpoc.getBytes()), new HandlerBase());

以上该示例仅通过ssrf的方式去验证存在xxe漏洞

3.png

漏洞分析

poc中先是通过SAXParserFactory实例化了个SAXParser对象,接着在对象的parse方法中执行了我们恶意的xxe语句,所以就从saxParser.parse开始断点分析即可

4.png

这里的this不再是saxParser,而是将恶意xxe的byte流带入到SAXParserImpl.parse方法中,而当中HandlerBase相当于一个xml的解析器,其中以下setDTDHandler方法向SAX解析器注册一个实例,是为了去解析咱们恶意xxe

5.png

继续跟踪到其父类的AbstractSAZParser.parse方法中,先是将xxe的byte流等内容赋给新创建的XMLInputSource对象,再调用XMLParser.parse方法

6.png

跟踪,可以看到fFeatures即XML解析器的安全配置。因为XML解析器有时需要去解析外部传入的XML文件,如果没有做特殊处理,大多会解析XML文件中的外部实体。 如果外部实体包含URI,那么XML解析器会访问URI指定的资源,例如本地或者远程系统上的文件。为了防止以上恶意操作,所以就有了xml解析器安全配置的存在

7.png

经过以上过滤,最后会来到XML11Configuration.parser方法中准备开始xml解析操作

8.png

直到XMLDocumentScannerImpl.startEntity才完成解析xml

9.png

调用栈如下:

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的解析器

10.png

并添加了FEATURES_DISALLOW_DOCTYPE安全配置,不允许使用DOCTYPE

11.png

通过补丁,我们修改poc以进行验证

SAXParser saxParser = XmlUtil.getSAXParserFactory().newSAXParser();
saxParser.parse(new ByteArrayInputStream(xmlpoc.getBytes()), new HandlerBase());

可以看到已经不允许解析DOCTYPE文档类型的内容了

12.png

0x02 Liquibase XXE 漏洞(CVE-2022-0839)

漏洞描述

Github liquibase是用于跟踪、版本和部署数据库架构更改。
liquibase 存在安全漏洞,该漏洞源于 XML 外部实体引用限制不当。

影响版本

Liquibase < 4.8.0

环境搭建

首先从漏洞描述先来看到漏洞源码处,可以看到在实例化解析日志XMLChangeLogSAXParser所构造的SAXParser解析器之后,在解析xml获取parser时并未设置安全Feature,直接将inputStream流带入parse进行解析导致XXE

a.png

以下给出验证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验证效果如下:

b.png

漏洞分析

关于poc中所要传入的东西就不说明了,请看这儿~

ParsedNode parseToNode(String physicalChangeLogLocation, ChangeLogParameters changeLogParameters, ResourceAccessor resourceAccessor)

接着让我们看看它在解析xml的过程前是不是没有配置相应的安全配置Feature
在调试过程中我们发现,首先来到XMLChangeLogSAXParser其父类AbstractChangeLogParser.parse方法中,看到了我们传进去所需要的东西

c.png

this.parseToNode将跳回XMLChangeLogSAXParser.parseToNode方法中,进行解析器实例化,并且做了相关配置,在执行对poc解析过程中我们来看看现在的解析器有哪些features

d.png

从上述features中我们可以看到,并没有存在相对于攻击者来说过分的安全配置,例如FEATURES_DISALLOW_DOCTYPE、FEATURE_SECURE_PROCESSING等,这将极易导致存在xxe漏洞的出现和利用,既然漏洞原因和利用入口点是出自xml解析器缺少安全配置,那么后面xml的解析过程不做过多分析了,因为到这里也就可以发现后续调用栈和前一个漏洞是类似的了

e.png

该漏洞利用调用栈如下:

.....
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处补充了featureproperty等安全配置以进行过滤

f.png

现在我们将liquibase换成更新后的版本,可以看到features确实多了关于xml解析的安全配置FEATURE_SECURE_PROCESSING

g.png

0x03 总结

1、在java安全开发中若需要用到对xml进行解析的话,应考虑xml组件默认有没有禁用外部实体引用或者其他安全问题,针对补充安全配置以防止功能点在引用到不安全的xml解析器的时候引发一系列的安全问题
2、话说,这不就多了一种挖掘cve的道路吗

  • 发表于 2022-03-24 09:29:22
  • 阅读 ( 7924 )
  • 分类:漏洞分析

0 条评论

请先 登录 后评论
w1nk1
w1nk1

12 篇文章

站长统计