## https://sploitus.com/exploit?id=33716C08-99B9-5C02-A039-226C4FDDF7C8
# CVE-2025-48734: Apache Commons BeanUtils โ enum declaredClass Information Leak & RCE Chain
> **For educational and authorized security research purposes only.**
This repository provides a controlled lab environment to reproduce the **CVE-2025-48734** vulnerability in Apache Commons BeanUtils and explore how an attacker could escalate to remote code execution (RCE) under certain conditions.
---
## ๐ Vulnerability Description
**CVE-2025-48734** affects Apache Commons BeanUtils in versions prior to **1.11.0** (and the 2.x branch before **2.0.0-M2**). The issue lies in `PropertyUtilsBean` allowing access to the `declaredClass` property of Java enums through nested paths (e.g., `enum.declaredClass`). All enums inherit the `getDeclaringClass()` method from `java.lang.Enum`, which BeanUtils exposes as a navigable property.
An attacker who can control the property path in calls to `getProperty()` or `getNestedProperty()` can:
- Obtain a reference to the application's `ClassLoader` (via `enum.declaredClass.classLoader`).
- Potentially escalate to code execution if the application has other components that allow loading classes or executing commands through properties.
> โ ๏ธ **Important:** The vulnerability alone **does not directly grant RCE**. It provides access to the `ClassLoader`, which must be chained with an additional gadget to achieve code execution. See the [Detailed Exploit Analysis](#-detailed-exploit-analysis) section.
**CVSS Score:** 8.8 (High) โ `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`
---
## ๐งช Lab Environment
The test application is a simple Spring Boot service exposing the following vulnerable endpoints:
- `GET /api/property?path=` โ reads a nested property using `PropertyUtilsBean.getNestedProperty()` without sanitization.
- `GET /api/nested-set?path=&value=` โ writes nested properties (also vulnerable).
The target bean is an `Order` object containing a `Status` enum. This allows building the chain `status.declaredClass.classLoader`.
Additionally, to **demonstrate RCE** under simulated additional conditions:
- A `MaliciousBean` bean with an `exec` property that executes system commands.
- A `GET /api/exec?cmd=` endpoint that allows arbitrary command execution.
> **Note:** The `/api/exec` endpoint is **not part of the original vulnerability**. It is included solely to illustrate the potential impact that could be achieved if an attacker successfully combines the information leak with a code invocation mechanism (gadget). In a real environment, achieving RCE would require chaining this vulnerability with other vectors.
---
## โ๏ธ Quick Setup
### Requirements
- Docker (with the Compose plugin)
### Steps
1. **Clone or download this repository.**
2. **Run the setup script** (creates the application files and Docker resources):
```bash
chmod +x setup.sh
./setup.sh
```
3. **Navigate to the generated directory and start the container:**
```bash
cd cve-2025-48734-lab
docker compose up --build -d
```
Wait for the build to finish (approximately 1โ2 minutes). The application will be available at `http://localhost:8080`.
---
## โ Vulnerability Verification
Once the container is running, use the included script to check whether the application is vulnerable:
```bash
./test-lab.sh
```
The script will test normal paths (`id`, `status`) and then the critical ones:
- `status.declaredClass`
- `status.declaredClass.classLoader`
- `status.class`
- `status.class.classLoader`
**Expected result (vulnerable):** All these paths return `"status":"success"` and display class or `ClassLoader` information.
**Expected result (patched):** Paths accessing `declaredClass` and `classLoader` return an error.
---
## ๐ RCE Demonstration (Additional Conditions)
To show how RCE could be achieved, the `/api/exec` endpoint has been added. Run the script:
```bash
./rce-poc.sh 'whoami'
```
This will return the username inside the container (typically `root`). You can try other commands:
```bash
./rce-poc.sh 'id'
./rce-poc.sh 'cat /etc/passwd'
```
### Hypothetical Attack Chain Explanation
1. **Information leak:** The attacker uses the original vulnerability to obtain the `ClassLoader` (e.g., `LaunchedURLClassLoader`).
2. **Malicious class loading:** If the application had a method (property) such as `loadClass` or a setter that allows class injection, the attacker could load a class that executes code.
3. **Command execution:** The malicious class could contain a property that executes commands, similar to our `MaliciousBean`.
In this lab, steps 2 and 3 are simulated via the `/api/exec` endpoint. In a real scenario, an attacker would need a gadget from the application itself or from a library that allows calling `Runtime.exec()` through the property chain.
---
## ๐ Detailed Exploit Analysis
### Why doesn't the vulnerability directly give RCE?
- `PropertyUtilsBean.getNestedProperty()` only invokes getters (no-argument methods starting with `get`).
- Although `getDeclaringClass()` is a valid getter, it does not execute arbitrary code โ it simply returns a `Class` object.
- Achieving RCE requires a gadget that is either a getter performing a dangerous action (such as `Runtime.getRuntime().exec()`) or a setter that allows code injection.
### Chaining in Real Applications
- **Unsafe deserialization:** Combined with libraries such as Commons Collections, a deserialization chain can be built using `BeanComparator` that, upon deserialization, accesses `declaredClass` and ultimately executes code.
- **Class injection:** In applications that allow dynamic class loading (e.g., through configuration), an attacker could use `ClassLoader` access to load a previously uploaded malicious class.
---
## ๐ก๏ธ Mitigation and Patch
The official fix is to upgrade to a patched version:
| Artifact | Vulnerable version | Safe version |
|---|---|---|
| `commons-beanutils:commons-beanutils` | = 1.11.0** |
| `org.apache.commons:commons-beanutils2` | = 2.0.0-M2** |
### Applying the Patch in the Lab
1. Edit the `pom.xml` file inside the `cve-2025-48734-lab` directory.
2. Change the `commons-beanutils` version from `1.9.4` to `1.11.0`.
3. Rebuild and restart the container:
```bash
docker compose down
docker compose up --build -d
```
4. Run `./test-lab.sh` again. The `status.declaredClass` paths should now return an error, confirming the vulnerability has been mitigated.
---
## ๐ References
- [CVE-2025-48734 on NVD](https://nvd.nist.gov/vuln/detail/CVE-2025-48734)
- [GitHub Advisory GHSA-wxr5-93ph-8wr9](https://github.com/advisories/GHSA-wxr5-93ph-8wr9)
- [Apache Commons BeanUtils Security Reports](https://commons.apache.org/proper/commons-beanutils/security-reports.html)
- [Atlassian Confluence Security Advisory (example of an affected application)](https://confluence.atlassian.com/security)
---
## Disclaimer
This tool/site is provided for **educational purposes and authorized security testing only**. Unauthorized use against systems you do not own or have explicit written permission to test is illegal. The author is not responsible for any misuse.