Apache Solr 认证绕过漏洞(CVE-2024-45216)

环境搭建:

security.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"authentication": {
"class": "solr.BasicAuthPlugin",
"credentials": {
"solr": "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="
},
"blockUnknown": false,
"": {
"v": 0
}
},
"authorization": {
"class": "solr.RuleBasedAuthorizationPlugin",
"permissions": [
{
"name": "security-edit",
"role": "admin"
}
],
"user-role": {
"solr": "admin"
}
}
}

docker-composer.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
version: '3.7'
services:
solr1:
image: solr:9.6.0
container_name: solr1e
ports:
- "8983:8983"
- "5006:5006"
environment:
- ZK_HOST=zoo1:2181,zoo2:2181,zoo3:2181
- SOLR_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006
volumes:
- [your-local-path]security.json:/var/solr/data/security.json
networks:
- solr
depends_on:
- zoo1
- zoo2
- zoo3


solr2:
image: solr:9.6.0
container_name: solr2
ports:
- "8982:8983"
environment:
- ZK_HOST=zoo1:2181,zoo2:2181,zoo3:2181
networks:
- solr
depends_on:
- zoo1
- zoo2
- zoo3


solr3:
image: solr:9.6.0
container_name: solr3
ports:
- "8981:8983"
environment:
- ZK_HOST=zoo1:2181,zoo2:2181,zoo3:2181
networks:
- solr
depends_on:
- zoo1
- zoo2
- zoo3


zoo1:
image: zookeeper:3.8
container_name: zoo1
restart: always
hostname: zoo1
ports:
- 2181:2181
- 7001:7000
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
ZOO_4LW_COMMANDS_WHITELIST: mntr, conf, ruok
ZOO_CFG_EXTRA: "metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true"
networks:
- solr

zoo2:
image: zookeeper:3.8
container_name: zoo2
restart: always
hostname: zoo2
ports:
- 2182:2181
- 7002:7000
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
ZOO_4LW_COMMANDS_WHITELIST: mntr, conf, ruok
ZOO_CFG_EXTRA: "metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true"
networks:
- solr

zoo3:
image: zookeeper:3.8
container_name: zoo3
restart: always
hostname: zoo3
ports:
- 2183:2181
- 7003:7000
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
ZOO_4LW_COMMANDS_WHITELIST: mntr, conf, ruok
ZOO_CFG_EXTRA: "metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true"
networks:
- solr

networks:
solr:

docker-composer up -d 启动环境

docker exec -it /bin/bash

solr zk cp /var/solr/data/security.json zk:/security.json -z zoo1:2181,zoo2:2181,zoo3:2181

访问http://ip:8983/ 使用账号密码: solr:SolrRocks登录后开启身份验证

漏洞分析:

根据漏洞通告:https://solr.apache.org/security.html#cve-2024-45216-apache-solr-authentication-bypass-possible-using-a-fake-url-path-ending

查看Solr 9.6.0和Solr 9.7.0的PKIAuthenticationPlugin对比,可以看到补丁是删除了一处权限校验,这里会检查传入的url如果以PublicKeyHandler.PATH(/admin/info/key)结尾就会绕过后续的权限校验

org.apache.solr.security.PKIAuthenticationPlugin#doAuthenticate

org.apache.solr.security.PublicKeyHandler

而在org.apache.solr.servlet.SolrDispatchFilter#authenticateRequest中会使用getPathAfterContext方法获取/solr/后的url和PublicKeyHandler.PATH(/admin/info/key)作对比从而导致失败.

因此我们很容易想到可在/solr/和/admin/info/key之间添加路径来进行绕过,我们发送请求http://ip/solr/123/admin/info/key,并在header头添加Solrauth: qaxcert来测试一下。

绕过上述所述后会进入到org.apache.solr.servlet.SolrDispatchFilter#dispatch方法,在这里会调用HttpSolrCall.call方法

跟进org.apache.solr.servlet.HttpSolrCall#call,会调用HttpSolrCall.init()方法

而对比Solr 9.6.0和Solr 9.7.0,可以看到删除了一处判断,在这里会判断是否存在: ,如果存在则保存:前边的url

org.apache.solr.servlet.HttpSolrCall#init

因此我们可以使用http://ip/solr/:/admin/info/key + ‘Solrauth: qaxcert’ 来绕过我们想要访问的api

并且由于官方拒绝修复某bug,我们也可以配合造成任意文件读取

https://mp.weixin.qq.com/s/3WuWUGO61gM0dBpwqTfenQ

https://github.com/vulhub/vulhub/blob/master/solr/Remote-Streaming-Fileread/README.zh-cn.md