solr漏洞审计

# 环境搭建

各版本源码下载:
http://archive.apache.org/dist/lucene/solr/7.0.1/

此处 win 环境,下载源码
d90b95d958f7a8aa03ec037e23ff6565.png

在源码根目录打开 cmd,运行 ant ivy-bootstrap
65611596abbf48fd002528219ce04da6.png

解压后用 idea 打开
6398b74ee6a4f3388ea89aa77e051942.png

(这里可以使用 ant 编译成 idea 项目后,再用 idea 直接打开,在项目根目录下运行 ant 命令即可)

在 solr 目录下,运行 ant server 创建 solr server
568e847efbb2bd3f814629269b607938.png

报错: Could not find file C:\Users\HAN91\.ant\lib\ivy-2.3.0.jar to generate checksum
ivy 下载
http://ant.apache.org/ivy/download.cgi

# 漏洞原理

# CVE-2017-12629

# XXE

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 修复方法

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

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

1
2
3
4
5
6
// 这是优先选择. 如果不允许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
0f16537ae621dca652c50598b2934616.png
我们看见一下这行代码执行了命令,并传入了三个参数
proc = Runtime.getRuntime().exec(cmd, envp ,dir);
查看 API
cmdarray:命令字符串
envp:代表 “环境” 变量设置,如果 envp 是 null ,则子进程继承当前进程的环境设置
dir:新子进程的工作目录由 dir 指定 。 如果 dir 是 null ,则子进程继承当前进程的当前工作目录。

9ec0917d903603b1067a566e250c5627.png

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

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

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

# 漏洞修复

官方修复直接将该类删除

# 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
a6303a016339679c882babc40deace8b.png
漏洞点:
org.apache.solr.handler.dataimport.DataImportHandler
其中 handleRequestBody() 函数接收了前端传入的 dataConfig
08710fb1d7d531e129962d80bb22941e.png
后面就不再分析了,因为这个漏洞是 solr 该模块允许执行脚本,官方文档中也描述了该模块以及脚本的使用

# 漏洞修复

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

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

官方文档中写明,solrconfig.xml 中 enableRemoteStreaming="true" 时允许远程流
d4e2c6715cd93bccb5ba0645bf44d89c.png
因此我们可以通过 config API,启用远程读取流
enableRemoteStreaming = “true” ,将允许任何人向任何 URL 或本地文件发送请求
DumpRequestHandler = “true” ,它将允许任何人查看系统上的任何文件。
漏洞点:
solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
d9c8060b808d32f29db7535380472c6e.png
其中通过以下代码获取前端传入数据

1
strs = params.getParams( CommonParams.STREAM_FILE );

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

1
2
3
4
5
6
7
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
e0c12b5404c9aa9db8cd8eb2b87f7d3e.png
其中若传入 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 ©milkii0