Padding oracle
El padding oracle es uno de los ataques criptográficos más elegantes y a la vez más prácticos: permite descifrar (y a menudo cifrar) datos protegidos con CBC sin conocer la clave, aprovechando que el sistema revela si el relleno (padding) es válido. Aparece en cookies, tokens, parámetros cifrados y APIs.
El contexto: CBC y PKCS#7
Sección titulada «El contexto: CBC y PKCS#7»CBC descifra: P_i = D(C_i) XOR C_{i-1} (C_0 = IV)PKCS#7 padding: rellena el último bloque con N bytes de valor N (p. ej. 04 04 04 04)Al descifrar, se valida que el padding sea correcto -> si no, ERROR de paddingEl fallo: si el servidor responde distinto ante “padding inválido” vs “padding válido pero datos mal” (error HTTP distinto, mensaje, o incluso timing), tienes un oráculo.
Cómo descifra el ataque (concepto)
Sección titulada «Cómo descifra el ataque (concepto)»Objetivo: recuperar P2 = D(C2) XOR C1, sin la clave.Se manipula C1 byte a byte (C1') y se observa el oráculo sobre [C1' | C2]: - ajustando el último byte de C1' hasta que el padding sea VÁLIDO (0x01), se deduce D(C2)[último] = C1'[último] XOR 0x01 - conocido D(C2)[último], se fuerza padding 0x02 0x02 y se repite para el penúltimo byte - ... así hasta recuperar los 16 bytes de D(C2) -> luego P2 = D(C2) XOR C1 (el C1 real)Resultado: se descifra bloque a bloque TODO el mensaje. Máx. 256 pruebas por byte.Para cifrar texto a voluntad (forjar un criptograma válido) se usa la misma propiedad al revés, eligiendo los C_{i-1} que produzcan el texto deseado.
Explotación práctica
Sección titulada «Explotación práctica»# padbuster: automatiza el ataque contra un endpoint webpadbuster http://host/x?data=<C> <C_en_base64> 16 -encoding 0 -cookies 'sess=...'# python-paddingoracle para montarlo a medida cuando el oráculo es no-estándar# clave: definir la función oracle(ciphertext)->bool (padding ok?) correctamenteSeñales de que hay oráculo: un parámetro/cookie que es claramente un criptograma (múltiplo de 16 bytes en base64/hex) y respuestas distinguibles al corromperlo.
Variante: Padding Oracle en RSA (Bleichenbacher / ROBOT)
Sección titulada «Variante: Padding Oracle en RSA (Bleichenbacher / ROBOT)»El mismo principio aplica a RSA con padding PKCS#1 v1.5: un oráculo de “padding válido” permite descifrar o firmar. Revivido como ROBOT (2017) en grandes sitios (ver PKI & certificados/TLS).
Herramientas
Sección titulada «Herramientas»- padbuster, python-paddingoracle, scripts propios en PyCryptodome.
- Burp (para automatizar peticiones y distinguir respuestas), CyberChef (verificar bloques).
Defensa
Sección titulada «Defensa»- Cifrado autenticado (AEAD): AES-GCM / ChaCha20-Poly1305 — no hay padding que validar.
- Si se usa CBC, encrypt-then-MAC y verificar el MAC antes de intentar descifrar/validar padding.
- No distinguir errores: misma respuesta y tiempo ante padding inválido y datos inválidos.
- No exponer criptogramas manipulables al cliente sin integridad.
CVEs y casos reales
Sección titulada «CVEs y casos reales»- Vaudenay (2002): formulación original del padding oracle sobre CBC.
- Lucky Thirteen (2013): padding oracle por timing en TLS CBC.
- ROBOT (2017): Bleichenbacher (padding oracle RSA) en Facebook, PayPal, Cisco, F5, etc.
- POODLE (2014): padding oracle sobre SSLv3 CBC.
Checklist de prueba
Sección titulada «Checklist de prueba»- Localizar parámetros/cookies que sean criptogramas CBC (múltiplo de 16)
- ¿El sistema distingue “padding inválido” de “datos inválidos”? (error/timing)
- Ejecutar padbuster / script para descifrar bloque a bloque
- Probar la forja de criptogramas (cifrado controlado)
- RSA PKCS#1v1.5: buscar oráculo tipo Bleichenbacher/ROBOT
- Verificar defensa: AEAD o encrypt-then-MAC + respuestas uniformes