lossy data algorithms algorithm compression
prueba de concepto de Security Focus

algorithm - data - ¿Cómo se hace una bomba Zip?



lossless compression (14)

Esta pregunta sobre las bombas zip naturalmente me llevó a la página de Wikipedia sobre el tema. El artículo menciona un ejemplo de un archivo comprimido de 45.1 kb que descomprime a 1.3 exabytes.

¿Cuáles son los principios / técnicas que se usarían para crear dicho archivo en primer lugar? No quiero hacer esto, estoy más interesado en una explicación simplificada de "conceptos prácticos" de los conceptos involucrados.

PD

El artículo menciona 9 capas de archivos zip, por lo que no es un simple caso de comprimir un montón de ceros. ¿Por qué 9, por qué 10 archivos en cada uno?


El artículo menciona 9 capas de archivos zip, por lo que no es un simple caso de comprimir un montón de ceros. ¿Por qué 9, por qué 10 archivos en cada uno?

En primer lugar, el artículo de Wikipedia actualmente dice 5 capas con 16 archivos cada una. No estoy seguro de dónde proviene la discrepancia, pero no es tan relevante. La verdadera pregunta es por qué usar el anidamiento en primer lugar.

DEFLATE, el único método de compresión admitido comúnmente para archivos zip *, tiene una relación de compresión máxima de 1032. Esto se puede lograr de forma asintótica para cualquier secuencia repetitiva de 1-3 bytes. No importa lo que haga en un archivo comprimido, siempre que solo use DEFLATE, el tamaño desempaquetado será como máximo 1032 veces el tamaño del archivo zip original.

Por lo tanto, es necesario usar archivos zip anidados para lograr proporciones de compresión realmente escandalosas. Si tiene 2 capas de compresión, la proporción máxima se convierte en 1032 ^ 2 = 1065024. Para 3, es 1099104768, y así sucesivamente. Para las 5 capas utilizadas en 42.zip, la relación de compresión máxima teórica es 1170572956434432. Como puede ver, el 42.zip real está lejos de ese nivel. Parte de eso es la sobrecarga del formato zip, y parte de eso es que simplemente no les importó.

Si tuviera que adivinar, diría que 42.zip se formó con solo crear un archivo grande y vacío, y comprimirlo y copiarlo repetidamente. No hay ningún intento de superar los límites del formato o maximizar la compresión o cualquier otra cosa, simplemente recogen arbitrariamente 16 copias por capa. El objetivo era crear una gran carga útil sin mucho esfuerzo.

Nota: Otros formatos de compresión, como bzip2, ofrecen relaciones de compresión máximas mucho, mucho, mucho mayores. Sin embargo, la mayoría de los analizadores zip no los aceptan.

PS Es posible crear un archivo zip que se descomprimirá en una copia de sí mismo (un quine). También puede crear uno que se descomprima en varias copias de sí mismo. Por lo tanto, si descomprime recursivamente un archivo para siempre, el tamaño máximo posible es infinito. La única limitación es que puede aumentar a lo sumo 1032 en cada iteración.

PPS La cifra 1032 supone que los datos del archivo en el zip son disjuntos. Una peculiaridad del formato de archivo zip es que tiene un directorio central que enumera los archivos en el archivo y los desplaza a los datos del archivo. Si crea varias entradas de archivos que apuntan a los mismos datos, puede lograr relaciones de compresión mucho más altas incluso sin anidar, pero es probable que los analizadores rechacen dicho archivo.


A continuación es para Windows:

De la prueba de concepto de Security Focus (NSFW!), Es un archivo ZIP con 16 carpetas, cada una con 16 carpetas, que continúa así (42 es el nombre del archivo comprimido):

/ 42 / lib 0 / book 0 / chapter 0 / doc 0 / 0.dll
...
/ 42 / lib F / book F / chapter F / doc F / 0.dll

Probablemente estoy equivocado con esta cifra, pero produce 4 ^ 16 (4,294,967,296) directorios. Debido a que cada directorio necesita espacio de asignación de N bytes, termina siendo enorme. El archivo dll al final es 0 bytes.

Descomprimimos el primer directorio solo /42/lib 0/book 0/chapter 0/doc 0/0.dll resulta en 4 /42/lib 0/book 0/chapter 0/doc 0/0.dll de espacio de asignación.


Algoritmos de compresión recientes (después de 1995) como bz2, lzma (7-zip) y rar ofrecen una compresión espectacular de archivos monótonos, y una sola capa de compresión es suficiente para envolver el contenido sobredimensionado a un tamaño manejable.

Otro enfoque podría ser crear un archivo disperso de tamaño extremo (exabytes) y luego comprimirlo con algo mundano que comprenda los archivos dispersos (por ejemplo, alquitrán), ahora si el examinador transmite el archivo, el examinador deberá leer más allá de todos los ceros que existen solo para rellenar el contenido real del archivo, si el examinador lo escribe en el disco, sin embargo, se usará muy poco espacio (suponiendo que un desarchivo con buen comportamiento y un sistema de archivos moderno).


Citando de la página de Wikipedia:

Un ejemplo de una bomba Zip es el archivo 45.1.zip que contenía 45.1 kilobytes de datos comprimidos, que contenía nueve capas de archivos zip anidados en conjuntos de 10, cada archivo de capa inferior contenía un archivo de 1.30 gigabytes para un total de 1.30 exabytes de datos sin comprimir .

Entonces, todo lo que necesita es un único archivo de 1.3 GB lleno de ceros, comprimirlo en un archivo ZIP, hacer 10 copias, empacarlas en un archivo ZIP y repetir este proceso 9 veces.

De esta forma, obtienes un archivo que, cuando se descomprime por completo, produce una cantidad absurda de datos sin que sea necesario comenzar con esa cantidad.

Además, los archivos anidados hacen que sea mucho más difícil para los programas como los escáneres de virus (el objetivo principal de estas "bombas") ser inteligentes y se niegan a desempacar los archivos que son "demasiado grandes", porque hasta el último nivel la cantidad total de datos no tanto, no "ve" qué tan grandes son los archivos en el nivel más bajo hasta que haya alcanzado ese nivel, y cada archivo individual no es "demasiado grande"; solo el gran número es problemático.


Crea un archivo de ceros de 1.3 exabytes.

Haga clic derecho> Enviar a la carpeta comprimida (comprimida).


El episodio 7 de la temporada 3 de Silicon Valley me trajo aquí. Los pasos para generar una bomba zip serían.

  1. Crea un archivo ficticio con ceros (o unos si crees que son delgados) de tamaño (digamos 1 GB).
  2. Comprima este archivo en un archivo zip, digamos 1.zip .
  3. Haga n (digamos 10) copias de este archivo y agregue estos 10 archivos a un archivo comprimido (digamos 2.zip ).
  4. Repita el paso 3 k número de veces.
  5. Obtendrás una bomba zip.

Para una implementación de Python, verifique this .


Esto se hace fácilmente bajo Linux usando el siguiente comando:

dd if=/dev/zero bs=1024 count=10000 | zip zipbomb.zip -

Reemplace recuento con la cantidad de KB que desea comprimir. El ejemplo anterior crea una bomba zip 10MiB (no mucho de una bomba, pero muestra el proceso).

NO NECESITA espacio en el disco duro para almacenar todos los datos sin comprimir.


Lo intenté. el tamaño del archivo zip de salida era un pequeño archivo de 84 KB.

Pasos que hice hasta ahora:

  1. crea un archivo .txt de 1.4 GB lleno de ''0''
  2. comprimirlo
  3. cambie el nombre de .zip a .txt y luego haga 16 copias
  4. comprimir todo en un archivo .zip,
  5. renombrar los archivos .txt renombrados dentro del archivo .zip en .zip nuevamente
  6. repita los pasos 3 a 5 ocho veces.
  7. Disfruta :)

aunque no sé cómo explicar la parte donde la compresión del archivo zip renombrado todavía lo comprime en un tamaño más pequeño, pero funciona. Tal vez me faltan los términos técnicos.


No sé si ZIP utiliza Run Length Encoding, pero si lo hiciera, dicho archivo comprimido contendría una pequeña porción de datos y un gran valor de longitud de tirada. El valor de longitud de ejecución especificará cuántas veces se repite la pequeña porción de datos. Cuando tiene un valor muy grande, los datos resultantes son proporcionalmente grandes.


Para crear uno en un entorno práctico (es decir, sin crear un archivo 1.3 exabyte en tu enorme disco duro), probablemente tendrías que aprender el formato de archivo en un nivel binario y escribir algo que se traduzca a cómo se vería el archivo deseado, post- compresión.


Respuesta seria:

(Muy básicamente) La compresión se basa en detectar patrones de repetición, por lo que el archivo comprimido contendrá datos que representan algo así como

0x100000000000000000000000000000000000 (Repeat this ''0'' ten trillion times)

Archivo zip muy corto, pero enorme cuando lo expandes.


Tal vez, en Unix, podría canalizar una cierta cantidad de ceros directamente en un programa zip o algo así? Sin embargo, no sé lo suficiente sobre Unix para explicar cómo lo harías. Aparte de eso, necesitaría una fuente de ceros, y póngalos en una cremallera que lea de stdin o algo así ...


Todos los algoritmos de compresión de archivos se basan en la entropy de la información que se comprimirá. En teoría, puedes comprimir una secuencia de 0 o 1, y si es lo suficientemente larga, se comprimirá muy bien.

Esa es la parte de la teoría. La parte práctica ya ha sido señalada por otros.


Una buena forma de crear una zipbomb (o gzbomb) es conocer el formato binario al que apunta. De lo contrario, incluso si usa un archivo de transmisión (por ejemplo, usando /dev/zero ), seguirá teniendo limitaciones para calcular la potencia necesaria para comprimir la transmisión.

Un buen ejemplo de una bomba gzip: http://selenic.com/googolplex.gz57 (hay un mensaje incrustado en el archivo después de varios niveles de compresión que da como resultado archivos enormes)

Diviértete encontrando ese mensaje :)