环境搭建:
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

