Apache Solr XXE漏洞分析 -【CVE-2018-8026】
环境搭建
这次的XXE漏洞依赖于SolrCloud API,影响到SolrCloud分布式系统。而SolrCloud需要用到zookeeper。
zookeeper
在 zookeeper文件夹下:
修改 conf\zoo.cfg中的dataDir和clientPort,以我为例:
然后启动服务
solr
solr受影响版本: 6.6.4, 7.3.1
solr的具体搭建过程不详细说明。通过ant idea等一系列编译可以搭建idea环境。最后启动solr服务时如下,其中-DzkHost=localhost即上面配置zookeeper的clientPort:
漏洞复现
附上最简单的脚本evil.py,其中evil.zip见文章附件:
还有外部实体xxe.dtd,如下用于读取存放在C盘根目录下的chybeta.txt文件:
如下图,8000服务器用于提供xxe.dtd,8888服务器用于接受xxe传送出来的结果

关于XXE的攻击方式等知识不妨参考小试XML实体注入攻击
漏洞分析
XXE 1
第一步是需要去上传ConfigSet,根据Upload a ConfigSet,这一步是将几个xml文件打包成压缩包后上传,其中 schema.xml内容为:
currency.xml为:
还有一个solrconfig.xml,其内容在此省略。
考虑到是xxe,因此主要来看在何处发生了xml外部实体的解析。当开始第二个请求solr/admin/collections?action=CREATE时,solrcloud将根据指定的collection.configName即上一步上传的evilconfig来进行创建Collections。
org/apache/solr/schema/FileExchangeRateProvider.java:245
跟进reload,到达
org/apache/solr/schema/FileExchangeRateProvider.java:159,此时变量如下

代码如下:
currencyConfigFile即前面的currency.xml,
通过is = loader.openResource(currencyConfigFile);读取了内容后,在最后把is对象传给了dbf。在dbf.newDocumentBuilder().parse(is);解析了外部实体,造成了xxe。

XXE 2
同样发生在对schema.xml的解析中,我们修改schema.xml的内容如下:
enumsConfig.xml内容为:
将schema.xml,enumsConfig.xml和solrconfig.xml打包成zip后,用上面的脚本执行。当solr运行至 org/apache/solr/schema/AbstractEnumField.java:90

接着在 org/apache/solr/schema/AbstractEnumField.java:110
同样由于dbf.newDocumentBuilder().parse(is)造成了外部实体的解析
补丁分析
针对 XXE 1 和 XXE 2 的补丁为 SOLR-12450.patch
其中增加了solr/core/src/java/org/apache/solr/util/SafeXMLParsing.java,其中定义了多种解析xml的方法。比如parseConfigXML:
对应的FileExchangeRateProvider.java也换成了:
AbstractEnumField.java则为