apache solr rce cve-2019-0192 分析

前言

漏洞详情:https://issues.apache.org/jira/browse/SOLR-13301
漏洞POC:https://github.com/mpgn/CVE-2019-0192

影响版本:5.0.0 ~ 5.5.5、6.0.0 ~ 6.6.5
安全版本:7.0

简要描述

ConfigAPI allows to configure Solr's JMX server via an HTTP POST request.By pointing it to a malicious RMI server, an attacker could take advantage of Solr's unsafe deserialization to trigger remote code execution on the Solr side.

调用栈

Solr 中由配置文件触发 Jmx流程:
org.apache.solr.handler.SolrConfigHandler#handleRequestBody
->
org.apache.solr.handler.SolrConfigHandler.Command#handlePOST
->
org.apache.solr.handler.SolrConfigHandler.Command#applySetProp
->
org.apache.solr.core.CoreContainer#reload
->
org.apache.solr.core.SolrConfig#SolrConfig
->
org.apache.solr.core.SolrCore#reload
->
org.apache.solr.core.SolrCore#SolrCore
->
org.apache.solr.core.SolrCore#initInfoRegistry
->
org.apache.solr.core.JmxMonitoredMap#JmxMonitoredMap
->
javax.management.remote.JMXConnectorServerMBean#start

分析过程

其路由过程不再分析,在 https://xz.aliyun.com/t/1523 这篇文章中分析过

直接到 ReuqestHandler 中,访问路径 /config 可以进入 SolrConfigHandler#handleRequestBody 中,如下图:

由poc知道我们走的是 POST 的处理流程,跟进 handlePOST 函数

如上图看见关键词 Config Overlay ,跟进 else 代码块调用的 handleCommands 函数,如下

第一个框就是 poc 给出的 POST 数据中指定的 set-property 流程,但是我感觉第二个框也可以,不过具体情况没测试

跟入 applySetProp 函数,如下

private ConfigOverlay applySetProp(CommandOperation op, ConfigOverlay overlay) {
      Map<String, Object> m = op.getDataMap();
      if (op.hasError()) return overlay;
      for (Map.Entry<String, Object> e : m.entrySet()) {
        String name = e.getKey();
        Object val = e.getValue();
        Class typ = ConfigOverlay.checkEditable(name, false, null);
[……中间省略了解析 POST 数据的流程……]
        overlay = overlay.setProperty(name, val);
      }
      return overlay;
    }

  }

如上,注意力转向 setProperty 的调用,跟进

这里就是将 POST 参数做处理后,全部用于生成一个新的 ConfigOverlay 对象并将其返回到 handleCommands 函数中的 overlay 变量去接受赋值

标注 handleCommands 中的 overlay 变量,看到如下调用

If 代码块是处于 zookeeper 分布式状态下的,也能触发成功,不过为了便于分析,我们跟进 else 代码块:单机孤儿模式

可以看见调用了 persistConfLocally 猜测应该是将刚刚生成的 ConfigOverlay 对象的数据做持久存储,其中 ConfigOverlay.RESOURCE_NAME 的值为:

public static final String RESOURCE_NAME = "configoverlay.json";

数据应该是存入了 configoverlay.json 中
第二步就调用了 reload 函数,重启服务器

其实这里我是反向跟踪的,因为 reload 流程中会有大量的 initial 操作,根本分不清啥时候会加载我们指定的配置,从 ConfigOverlay.RESOURCE_NAME 入手

这里有个获取流数据操作,八九不离十就是这里,但是为了调用流程直观,我们还是从 reload 流程中讲述

注意到了这一句,重新加载的话,所有配置文件也会重新加载一次,既然之前写入了 configoverlay.json 文件中,那也算作是配置文件,跟进 getConfig 函数

很显眼 createSolrConfig 函数流程肯定是重加载配置,一直跟踪到 SolrConfig#SolrConfig 中,如下:

看见 overlay 了,跟进到 getConfigOverlay 函数如下

这里就刚好和前面搜索到的流数据操作吻合,那么继续在 SolrConfig 的构造函数中查看,找到如下

上图中看见了 poc 中指定的三个参数,并且用他们创建了 JmxConfiguration 对象赋值给 jmxConfig
这里还没完,JmxConfiguration 仅仅是存储信息的,并没有执行任何操作,跟踪 jmxConfig 参数如下

跟入红框所示位置

JmxMonitoredMap 的构造函数中就进行了 JMX 监控操作,可以触发 rmi 序列化

但是这里属于 initInfoRegistry 函数中,还不清楚这个函数在哪儿调用,反向查找在 SolrCore 的构造函数中被调用到

SolrCore 的构造函数由 CoreContainer#reload 调用的 SolrCore#reload 触发

至此服务端触发jmx流程已经完整

链接

漏洞详情:https://issues.apache.org/jira/browse/SOLR-13301
漏洞POC:https://github.com/mpgn/CVE-2019-0192
https://issues.apache.org/jira/secure/attachment/12961503/12961503_SOLR-13301.patch
https://lucene.apache.org/solr/guide/6_6/config-api.html#ConfigAPI-CommandsforCommonProperties

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值