solr漏洞审计

CVE-2017-12629

XXE

Lucene包含了一个查询解析器支持XML格式进行数据查询,并且解析xml数据时,未设置任何防御措施,导致我们可引入任意恶意外部实体
而Solr由于使用Lucenne作为核心语义分析引擎,因此受到影响

漏洞点:
org.apache.lucene.queryparser.xml.CoreParser#parseXML
此处为解析xml数据的方法,其中并未包含任何xxe防御措施
因此可正常解析我们引入的恶意外部实体

static Document parseXML(InputStream pXmlFile) throws ParserException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    try {
      db = dbf.newDocumentBuilder();
    }
    catch (Exception se) {
      throw new ParserException("XML Parser configuration error", se);
    }
    org.w3c.dom.Document doc = null;
    try {
      doc = db.parse(pXmlFile);
    }
    catch (Exception se) {
      throw new ParserException("Error parsing XML stream:" + se, se);
    }
    return doc;
  }

漏洞修复

官方修复是增加XXE通用防御,这也是我们常用的xxe修复方法

DocumentBuilderFactory.setFearture("http://javax.xml.XMLConstants/feature/secure-processing")

以下列出一些通过设置解析器行为,达到对xxe进行限制的方法

// 这是优先选择. 如果不允许DTDs (doctypes) ,几乎可以阻止所有的XML实体攻击
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

// 如果不能完全禁用DTDs,最少采取以下措施,必须两项同时存在
setFeature("http://xml.org/sax/features/external-general-entities", false);// 防止外部实体POC
setFeature("http://xml.org/sax/features/external-parameter-entities", false);// 防止参数实体POC

RCE

RCE需要使用到SolrCloud Collections API,所以RCE只影响Solrcloud分布式系统

漏洞点:
org.apache.solr.core.RunExecutableListener#exec

我们看见一下这行代码执行了命令,并传入了三个参数
proc = Runtime.getRuntime().exec(cmd, envp ,dir);
查看API
cmdarray:命令字符串
envp:代表“环境”变量设置,如果envp是null ,则子进程继承当前进程的环境设置
dir:新子进程的工作目录由dir指定 。 如果dir是null ,则子进程继承当前进程的当前工作目录。

那么我们怎么才能控制以上这三个参数呢?
在初始化时,通过初始化传入的参数args
分别获得这三个参数cmd,dir,envp

找到调用exec()的有两处
org.apache.solr.core.RunExecutableListener#postCommit
org.apache.solr.core.RunExecutableListener#newSearcher

因此我们可以config API调用以上两个命令执行命令
关于config API更多信息可查看传送门中放置的官网链接

漏洞修复

官方修复直接将该类删除

CVE-2019-0193

DataImportHandler 是一个可选但流行的模块,用于从数据库和其他来源提取数据。它有一个特性,即整个 DIH(the Data Import Handler,数据导入处理程序) 配置可以来自请求的dataConfig参数

DIH 管理屏幕的调试模式使用它来方便 DIH 配置的调试/开发。因为 DIH 配置可以包含脚本,并未对脚本进行任何过滤检测,所以这个参数存在安全风险

从 Solr 的8.2.0版本开始,使用这个参数需要将 Java System 属性 enable.dih.dataConfigParam 设置为 true,此时也将存在该漏洞

DHI和script官方文档链接放在传送门中

我们可以根据官方文档的说明,插入脚本并执行,其中entity标签支持jndi以及script

漏洞点:
org.apache.solr.handler.dataimport.DataImportHandler
其中handleRequestBody()函数接收了前端传入的dataConfig

后面就不再分析了,因为这个漏洞是solr该模块允许执行脚本,官方文档中也描述了该模块以及脚本的使用

漏洞修复

官方修复增加enable.dih.dataConfigParam参数,默认=false,仅在启动solr时带上参数enable.dih.dataConfigParam=true才可启动debug模式

Remote-Streaming-Fileread(任意文件读取)

官方文档中写明,solrconfig.xml中enableRemoteStreaming="true"时允许远程流

因此我们可以通过config API,启用远程读取流
enableRemoteStreaming = “true”,将允许任何人向任何 URL 或本地文件发送请求
DumpRequestHandler = “true”,它将允许任何人查看系统上的任何文件。
漏洞点:
solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java

其中通过以下代码获取前端传入数据

  strs = params.getParams( CommonParams.STREAM_FILE );

在进行文件获取时,未对传入的strs进行任何检测和过滤,并生成stream

for( final String file : strs ) {
        ContentStreamBase stream = new ContentStreamBase.FileStream( new File(file) );
        if( contentType != null ) {
          stream.setContentType( contentType );
        }
        streams.add( stream );
      }

solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java中,写明了stream.file即为传入的CommonParams.STREAM_FILE

其中若传入url可导致ssrf,原理同上

修复建议

  1. 控制solr访问权限,增加访问口令
  2. 不对外网开放solr
  3. 关闭ConfigAPI:在bin目录下的solr.in.cmd中加入一行set SOLR_OPTS=%SOLR_OPTS% -Ddisable.configEdit=true;然后关闭远程读取文件流,默认不开启

CVE-2019-17558

传送门:
本地部署idea调试环境
Apache Solr组件安全
XXE漏洞原理以及防御方式
apache solr远程代码执行漏洞(cve-2019-0193)
config API
DHI
script
solr历史漏洞
content-streams

Copyright (c)milkii0

posted @ 2022-07-19 09:49  milkii0  阅读(198)  评论(0编辑  收藏  举报