如何制作拉链炸弹?

这个关于邮政炸弹的问题自然让我进入了维基百科的主题页面 。 本文提到了一个解压缩到1.3 EB的45.1 kb zip文件的例子。

什么是原则/技术将用于创build这样的文件呢? 我不想实际做到这一点,更多的是对所涉概念的简化的“如何作品”的解释感兴趣。

PS

这篇文章提到了9层的zip文件,所以这不是一个压缩一堆零的简单情况。 为什么9,为什么每个文件有10个?

从维基百科页面引用:

一个Zip炸弹的例子是文件45.1.zip,它是45.1千字节的压缩数据, 包含九层嵌套的zip文件,每层10个,每个底层存档包含一个1.30千兆字节的文件 ,总共1.30艾字节的未压缩数据。

因此,您只需要一个1.3GB的文件,将其压缩成一个ZIP文件,制作10个副本,将这些文件打包成一个ZIP文件,然后重复这个过程9次。

这样,你得到一个文件,当完全解压缩时,会产生一个荒谬的数据量,而不需要你从这个数量开始。

此外,嵌套的档案使病毒扫描程序(这些“炸弹”的主要目标)变得更加智能,并且拒绝解压“太大”的档案,因为直到最后一级数据总量没有那么多,你不会“看到”最低级别的文件有多大,直到达到这个级别,每个单独的文件不是“太大” – 只有大数目是有问题的。

创build一个1.3 exabyte文件的零。

右键单击>发送到压缩(压缩)文件夹。

这很容易在Linux下使用以下命令完成:

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

将计数replace为要压缩的KB数。 上面的例子创build了一个10MiB的拉链炸弹(根本不是一个炸弹,但它显示了这个过程)。

您不需要硬盘空间来存储所有未压缩的数据。

以下是针对Windows的:

从安全焦点概念validation (NSFW!)开始,它是一个带有16个文件夹的ZIP文件,每个文件夹都有16个文件夹,如下所示(42是zip文件名):

\ 42 \ lib 0 \ book 0 \ chapter 0 \ doc 0 \ 0.dll

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

我可能是错误的这个数字,但它产生4 ^ 16(4,294,967,296)的目录。 因为每个目录需要N个字节的分配空间,所以结果是巨大的。 最后的dll文件是0字节。

解压缩第一个目录\42\lib 0\book 0\chapter 0\doc 0\0.dll导致4gb的分配空间。

严肃的回答:

(非常基本)压缩依靠发现重复模式,所以压缩文件将包含表示类似的数据

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

非常短的zip文件,但是当你扩展它时很大。

要在实际环境中创build一个文件(即不需要在您的硬盘上创build一个1.3字节的文件),您可能需要在二进制级别学习文件格式,然后编写一些能够转化为所需文件的文件格式,压缩。

这篇文章提到了9层zip文件,所以这不是一个压缩一堆零的简单情况。 为什么9,为什么每个文件有10个?

首先,维基百科的文章目前说5层,每个16个文件。 不知道差异来自哪里,但并不是那么重要。 真正的问题是为什么首先使用嵌套。

DEFLATE是ZIP压缩文件唯一常用的压缩方法*,最大压缩比为1032.对于1-3字节的任何重复序列,这可以渐近地实现。 不pipe你做了什么压缩文件,只要使用DEFLATE,解压后的大小最多是原始压缩文件大小的1032倍。

因此,有必要使用嵌套的zip文件来实现非常大的压缩率。 如果你有2层压缩,最大比率变成1032 ^ 2 = 1065024. 3,1099104768,依此类推。 对于42.zip中使用的5个层,理论上的最大压缩比是1170572956434432。正如你所看到的,实际的42.zip与这个层次相差甚远。 其中一部分就是zip格式的开销,其中一部分是他们根本不在乎。

如果我不得不猜测,我会说,42.zip是由创build一个大的空文件,并重复压缩和复制它形成的。 没有尝试推动格式的限制或最大化压缩或任何东西 – 他们只是任意select每层16个副本。 关键是不费很大的努力就能创造一个大的有效载荷。

注意:其他压缩格式(例如bzip2)可提供更大的最大压缩比。 但是,大多数zipparsing器不接受它们。

PS可以创build一个zip文件,将其解压缩到自己的副本(一个quine)。 你也可以制作一个解压缩到自己的多个副本。 因此,如果你recursion地解压缩一个文件,最大可能的大小是无限的。 唯一的限制是每次迭代最多可以增加1032个。

PPS 1032图假定zip中的文件数据是不相交的。 压缩文件格式的一个怪癖是它有一个中央目录,它列出了档案中的文件和文件数据的偏移量。 如果您创build了多个指向相同数据的文件条目,即使没有嵌套,也可以实现更高的压缩比率,但这样的zip文件可能会被parsing器拒绝。

创build一个zipbomb(或gzbomb)的一个好方法是知道你的目标二进制格式。 否则,即使使用stream文件(例如使用/dev/zero ),仍然会受到压缩stream所需的计算能力的限制。

gzip炸弹的一个很好的例子: http : //selenic.com/googolplex.gz57 (经过几个级别的压缩后,在文件中embedded了一条消息导致大文件)

玩得开心find那个消息:)

也许,在UNIX上,你可以直接将一定数量的零input到一个zip程序或其他东西? 不太了解unix解释你将如何做到这一点。 除此之外,你将需要一个零源,并将其pipe入一个拉链,从标准input或其他东西读取…

所有的文件压缩algorithm都依赖于要压缩的信息的熵 。 理论上你可以压缩一个0或1的数据stream,如果它足够长,它会压缩得很好。

这是理论部分。 其实际部分已被别人指出。

试过了。 输出的zip文件大小是一个小的84 KB的文件。

我到目前为止的步骤:

  1. 创build一个充满'0'的1.4 GB的.txt文件
  2. 压缩它。
  3. 将.zip重命名为.txt,然后制作16个副本
  4. 把它压缩成一个.zip文件,
  5. 再次将.zip文件中重命名的.txt文件重命名为.zip
  6. 重复步骤3至5八次。
  7. 请享用 :)

虽然我不知道如何解释重命名压缩文件的压缩仍然压缩到一个较小的大小,但它的作品。 也许我只是缺乏技术术语。

我不知道ZIP是否使用“运行长度编码”,但是如果是这样的话,这样的压缩文件将包含一小段数据和一个非常大的运行长度值。 运行长度值将指定重复一小段数据的次数。 当你有一个非常大的值时,结果数据是相当大的。

最近(1995年以后)的压缩algorithm,如bz2,lzma(7-zip)和rar给出了单调文件的壮观压缩,单层压缩足以将超大内容包装成可pipe理的大小。

另一种方法是创build一个极端大小的稀疏文件(exabytes),然后用一些理解稀疏文件(比如焦油)的世俗文件压缩它,现在如果审查员将文件传输到审查员需要读取的文件,只是在文件的实际内容之间进行填充,如果审查员将其写入磁盘,则将使用很less的空间(假设performance良好的unarchiver和现代文件系统)。

硅谷第3季第7集把我带到这里。 生成一个拉链炸弹的步骤是。

  1. 创build一个带有零(或者如果你认为他们很瘦)的虚拟文件的大小(比如说1GB)。
  2. 压缩这个文件到压缩文件说1.zip
  3. 制作n (比如10)这个文件的副本,并将这10个文件添加到一个压缩存档(比如2.zip )。
  4. 重复步骤3 k次。
  5. 你会得到一个拉链炸弹。

对于Python实现,请检查这一点 。