【漏洞预警】Apache Solr远程代码执行漏洞 (CVE-2019-0193)处置手册及技术分析

2019-10-24 14:22:16 浏览数 (1)

预警编号:NS-2019-0029-1

2019-08-07

TAG:

Apache Solr、CVE-2019-0193、远程代码执行

危害等级:

攻击者利用此漏洞可实现远程代码执行。

版本:

2.0

1

漏洞概述

近日,Apache Solr官方发布Apache Solr远程代码执行漏洞(CVE-2019-0193)安全通告,此漏洞存在于可选模块DataImportHandler中,DataImportHandler是用于从数据库或其他源提取数据的常用模块,该模块中所有DIH配置都可以通过外部请求的dataConfig参数来设置,由于DIH配置可以包含脚本,因此该参数存在安全隐患。

攻击者可利用dataConfig参数构造恶意请求,实现远程代码执行,请相关用户尽快升级Solr至安全版本,以确保对此漏洞的有效防护。

参考链接:

https://issues.apache.org/jira/browse/SOLR-13669

SEE MORE →

2影响范围

受影响版本

  • Apache Solr < 8.2.0

不受影响版本

  • Apache Solr >= 8.2.0

3漏洞检测

在Solr管理后台Dashboard仪表盘中,可查看当前Solr的版本信息。若Solr版本在受影响范围内,且未做相关防护配置,则受此漏洞影响,请尽快采取防护措施。

4漏洞防护

4.1 官方升级

从Solr的8.2.0版本开始,使用问题参数dataConfig需要将java系统属性“enable.dih.dataconfigparam”设置为true。因此用户可通过将Solr版本升级至8.2.0及以上,对此漏洞进行防护。

下载链接:

http://lucene.apache.org/solr/downloads.html

4.2 临时防护建议

1、用户也可通过配置solrconfig.xml文件,将所有DataImport 所在的requestHandler注释掉并重启。

注:

  • 执行此操作会禁用dataimport 功能,请确定禁用该功能不会对业务产生影响后,再执行此操作。
  • 每个core都有对应的配置文件,需要修改每个core的配置。
  • 经测试,官方给出防护方案置dataConfig参数为空字符串无效,用户需参考上述方案对此漏洞进行防护。

2、确保网络设置只允许可信流量与Solr建立通信,尤其是与DIH请求处理器的通信。

4.3 产品防护

针对此漏洞,绿盟科技防护产品已发布规则升级包,可形成针对此漏洞的防护能力。强烈建议相关用户升级至最新规则。安全防护产品规则版本号如下:

安全防护产品

规则版本号

升级包下载链接

规则编号

IPS

5.6.10.20856

http://update.nsfocus.com/update/downloads/id/30905

【24541】

5.6.9.20856

http://update.nsfocus.com/update/downloads/id/30904

【24541】

5.6.8.792

http://update.nsfocus.com/update/downloads/id/30867

【24542】

产品规则升级的操作步骤详见如下链接:

IPS:https://mp.weixin.qq.com/s/JsRktENQNj1TdZSU62N0Ww

5技术分析

5.1 前置概念

  • Dataimport

Solr支持从Dataimport导入自定义数据,dataconfig需要满足一定语法,参考:

  • https://lucene.apache.org/solr/guide/6_6/uploading-structured-data-store-data-with-the-data-import-handler.html
  • https://cwiki.apache.org/confluence/display/solr/DataImportHandler

其中ScriptTransformer可以编写自定义脚本,支持常见的脚本语言如Javascript、JRuby、Jython、Groovy和BeanShell

ScriptTransformer容许用脚本语言如Javascript、JRuby、Jython、Groovy和BeanShell转换,函数应当以行(类型为Map<String,Object>)为参数,可以修改字段。脚本应当写在数据仓库配置文件顶级的script元素内,而转换器属性值为script:函数名。

使用示例:

<dataconfig> <script><![CDATA[ function f2c(row) { var tempf, tempc; tempf = row.get('temp_f'); if (tempf != null) { tempc = (tempf - 32.0)*5.0/9.0; row.put('temp_c', temp_c); } return row; } ]]> </script> <document> <entity name="e1" pk="id" transformer="script:f2c" query="select * from X"> </entity> </document> </dataConfig>

  • Nashorn引擎

在Solr中解析js脚本使用的是Nashorn引擎,可以通过Java.typeAPI在JavaScript中引用,就像Java的import一样,例如:

var MyJavaClass = Java.type(`my.package.MyJavaClass`);var result = MyJavaClass.sayHello('Nashorn');print(result);

5.2 漏洞分析

Solr在处理dataimport请求时,首先进入dataimport/DataImportHandler的handleRequestBody方法,当前请求的command为full-import,因此通过maybeReloadConfiguration重新加载配置。

在maybeReloadConfiguration中通过params.getDataConfig()判断了post的数据(dataConfig)是否为空,如果不是则通过loadDataConfig来加载。

随后在loadDataConfig中通过readFromXml方法解析提交的配置数据中的各个标签,比如document,script,function,dataSource等,传入的script自定义脚本即在此处被存入script变量,递归解析完所有标签构建出DIHConfiguration对象并返回。

获取到配置信息后通过this.importer.runCmd()方法处理导入过程。

this.importer.runCmd(requestParams, sw);

在doFullImport中,首先会创建一个DocBuilder对象,DocBuilder的主要功能是从给定配置中创建Solr文档,同时会记录一些状态信息。随后通过execute()方法会通过遍历Entity的所有元素来解析config结构,最终得到是一个EntityProcessorWrapper对象。EntityProcessorWrapper是一个比较关键的类,继承自EntityProcessor,在整个解析过程中起到重要的作用,可以参考https://lucene.apache.org/solr/8_1_1/solr-dataimporthandler/org/apache/solr/handler/dataimport/EntityProcessorWrapper.html

在解析完config数据后solr会把最后更新时间记录到配置文件中,这个时间是为了下次进行增量更新的时候用的。接着通过this.dataImporter.getStatus()判断当前数据导入是“全部导入”还是“增量导入”,两个操作对应的方法分别为doDelta()和doFullDump(),此处的操作是full-import,因此调用doFullDump()。

在doFullDump()中调用的是DocBuilder.buildDocument()方法,这个方法会为发送的配置数据的每一个processor做解析,当发送的entity中含有Transformers时,会进行相应的转换操作,例如转换成日期格式(DateFormatTransformer)、根据正则表达式转换(RegexTransformer)等,这次出现问题的是ScriptTransformer,可以根据用户自定义的脚本进行数据转换。由于脚本内容完全是用户控制的,当指定的script含有恶意代码时就会被执行,下面看一下Solr中如何执行javascript代码:

在读取EntityProcessorWrapper的每一个元素时,是通过epw.nextRow()调用的,它返回的是一个Map对象,进入EntityProcessorWrapper.nextRow方法。

通过applyTransformer()执行转换,调用的是相应Transformer的transformRow方法。

ScriptTransformer允许多种脚本语言调用,如Javascript、JRuby、Jython、Groovy和BeanShell等,transformRow()方法则会根据指定的语言来初始化对应的解析引擎,例如此处初始化的是scriptEngine,用来解析JavaScript脚本

Solr中默认的js引擎是Nashorn,Nashorn是在Java 8中用于取代Rhino(Java 6,Java 7)的JavaScript引擎,在js中可以通过Java.type引用Java类,就像Java的import一样,此处就可以通过这个语法导入任意Java类。

随后通过反射调用自定义的函数并执行,例如通过java.lang.Runtime执行系统命令。

整个漏洞就是因为可以通过<script>标签指定ScriptTransformer,而在这个标签内可以导入任意的java类,Solr也并没有对标签内容做限制,导致可以执行任意代码。

调用栈情况

END

作者:绿盟科技伏影实验室

声明

本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。

绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。

0 人点赞