古典的なサービス拒否アーカイブは再帰型zip爆弾だった。42.zipは6層のzipファイルを入れ子にし、解凍ツールが入れ子のアーカイブを解凍し続けた場合にのみ4.5 PBに達する。実際のパーサーのほとんどは1回しか解凍しないため、最上層は取るに足らない0.6 MBしか生み出さず、スキャナーは再帰の深さと展開後サイズに上限を設けて防御していた。誰もが知っていた攻撃は木の形をしていた。

David Fifieldの手法は再帰を取り除くことだった。彼は繰り返しバイトの単一カーネルを圧縮し、数万のセントラルディレクトリエントリをそれらバイトの重複する範囲に向け、その間に挟まる各ローカルファイルヘッダーをDEFLATEの非圧縮ブロック内に引用することで、通常のパーサーには依然として別個の整形式ファイルが見えるようにした。カーネルの各バイトはファイルごとに1回展開されるため、出力は入力に対して二次関数的に増大し、爆弾は1回の解凍で起爆する。

数値は以前のあらゆる構築物を凌駕した。42.zipの外層のサイズである42,374バイトでは、アーカイブは5.5 GBに展開される(比率129,000)。10 MB版は281 TBに展開され、比率は2,800万を超え、zip形式の理論上の最大値の99.97%に達する。Zip64拡張を使えば、46 MBが4.5 PBに展開される。USENIXはこの論文をWOOT 2019ワークショップに採録し、Best Paperを授与した。

この公開は業界の防御の実地テストとなった。10 MBサンプルのVirusTotalスキャンは多くのエンジンでタイムアウトした。ClamAVは検出がパッチされるまでCPUを焼き続け、その後再びパッチされた。Mark AdlerはUnZip向けの重複ファイル検出器を書き、Debianはそれを出荷したがSUSEは拒否した(CVE-2019-13232)。Chromiumは異常な圧縮率の指標を追加し、AppleはiOS 14でiOS Quick Lookのキャッシュ枯渇を緩和した。

多数のファイルを単一の圧縮カーネル上で重複させ、格納された各バイトがN回展開されるようにする

標準的な防御の前提を攻撃する。スキャナーは再帰の深さを制限していたため、1回で完全に展開する爆弾はディスクを溢れさせるまで普通に見える。

重複により比率は超線形になる。格納された各バイトがすべての出力ファイルに寄与するため、アーカイブは層ごとに固定の係数を加えるのではなく、大きくなるほど危険度が増す。

互換性は一致する名前、正しいCRC、平文のDEFLATEによって組み込まれ、デモは特殊ケースではなくInfo-ZIP、Python、Go、Androidのパーサーで動作した。

Fifieldは動作するサンプルを公開し、攻撃を修正策、重複検出、パーサーファンドボクシングと組み合わせることで、珍品をベンダーが採用できるパッチに変えた。

防御側がある形の攻撃にパッチを当てたら、形を変える。重複ファイルは再帰を任意にし、深さ制限を無用にした。署名を列挙するのではなく、パーサー内で時間とディスクを制限する。

Mark Adlerの重複検出器はUnZipとDebianに到達し、ClamAVは当初隣接ペアのみを検査し、その後時間制限を課した。Dのstd.zipは重複を拒否するようになり、Chromiumは異常比率の指標を追加し、AppleはiOS 14でiOS 12/13のQuick Look枯渇を緩和した。VirusTotalはタイムアウトした文書化済みエンジンを記録し、アンチウイルスベンダーは2019年を通じて検出を更新した。Google Safe Browsingは2019年7月下旬から8月中旬にかけてbamsoftware.com全体にフラグを立て、TorのSnowflakeブローカーを一時的に壊し、Xfinityは2019年11月にページをブロックした。FifieldはUSENIX WOOT 2019でBest Paperを受賞した。

出典をたどる

出典

  1. A better zip bomb David Fifield · bamsoftware.com
  2. A better zip bomb (Best Paper), USENIX WOOT 19 USENIX Association · usenix.org
  3. A better zip bomb — Hacker News discussion Hacker News · news.ycombinator.com ·