diff --git a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md index 9582cd3b5..929df414e 100644 --- a/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md +++ b/src/pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md @@ -1,15 +1,27 @@ +# Basic Java Deserialization with ObjectInputStream readObject + {{#include ../../banners/hacktricks-training.md}} -Neste POST, será explicado um exemplo usando `java.io.Serializable`. +Neste POST, será explicado um exemplo usando `java.io.Serializable` **e por que sobrescrever `readObject()` pode ser extremamente perigoso se o fluxo de entrada for controlado pelo atacante**. -# Serializable +## Serializable -A interface Java `Serializable` (`java.io.Serializable`) é uma interface de marcador que suas classes devem implementar se forem **serializadas** e **desserializadas**. A serialização de objetos Java (escrita) é feita com o [ObjectOutputStream](http://tutorials.jenkov.com/java-io/objectoutputstream.html) e a desserialização (leitura) é feita com o [ObjectInputStream](http://tutorials.jenkov.com/java-io/objectinputstream.html). +A interface Java `Serializable` (`java.io.Serializable`) é uma interface de marca que suas classes devem implementar se forem **serializadas** e **desserializadas**. A serialização de objetos Java (escrita) é feita com o [`ObjectOutputStream`](http://tutorials.jenkov.com/java-io/objectoutputstream.html) e a desserialização (leitura) é feita com o [`ObjectInputStream`](http://tutorials.jenkov.com/java-io/objectinputstream.html). + +### Lembrete: Quais métodos são invocados implicitamente durante a desserialização? + +1. `readObject()` – lógica de leitura específica da classe (se implementada e *privada*). +2. `readResolve()` – pode substituir o objeto desserializado por outro. +3. `validateObject()` – via callbacks de `ObjectInputValidation`. +4. `readExternal()` – para classes que implementam `Externalizable`. +5. Construtores **não** são executados – portanto, cadeias de gadgets dependem exclusivamente dos callbacks anteriores. + +Qualquer método nessa cadeia que acabe invocando dados controlados pelo atacante (execução de comando, buscas JNDI, reflexão, etc.) transforma a rotina de desserialização em um gadget RCE. Vamos ver um exemplo com uma **classe Person** que é **serializável**. Esta classe **sobrescreve a função readObject**, então quando **qualquer objeto** desta **classe** é **desserializado**, esta **função** será **executada**.\ No exemplo, a **função readObject** da classe Person chama a função `eat()` de seu animal de estimação e a função `eat()` de um Dog (por algum motivo) chama um **calc.exe**. **Vamos ver como serializar e desserializar um objeto Person para executar esta calculadora:** -**O seguinte exemplo é de [https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649](https://medium.com/@knownsec404team/java-deserialization-tool-gadgetinspector-first-glimpse-74e99e493649)** +**O seguinte exemplo é de ** ```java import java.io.Serializable; import java.io.*; @@ -80,8 +92,63 @@ payloadTest("test.ser"); } } ``` -## Conclusão +### Conclusão (cenário clássico) -Como você pode ver neste exemplo muito básico, a "vulnerabilidade" aqui aparece porque a função **readObject** está **chamando outras funções vulneráveis**. +Como você pode ver neste exemplo muito básico, a “vulnerabilidade” aqui aparece porque o método **readObject()** está **chamando outro código controlado pelo atacante**. Em cadeias de gadgets do mundo real, milhares de classes contidas em bibliotecas externas (Commons-Collections, Spring, Groovy, Rome, SnakeYAML, etc.) podem ser abusadas – o atacante só precisa de *um* gadget acessível para obter execução de código. + +--- + +## 2023-2025: O que há de novo em ataques de deserialização Java? + +* 2023 – CVE-2023-34040: A deserialização de cabeçalhos de registros de erro do Spring-Kafka quando as flags `checkDeserExWhen*` estão habilitadas permitiu a construção arbitrária de gadgets a partir de tópicos publicados por atacantes. Corrigido em 3.0.10 / 2.9.11. ¹ +* 2023 – CVE-2023-36480: A suposição de servidor confiável do cliente Java Aerospike foi quebrada – respostas de servidor malicioso continham cargas úteis serializadas que foram deserializadas pelo cliente → RCE. ² +* 2023 – CVE-2023-25581: A análise do atributo de perfil de usuário do `pac4j-core` aceitou blobs Base64 com prefixo `{#sb64}` e os deserializou apesar de um `RestrictedObjectInputStream`. Atualize para ≥ 4.0.0. +* 2023 – CVE-2023-4528: O JSCAPE MFT Manager Service (porta 10880) aceitou objetos Java codificados em XML levando a RCE como root/SYSTEM. +* 2024 – Várias novas cadeias de gadgets foram adicionadas ao ysoserial-plus(mod), incluindo classes Hibernate5, TomcatEmbed e SnakeYAML 2.x que contornam alguns filtros antigos. + +## Mitigações modernas que você deve implementar + +1. **JEP 290 / Filtragem de Serialização (Java 9+)** +*Adicione uma lista de permissão ou lista de negação de classes:* +```bash +# Aceite apenas seus DTOs e java.base, rejeite tudo o mais +-Djdk.serialFilter="com.example.dto.*;java.base/*;!*" +``` +Exemplo programático: +```java +var filter = ObjectInputFilter.Config.createFilter("com.example.dto.*;java.base/*;!*" ); +ObjectInputFilter.Config.setSerialFilter(filter); +``` +2. **JEP 415 (Java 17+) Fábricas de Filtros Específicos de Contexto** – use um `BinaryOperator` para aplicar filtros diferentes por contexto de execução (por exemplo, por chamada RMI, por consumidor de fila de mensagens). +3. **Não exponha `ObjectInputStream` bruto pela rede** – prefira codificações JSON/binárias sem semântica de execução de código (Jackson após desabilitar `DefaultTyping`, Protobuf, Avro, etc.). +4. **Limites de Defesa em Profundidade** – Defina comprimento máximo de array, profundidade, referências: +```bash +-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000" +``` +5. **Escaneamento contínuo de gadgets** – execute ferramentas como `gadget-inspector` ou `serialpwn-cli` em seu CI para falhar a construção se um gadget perigoso se tornar acessível. + +## Folha de dicas de ferramentas atualizada (2024) + +* `ysoserial-plus.jar` – fork da comunidade com > 130 cadeias de gadgets: +```bash +java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0 +``` +* `marshalsec` – ainda a referência para geração de gadgets JNDI (LDAP/RMI). +* `gadget-probe` – descoberta rápida de gadgets em caixa-preta contra serviços de rede. +* `SerialSniffer` – agente JVMTI que imprime cada classe lida por `ObjectInputStream` (útil para criar filtros). +* **Dica de detecção** – habilite `-Djdk.serialDebug=true` (JDK 22+) para registrar decisões de filtro e classes rejeitadas. + +## Lista de verificação rápida para implementações seguras de `readObject()` + +1. Torne o método `private` e adicione a anotação `@Serial` (ajuda na análise estática). +2. Nunca chame métodos fornecidos pelo usuário ou realize I/O no método – apenas leia campos. +3. Se a validação for necessária, realize-a **após** a deserialização, fora de `readObject()`. +4. Prefira implementar `Externalizable` e faça leituras de campos explícitas em vez de serialização padrão. +5. Registre um `ObjectInputFilter` endurecido mesmo para serviços internos (design resiliente a compromissos). + +## Referências + +1. Aviso de Segurança do Spring – CVE-2023-34040 Deserialização Java no Spring-Kafka (Ago 2023) +2. GitHub Security Lab – GHSL-2023-044: Deserialização insegura no Cliente Java Aerospike (Jul 2023) {{#include ../../banners/hacktricks-training.md}}