この質問 Zip爆弾について自然に私は Wikipediaページ トピックに導いた。この記事では、1.3エクサバイトに圧縮解除する45.1 kb Zipファイルの例を挙げています。
そもそもこのようなファイルを作成するために使用される原則/技術は何ですか?私は実際にこれを行いたくありません。関連する概念の単純化された「how-stuff-works」の説明にもっと興味があります。
追伸.
この記事では9層のZipファイルに言及しているため、ゼロの塊を圧縮するという単純なケースではありません。なぜ9、なぜそれぞれ10ファイルですか?
ウィキペディアのページから引用:
Zip爆弾の1つの例は、45.1.Zipの45.1キロバイトの圧縮データでした。10のセットにネストされたZipファイルの9つの層を含み、各最下層のアーカイブには1.30ギガバイトのファイルが含まれます合計1.30エクサバイトの非圧縮データ。
必要なのは、ゼロでいっぱいの1つの1.3GBファイルを1つだけ圧縮し、それをZipファイルに圧縮し、10個のコピーを作成し、Zipファイルにパックして、このプロセスを9回繰り返します。
この方法では、完全に圧縮解除すると、その量で開始することなく、不当な量のデータを生成するファイルを取得します。
さらに、ネストされたアーカイブにより、ウイルススキャナー(これらの「爆弾」の主なターゲット)などのプログラムがスマートになり、「大きすぎる」アーカイブのアンパックが拒否されます。それほど多くはありませんが、最下位レベルのファイルがどれくらい大きいかは、そのレベルに到達するまで「表示」されず、個々のファイルは「大きすぎ」ません-膨大な数だけが問題になります。
ゼロの1.3エクサバイトファイルを作成します。
右クリック>圧縮(zip形式)フォルダーに送信します。
これは、Linuxで次のコマンドを使用して簡単に実行できます。
dd if=/dev/zero bs=1024 count=10000 | Zip zipbomb.Zip -
Countを、圧縮するKBの数に置き換えます。上記の例では、10MiBのZip爆弾を作成します(爆弾はそれほど多くありませんが、プロセスを示しています)。
すべての非圧縮データを保存するのにハードディスクの空き容量は必要ありません。
以下はWindows用です。
セキュリティフォーカスの概念実証 (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の割り当てスペースになります。
深刻な答え:
(基本的に)圧縮は繰り返しパターンの発見に依存するため、Zipファイルには次のようなデータが含まれます。
0x100000000000000000000000000000000000
(Repeat this '0' ten trillion times)
非常に短いZipファイルですが、展開すると巨大になります。
実際の設定で(つまり、巨大なハードドライブに1.3エクサバイトのファイルを作成せずに)作成するには、おそらくバイナリレベルでファイル形式を学習し、目的のファイルのように見えるものに変換するものを書く必要があります。圧縮。
この記事では9層のZipファイルに言及しているため、ゼロの塊を圧縮するという単純なケースではありません。なぜ9、なぜそれぞれ10ファイルですか?
まず、Wikipediaの記事では、現在、それぞれ16個のファイルを持つ5つのレイヤーについて説明しています。不一致の原因は定かではありませんが、それほど重要ではありません。本当の問題は、最初にネストを使用する理由です。
DEFLATEは、Zipファイルで唯一一般的にサポートされている圧縮方法*であり、最大圧縮率は1032です。これは、1〜3バイトの繰り返しシーケンスに対して漸近的に達成できます。 DEFLATEのみを使用している限り、Zipファイルをどのように処理しても、解凍されたサイズは元のZipファイルのサイズの最大1032倍になります。
そのため、ネストされたZipファイルを使用して、本当にとんでもない圧縮率を実現する必要があります。 2層の圧縮がある場合、最大比は1032 ^ 2 = 1065024になります。3の場合、1099104768などになります。 42.Zipで使用される5つのレイヤーの理論上の最大圧縮率は1170572956434432です。ご覧のとおり、実際の42.Zipはそのレベルからはほど遠いです。その一部はZip形式のオーバーヘッドであり、その一部は単に気にかけなかったことです。
推測しなければならない場合、42.Zipは大きな空のファイルを作成し、それを繰り返し圧縮してコピーすることによって形成されたと言えます。フォーマットの限界を押し広げたり、圧縮などを最大化する試みはありません-レイヤーごとに16個のコピーを勝手に選んだだけです。ポイントは、大きな労力をかけずに大きなペイロードを作成することでした。
注:bzip2などの他の圧縮形式では、最大の圧縮率がはるかに大きくなります。ただし、ほとんどのZipパーサーはそれらを受け入れません。
追伸自分自身のコピー(クイン)に解凍するZipファイルを作成することができます。自分自身の複数のコピーに解凍するものを作成することもできます。したがって、ファイルを再帰的に永久に解凍すると、可能な最大サイズは無限になります。唯一の制限は、各反復で最大1032まで増加できることです。
P.P.S. 1032の図は、Zip内のファイルデータがばらばらであると想定しています。 Zipファイル形式の特徴の1つは、アーカイブ内のファイルとファイルデータへのオフセットを一覧表示する中央ディレクトリがあることです。同じデータを指す複数のファイルエントリを作成すると、ネストなしでもはるかに高い圧縮率を実現できますが、そのようなZipファイルはパーサーによって拒否される可能性があります。
Zipbomb(またはgzbomb)を作成する良い方法は、対象のバイナリ形式を知ることです。それ以外の場合、ストリーミングファイルを使用していても(たとえば、/dev/zero
)ストリームを圧縮するために必要な計算能力によって制限されます。
Gzip爆弾の素敵な例: http://selenic.com/googolplex.gz57 (いくつかのレベルの圧縮の後にファイルに埋め込まれたメッセージがあり、巨大なファイルになります)
そのメッセージを見つけて楽しんでください:)
おそらく、Unixでは、一定量のゼロを直接Zipプログラムなどにパイプすることができますか?ただし、Unixについて十分に知らないで、それをどのように行うかを説明してください。それ以外には、ゼロのソースが必要になり、それらを標準入力または何かから読み取るジッパーにパイプします...
Bz2、lzma(7-Zip)、rarなどの最近の(1995年以降の)圧縮アルゴリズムは、単調なファイルの見事な圧縮を提供します。また、オーバーサイズのコンテンツを管理可能なサイズにラップするには、単一レイヤーの圧縮で十分です。
別のアプローチは、極端なサイズ(エクサバイト)のスパースファイルを作成し、スパースファイル(tarなど)を理解する普通のファイルで圧縮することです。審査官がディスクに書き込む場合、ファイルの実際のコンテンツの間にのみパディングしますが、使用されるスペースはごくわずかです(正常に機能するアンアーカイバと最新のファイルシステムを想定)。
それを試してみました。出力Zipファイルのサイズは、84 KBの小さなファイルでした。
これまでに行った手順:
ただし、名前を変更したZipファイルを圧縮してもまだ小さいサイズに圧縮される部分を説明する方法はわかりませんが、機能します。たぶん、専門用語が足りないだけかもしれません。
すべてのファイル圧縮アルゴリズムは、圧縮される情報の エントロピー に依存しています。理論的には、0または1のストリームを圧縮できます。十分に長い場合、非常によく圧縮されます。
それが理論の一部です。実用的な部分はすでに他の人から指摘されています。
シリコンバレーシーズン3エピソード7でここに来ました。 Zip爆弾を生成する手順は次のとおりです。
1.Zip
などのZipファイルに圧縮します。n
(たとえば10)のコピーを作成し、これらの10個のファイルを圧縮アーカイブ(たとえば2.Zip
)に追加します。k
を繰り返します。Python実装の場合、 this を確認してください。
ZipでRun Length Encodingを使用するかどうかはわかりませんが、使用する場合、そのような圧縮ファイルには小さなデータと非常に大きなランレングス値が含まれます。ランレングスの値は、小さなデータが繰り返される回数を指定します。値が非常に大きい場合、結果のデータは比例して大きくなります。