
Descifrar cifrado ZIP legacy con el ataque de texto plano conocido de Biham y Kocher.
Descifra el cifrado legacy de ZIP con el ataque de texto plano conocido de Biham y Kocher.
Un archivo ZIP puede contener muchas entradas cuyo contenido puede estar comprimido y/o cifrado. En particular, las entradas pueden cifrarse con un algoritmo de cifrado simétrico basado en contraseña denominado cifrado tradicional PKWARE, cifrado legacy o ZipCrypto. Este algoritmo genera un flujo pseudoaleatorio de bytes (keystream) que se aplica XOR al contenido de la entrada (texto plano) para producir datos cifrados (texto cifrado). El estado del generador, compuesto por tres enteros de 32 bits, se inicializa con la contraseña y luego se actualiza continuamente con el texto plano a medida que avanza el cifrado. Este algoritmo de cifrado es vulnerable a ataques de texto plano conocido, como demostraron Eli Biham y Paul C. Kocher en el artículo de investigación A known plaintext attack on the PKZIP stream cipher. Dado un texto cifrado y 12 o más bytes del texto plano correspondiente, se puede recuperar el estado interno del generador de keystream. Este estado interno es suficiente para descifrar completamente el texto cifrado, así como otras entradas que fueron cifradas con la misma contraseña. También se puede usar para realizar un ataque de fuerza bruta sobre la contraseña con una complejidad de nl-6 donde n es el tamaño del conjunto de caracteres y l es la longitud de la contraseña.
bkcrack es una herramienta de línea de comandos que implementa este ataque de texto plano conocido. Las características principales son:
Puedes obtener la última versión oficial en GitHub.
Hay paquetes precompilados disponibles para Ubuntu, MacOS y Windows. Extrae el archivo descargado donde prefieras.
En Windows, se necesitan las bibliotecas de runtime de Microsoft para que bkcrack funcione. Si no están ya instaladas en tu sistema, descarga e instala el último paquete de Microsoft Visual C++ Redistributable.
Alternativamente, puedes compilar el proyecto con CMake.
Primero, descarga los archivos fuente o clona el repositorio git.
Luego, ejecutando los siguientes comandos en el árbol fuente se creará una instalación en la carpeta install.
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=install
cmake --build build --config Release
cmake --build build --config Release --target install
bkcrack está disponible en los repositorios de paquetes que se muestran a continuación. Estos paquetes son proporcionados por mantenedores externos.
Puedes ver una lista de nombres de entrada y metadatos en un archivo llamado archive.zip de esta manera:
bkcrack -L archive.zip
Las entradas que usan cifrado ZipCrypto son vulnerables a un ataque de texto plano conocido.
El ataque requiere al menos 12 bytes de texto plano conocido. Al menos 8 de ellos deben ser contiguos. Cuanto mayor sea el texto plano contiguo conocido, más rápido será el ataque.
Teniendo un archivo zip encrypted.zip con la entrada cipher como texto cifrado y plain.zip con la entrada plain como texto plano conocido, bkcrack se puede ejecutar así:
bkcrack -C encrypted.zip -c cipher -P plain.zip -p plain
Teniendo un archivo cipherfile con el texto cifrado (comenzando con los 12 bytes correspondientes al encabezado de cifrado) y plainfile con el texto plano conocido, bkcrack se puede ejecutar así:
bkcrack -c cipherfile -p plainfile
Si el texto plano corresponde a una parte distinta del inicio del texto cifrado, puedes especificar un desplazamiento. Puede ser negativo si el texto plano incluye una parte del encabezado de cifrado.
bkcrack -c cipherfile -p plainfile -o offset
Si conoces poco texto plano contiguo (entre 8 y 11 bytes), pero conoces algunos bytes en otros desplazamientos conocidos, puedes proporcionar esta información para alcanzar el requisito de un total de 12 bytes conocidos.
Para ello, usa el indicador -x seguido de un desplazamiento y bytes en hexadecimal.
bkcrack -c cipherfile -p plainfile -x 25 4b4f -x 30 21
Si el ataque tiene éxito, los datos descifrados asociados al texto cifrado utilizado para el ataque se pueden guardar:
bkcrack -c cipherfile -p plainfile -d decipheredfile
Si las claves son conocidas de un ataque anterior, es posible usar bkcrack para descifrar datos:
bkcrack -c cipherfile -k 12345678 23456789 34567890 -d decipheredfile
Los datos descifrados podrían estar comprimidos, dependiendo de si se usó compresión o no al crear el archivo zip.
Si se usó compresión deflate, se puede usar un script de Python 3 proporcionado en la carpeta tools para descomprimir los datos.
python3 tools/inflate.py < decipheredfile > decompressedfile
Para acceder a todas las entradas del archivo cifrado en un solo paso, puedes generar un nuevo archivo con el mismo contenido pero sin cifrado. Se asume que cada entrada fue originalmente cifrada con la misma contraseña.
bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -D decrypted.zip
También es posible generar un nuevo archivo cifrado con la contraseña que elijas:
bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -U unlocked.zip new_password
También puedes definir la nueva contraseña mediante su representación interna correspondiente.
bkcrack -C encrypted.zip -k 12345678 23456789 34567890 --change-keys unlocked.zip 581da44e 8e40167f 50c009a0
Estos dos comandos se pueden usar juntos para cambiar el contenido de un archivo cifrado sin conocer la contraseña, pero conociendo solo las claves internas: puedes hacer una copia cifrada con la contraseña que elijas, luego editar la copia con un gestor de archivos ingresando la contraseña elegida cuando se solicite, y finalmente hacer una copia del archivo modificado de vuelta con las claves de cifrado originales.
Dadas las claves internas, bkcrack puede intentar encontrar la contraseña original.
Puedes buscar una contraseña usando caracteres en un conjunto de caracteres determinado:
bkcrack -k 1ded830c 24454157 7213b8c5 -b ?p
Puedes restringir la búsqueda a contraseñas de una longitud determinada o un rango de longitudes:
bkcrack -k 1ded830c 24454157 7213b8c5 -b ?p -l 9
bkcrack -k 1ded830c 24454157 7213b8c5 -b ?p -l 8..10
La opción -r <length> <charset> es un atajo para -l 0..<length> -b <charset>:
bkcrack -k 1ded830c 24454157 7213b8c5 -r 10 ?p