the_open_door
café
ESEN
← Volver al índice

Padding Oracle Attack

Un Padding Oracle permite descifrar y forjar datos cifrados en CBC sin conocer la clave, aprovechando que la aplicación revela si el relleno (padding) de un texto descifrado es válido. Un oráculo es cualquier señal que distingue "relleno correcto" de "relleno corrupto": un mensaje de error distinto, un código de estado diferente o incluso una variación de tiempo de respuesta. Con esa única respuesta binaria, un atacante recupera el texto claro byte a byte.

La palanca es cómo CBC encadena bloques: cada bloque de texto claro se obtiene como P_i = D(C_i) XOR C_{i-1}. Como controlamos el bloque anterior C_{i-1}, podemos ir modificando sus bytes y observar cuándo el oráculo acepta el padding: en ese momento conocemos D(C_i) para ese byte y, haciendo XOR con el C_{i-1} original, deducimos el byte de texto claro. Repetido sobre todos los bytes y bloques, se descifra el mensaje entero; y como el proceso también permite calcular el C_{i-1} que produce un texto claro elegido, se puede cifrar contenido arbitrario (por ejemplo, cambiar una cookie user=invitado por user=admin). La herramienta estándar automatiza ambas operaciones:

# descifrar una cookie cifrada en CBC (bloques de 8 bytes)
padbuster http://<ip>/index.php <cookie_cifrada> 8 -cookies "auth=<cookie_cifrada>"
# forjar un texto claro elegido -> nueva cookie valida
padbuster http://<ip>/index.php <cookie_cifrada> 8 -cookies "auth=<cookie_cifrada>" -plaintext "user=admin"

Cuando no hay un oráculo de error explícito pero el cifrado es débil, a veces basta un bit flipping: si el usuario cdmin genera un cifrado casi idéntico al de admin, se fuerzan con Intruder los bits del bloque hasta que la respuesta cambia de longitud, señal de que se ha obtenido una cookie válida de admin.

Requisitos. La aplicación debe (1) usar CBC con relleno (PKCS#7) sin comprobación de integridad y (2) distinguir de cara al atacante el padding válido del inválido (error, estado o tiempo diferentes). Sin ese oráculo observable, el ataque no arranca; con integridad autenticada (HMAC verificado en tiempo constante o AEAD), tampoco.

Cómo detectarlo. El patrón es inconfundible en el log: miles de peticiones con el mismo texto cifrado salvo pequeñas mutaciones de un bloque, la inmensa mayoría devolviendo el error de "padding inválido" y unas pocas el de "válido". Ese volumen de descifrados fallidos sobre un mismo token es lo que delata a padbuster; un WAF o un rate-limit sobre errores de descifrado lo corta en seco.

Defensa. No confiar la integridad al padding: autenticar el cifrado (AES-GCM u otro AEAD, o encrypt-then-MAC con HMAC verificado en tiempo constante) antes de descifrar, de modo que cualquier manipulación se rechace sin revelar nada del relleno. Devolver un error genérico e idéntico ante fallo de descifrado y limitar la tasa. Los datos así extraídos, si son hashes, aún hay que romperlos: enlaza con cracking de hashes.