Apache-Solr-RCE(CNVD-2023-27598)漏洞原理分析
2023-04-23 14:35:00

0x00、前言

Apache-Solr-RCE(CNVD-2023-27598)复现与分析,核心跟着原作者分析文章进行复现和过程调试。

0x01、漏洞描述

Apache Solr是一个开源搜索服务引擎,Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。

在Apache Solr 受影响版本中,由于Solr默认配置下存在服务端请求伪造漏洞,且SolrResourceLoader中实现了java SPI机制。当Solr以SolrCloud模式启动时,攻击者可以通过构造恶意的solrconfig.xml文件,组合利用从而执行任意java代码。

0x02、漏洞范围

8.10.0 <= Apache Solr < 9.2.0

0x03、环境搭建

github源码:https://github.com/apache/solr/tags
(8系列使用ant ivy-bootstrap、ant idea构建导入idea即可、9系列使用gradle构建编译导入idea)

官方solr程序安装包,src后缀为源码,下载不带src后缀的即为编译好的程序运行包:
https://dlcdn.apache.org/lucene/solr/

运行方式:
进入安装包bin目录下

solr.cmd start -c -f -a "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:35005"
-c开启solrcloud模式,-f后台显示执行情况,-a调试参数(端口设置同idea一样)


将源码导入idea,开启远程调试就可以进行断点调试


0x04、漏洞复现

通过configset添加主题,name参数对应主题名,可自取

curl -X POST --header "Content-Type:application/octet-stream" --data-binary @conf.zip "http://ip:8983/solr/admin/configs?action=UPLOAD&name=lib9"

其中上传的压缩包可将默认配置进行打包成zip进行上传

伪造恶意jar包(注意依赖必须添加程序包中的lucene-codecs-8.11.2.jar、lucene-core-8.11.2.jar两个依赖包)

通过Idea添加控件生成恶意jar包

复制默认配置中的solrconfig.xml,修改solrconfig.xml文件,将恶意lib植入xml文件中

主机开启unc,将恶意jar放入路径中

修改主体solrconfig配置文件,name对应上传的主体名

curl -X POST --header "Content-Type:application/octet-stream" --data-binary @solrconfig.xml "http://192.168.43.233:8983/solr/admin/configs?action=UPLOAD&name=lib9&filePath=solrconfig.xml&overwrite=true"

上传完solrconfig.xml文件覆盖后,再新建主题

触发漏洞

0x05、原理分析

根据原作者分析思路,在通过configset上传主题时,将默认的demo进行上传,其中demo中自带了solrconfig.xml文件,创建后可直接创建主题


其中调试SchemaDesignerConfigSetHelper.loadSolrConfig方法创建solr资源加载器过后,读取资源会传入SOLR_CONFIG_XML获取的solrconfig.xml文件

跟进到SolrConfig.readFromResourceLoader方法,调用构造方法

从方法注释可以知道该构造方法是从资源加载器、配置名称和流创建配置实例

其中会创建资源提供器,其中会对solrconfig.xml文件从资源配置中获取

由于上传的默认配置中包含了默认的solrconfig.xml文件,因此能够在zookeeper中找到配置文件,如果上传的主题配置中删除了solrconfig.xml,则会抛出异常提示找不到solrconfig.xml文件

资源加载器创建好后,进入主要的initLibs方法初始化lib资源,由于默认配置中的solrconfig.xml中的lib标签未添加额外的,因此读取添加到加载器的步骤都会跳过。

因此重新覆盖solrconfig.xml文件,将恶意jar路径通过unc路径方式(windows环境下,并且将该目录的文件共享打开,使服务器能访问该主机)放置恶意solrconfig.xml中

curl -X POST --header "Content-Type:application/octet-stream" --data-binary @solrconfig.xml "http://192.168.43.233:8983/solr/admin/configs?action=UPLOAD&name=lib12&filePath=solrconfig.xml&overwrite=true"

上传后重新新建主题

此时initlibs获取到solrconfig.xml文件中的lib标签

再通过getFilteredURLs.getURLs方法去循环获取lib标签中的url值,获取url过程:



获取到url后,添加到url类加载器中


添加到加载器过后,调用reloadLuceneSPI方法进行重载SPI操作

加载PostingsFormats调用到NamedSPILoader.reload方法进行重载

先是获取SPI类迭代器,关联的类名为org.apache.lucene.codecs.PostingsFormat


接着从迭代加载器中获取/META-INF/services/org.apache.lucene.codecs.PostingsFormat文件名

写入到URL连接流中


再循环读取/META-INF/services/org.apache.lucene.codecs.PostingsFormat文件中的类名,添加到linesIterator


然后循环进行实例化操作

最后循环获取到构造恶意jar中/META-INF/services/org.apache.lucene.codecs.PostingsFormat文件名下的恶意类名路径

随后进行实例化恶意类调用静态方法触发漏洞


0x06、漏洞修复

官方更新补丁,升级至9.2.0版本:https://solr.apache.org/downloads.html

0x07、参考链接

https://blog.noah.360.net/apache-solr-rce/