Serialization and deserialization in Java: explaining the Java deserialize vulnerability

Java serialization is a mechanism to transform an object into a byte stream. A deserialização Java é exatamente o contrário e nos permite recriar um objeto a partir de um fluxo de bytes. A serialização Java—e mais especificamente a deserialização em Java-também é conhecida como “o presente que continua dando”. Isto está relacionado com as muitas questões de segurança e outros problemas que tem produzido ao longo dos anos.,

o que é a serialização em Java?

em Java, criamos objetos. Estes objetos vivem na memória e são removidos pelo coletor de lixo uma vez que eles não são mais usados. Se quisermos transferir um objeto, por exemplo, armazená-lo em um disco ou enviá-lo por uma rede, precisamos transformá-lo em um fluxo de bytes. Para fazer isso, a classe desse objeto precisa implementar a interface Serializable. Serialização é converter o estado de um objeto em um fluxo de bytes. Este fluxo de bytes não contém o código real.,

o que é a deserialização em Java?

Deserialização é precisamente o oposto da serialização. Com a deseralização, você tem um fluxo de bytes e você recria o objeto no mesmo estado que quando você o serializou. Isto significa que você precisa ter a definição real do objeto para realizar a recreação.

como funciona a serialização Java?

java serialization uses reflection to scrape all the data from the object’s fields that need to be serialized. Isto inclui campos privados e finais., Se um campo contém um objeto, esse objeto é serializado recursivamente. Mesmo que você possa ter getters e setters, essas funções não são usadas na serialização de um objeto em Java.

como funciona a deserialização Java?

ao deserializar um fluxo de bytes de volta para um objeto, ele não usa o construtor. Ele cria um objeto vazio e usa reflexão para escrever os dados para os campos. Assim como com a serialização, campos privados e finais também estão incluídos.

o que é uma vulnerabilidade deserializar Java?,

uma vulnerabilidade deserialize Java é uma vulnerabilidade de segurança que ocorre quando um usuário malicioso tenta inserir um objeto serializado modificado no sistema que eventualmente compromete o sistema ou seus dados. Pense na execução arbitrária de código que pode ser desencadeada ao deserializar um objeto serializado. Para explicar melhor as vulnerabilidades do Java, primeiro precisamos explorar como a deserialização funciona em Java.

Explicando Java desserializar vulnerabilidades

Um objeto serializado em Java é uma array de bytes com informações do estado., Contém o nome do objeto a que se refere e os dados do campo. Se você olhar para um objeto serializado armazenado com um editor Hexadecimal, você pode anexar e manipular a informação rapidamente.

já sabemos que a deserialização Java não usa o construtor para criar um objeto, mas usa a reflexão para carregar os campos. Isto significa que qualquer verificação de validação feita no construtor nunca é chamada ao recriar o objeto. Você pode pensar em Verificações como a data de início antes da data de fim ao descrever um período., Ao deserializar um objeto Java, este novo objeto pode ter um estado inválido.

vejamos o seguinte exemplo de Java anular a serialização de vulnerabilidade, onde podemos serializar um objeto de uma classe serializável ValueObject:

Ao ler o arquivo ValueObject.ser que contém o objeto serializado com um editor hexa, a saída é essa.

Agora, posso facilmente manipular o valor de seqüência de caracteres. Below I change it from Hi to Hallo.,

Ao desserializar o ajuste do binário de arquivo, descobrimos que o objeto value mudou. Também vemos que a data não mudou, provando que o construtor nunca é chamado. Então, se uma aplicação Aceita objetos serializados, é relativamente fácil de temperar com os valores. Alterando os objetos serializados, podemos criar objetos inválidos, mexer com a integridade dos dados, ou ainda pior.,

execução arbitrária de código, gadgets e cadeias

manipulação dos dados em um objeto já é prejudicial. No entanto, isso também pode levar à execução de código se o conjunto correto de objetos é deserializado. Para explicar isso eu primeiro tenho que explicar gadgets e correntes.

Gadgets

Um gadget—como o usado por Lawrence & Frohoff em seu discurso Marschalling de Picles em AppSecCali 2015—é uma classe ou função já existente de código executável presente no processo vulnerável. Este código executável existente pode ser reutilizado para fins maliciosos., Se olharmos para objetos serializáveis Java, alguns métodos mágicos—como o private readObject() method-são chamados refletivamente quando deserializam.

Let’s look at the simplified gadget below:

This gadget class overrides the default readObject method. Como resultado, toda vez que um objeto da classe Gadget é deserializado, o comando Runnable objeto é executado. Quando uma classe de comando se parece com o exemplo abaixo, é fácil manipular este objeto serializado e executar a injeção de código.,

também, note que se uma aplicação Aceita objetos serializados, o objeto é deserializado primeiro antes de ser lançado para o tipo desejado. Isto significa que, mesmo que o elenco falhe, a deserialização já está concluída e o método readObject() é executado.

Gadget chains deserialization attack

a typical deserialization attack consists of a cleverly crafted chain of gadgets. Um atacante procura por um gadget que é utilizável para lançar um ataque e acorrenta várias execuções que terminam com a execução arbitrária de código, por exemplo.,
In our example:

Gadget -> readObject() -> command.run() -> Runtime.getRuntime().exec()

For a more real-life example, take a look at the implementation of java.util.HashMap. Esta classe tem uma implementação personalizada do método readObject() que despoleta a função

.

bibliotecas

é bom saber que quaisquer cadeias gadget estão disponíveis em sua aplicação, não está relacionado ao seu código., Como importamos muitos códigos de bibliotecas e frameworks, o número de classes importadas por suas dependências (transitivas) influencia a possibilidade de certas cadeias de gadget. Embora a criação de uma tal cadeia de gadget maliciosa é muito difícil e trabalhosa, as vulnerabilidades de deserialização Java são um risco de segurança genuíno e perigoso.

como prevenir uma vulnerabilidade Deserializar Java?

a melhor maneira de prevenir uma vulnerabilidade deserialize Java é prevenir a serialização Java em geral. Se a sua aplicação não aceitar objetos serializados de todo, ela não pode prejudicá-lo.,

no entanto, se você precisar implementar a interface serializável devido à herança, você pode substituir o readObject(), como visto abaixo, para evitar a deseralização real.

Se a sua aplicação se basear em objectos serializados, pode considerar inspeccionar o seu ObjectInputStream antes de deserializar. Uma biblioteca que pode ajudá-lo com isso é a biblioteca Apache Commons IO. Esta biblioteca fornece um ValidatedObjectInputStream onde você pode permitir explicitamente os objetos que deseja deserializar. Agora você evita que tipos inesperados sejam desertificados.,

uma ferramenta como o ysoserial também é extremamente útil para encontrar vulnerabilidades do Java em seu código. É uma ferramenta que gera carga útil para descobrir cadeias de gadget em bibliotecas Java comuns que podem, sob as condições certas, explorar aplicações Java executando deserialização insegura de objetos.

Note que as vulnerabilidades de deserialização Java não são exclusivas da implementação de serialização personalizada de Java. Embora este artigo se concentre apenas nesta parte, as mesmas vulnerabilidades existem em serialização ou esquemas de marshaling que lidam com isso para você., Se existe um framework que magicamente cria POJO de XML, JSON, yaml, ou formatos similares, ele provavelmente usa a reflexão da mesma forma como descrito acima. Isto significa que existem os mesmos problemas.

Author: admin

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *