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,原理同上
修复建议
- 控制solr访问权限,增加访问口令
- 不对外网开放solr
- 关闭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