TOOLPIPO LAB ZIP · 13条件
ZIPを展開する前に、どこまで確認できる?
二重拡張子、不自然なパス、実行形式、高い圧縮率など13種類のZIPを自作し、展開せずに何が分かるか確認しました。
公開日・検証日:2026年10月5日
結論
ZIPを展開しなくても、ファイル名・パス・拡張子・圧縮前後のサイズから、確認の手がかりを得られます。13条件では、二重拡張子、実行形式候補、不自然なパス、入れ子ZIP、高圧縮率などを区別して表示できました。
一方、ファイル内容がマルウェアか、実際に開いて安全かまでは判断できません。確認項目が0件でも、安全性を保証する結果ではありません。
検証概要
- 使用Tool・方法
- ZIP安全性チェッカーと同じ解析コードでZIPの名前・記録サイズを読取り
- 検証日・条件
- ・13種類のsynthetic fixture(自作の検証ファイル)
- 入力データ・処理
- Tool入力の外部送信0。OSへの展開0。内側ZIPの再帰解析0。サイト共通の広告・アクセス解析通信は別です。
- 再現用ファイル
- 13条件とREADMEをダウンロード/測定結果JSON
今回作った13種類のZIP
通常例は短いtext、自作の1ページPDF、単色の8×8 PNGを含みます。他の条件では1つの特徴を選び、同じToolで読み直しました。実在人物・企業・実データ、実行可能コード、マクロ、マルウェアは使用していません。
setup.exe・invoice.pdf.exe・book.xlsmの実バイトは短い無害textです。ファイルの拡張子を分類する試験であり、EXE・Officeとしての内容を検査する試験ではありません。
生成はfflate 0.8.3。測定では公開ToolのanalyzeBytesを呼び、全entryのfilterがfalseになることを確認しました。読み取った件数・サイズ・倍率・finding(確認項目)を保存しています。
二重拡張子は「dotが2つある」だけではない
invoice.pdf.exeは、実行形式候補1件と二重拡張子候補1件でした。最後の.exeに加え、その直前の.pdfが文書形式を思わせる組合せを見ています。
backup.tar.gzは二重拡張子0件で、入れ子の圧縮ファイルという情報1件でした。.tar.gzは既知の複合拡張子として扱われます。単にdotの数を数える判定ではありません。
.exeや.xlsmという名前から、内容は断定できない
setup.exeは実行・script関連形式の候補1件になりました。.exeという名前だから要確認になるのであって、内容がマルウェアだと判定したわけではありません。今回の中身はtextです。
book.xlsmはマクロ対応Office形式の候補1件でした。.xlsmだからVBAが存在すると判定しているわけではありません。このToolはOffice内部のVBAを読みません。
../や絶対パスを展開前に確認できる
../toolpipo-test-outside.txtから、展開先の外側を参照する可能性があるパス1件が表示されました。同じentryの..は末尾dotの条件にも合い、環境依存名という情報1件も付きました。確認項目の合計2件は、2つのファイルという意味ではありません。
/tmp/toolpipo-test.txtとC:\temp\toolpipo-test.txtは絶対パス候補2件でした。ZIP内の名前が絶対パス形式であることを検出しただけです。OSに実際に展開した場合の保存先や上書きは検証していません。
OWASPは、アーカイブを展開する処理が内部パスを適切に検証しない場合に、意図しない場所へ書き込める問題を説明しています。結果は展開ソフト側の処理にも依存します。今回の内側ZIPを普通に展開して試す必要はありません。OWASP WSTG:Archive Directory Traversal
ファイル名だけでも分かる確認候補がある
Readme.txtとreadme.txtは、大文字・小文字による衝突の可能性1件でした。OSやfilesystemで扱いが異なるため、必ず上書きされるとは限りません。
- 見た目
reportfinal.txt- 実際の文字列
report[U+200B]final.txt— reportとfinalの間に幅のない文字を1つ挿入
この名前は制御文字候補1件でした。U+200Bはzero-width space(幅のない空白)です。表示を分かりにくくする候補を挙げた結果であり、意図や内容の判定ではありません。
report.とfolder/name[末尾にspace]は環境依存名2件でした。21個のフォルダをつないだパスは、末尾のfile.txtも含めTool上で22階層あります。と表示されました。ここでの階層は空でないパス要素数で、フォルダだけの数ではありません。
入れ子ZIPの中までは確認していない
archives/inner.zipを含むZIPは、入れ子の圧縮ファイルという情報1件でした。存在と名前は分かりますが、inner.zipのentryや内容を再帰的に読み直してはいません。今回はinner.zip自体も短いreadme.txtから自作しています。
高い圧縮率は何を意味する?
文字Aを12,582,912 B(12 MiB)繰り返し、entryの圧縮後サイズは12,283 Bでした。entryの倍率は1,024.42倍で、高圧縮率候補1件となりました。
ZIP全体はヘッダーなどを含む12,405 Bです。Toolの要約に表示される展開倍率は、展開後合計÷ZIP全体のサイズで1,014.34倍。entryの倍率とは分母が違います。
現在のToolは、entryの展開後サイズが10×1024² B以上で、圧縮率1000倍以上なら候補を表示します。これはToolPipoの確認用の目安(heuristic)であり、規格上の危険ラインではありません。高圧縮率=ZIP bombとは断定しません。展開後サイズが大きい場合は、展開時に多くのメモリ・保存容量を必要とする可能性があります。
13条件の実測結果
「要確認」と「情報」を両方掲載しています。同じentryに複数の項目が付く場合があります。すべて生成したZIPを読み直した結果です。
| 条件 | Toolで確認できたこと | 断定できないこと |
|---|---|---|
通常の小さなZIPnormal.zip | 確認項目0件 | 安全性やファイル内容の正しさ |
実行形式の拡張子executable-extension.zip | 実行・script関連形式の候補 1件 | 実行内容・マルウェアの有無 |
二重拡張子double-extension.zip | 実行・script関連形式の候補 1件/二重拡張子で実際の形式を見落とす可能性 1件 | PDFや実行ファイルとしての内容 |
通常の複合拡張子compound-extension.zip | 入れ子の圧縮ファイル 1件 | 圧縮ファイルの中身 |
マクロ対応Office形式macro-office.zip | マクロ対応Office形式 1件 | VBAやマクロの存在 |
入れ子ZIPnested-archive.zip | 入れ子の圧縮ファイル 1件 | inner.zip内のentryや内容 |
../を含むパスpath-traversal.zip | 展開先の外側を参照する可能性があるパス 1件/環境依存のファイル名 1件 | OS上で実際に展開した挙動 |
絶対パス形式absolute-path.zip | 絶対パスの可能性 2件 | OSや展開ソフトごとの保存先 |
大文字・小文字だけの違いcase-collision.zip | 環境によって名前が衝突する可能性 1件 | 上書きや衝突の発生 |
見えにくいUnicode文字invisible-character.zip | 表示を分かりにくくする制御文字を含む可能性 1件 | 内容や文字を入れた意図 |
末尾のdot・spaceenvironment-name.zip | 環境依存のファイル名 2件 | 各OS・filesystemでの扱い |
21フォルダの深いパスdeep-path.zip | 非常に深いフォルダ階層 1件 | OSやソフトでのパス長制限 |
高い圧縮率high-compression-ratio.zip | 極端に高い圧縮率候補 1件 | ZIP bombかどうかや安全性 |
サイズ・件数・倍率の実測値を見る
| 条件 | ZIP全体 | file / folder | 展開後合計 | 展開倍率 | 確認項目 |
|---|---|---|---|---|---|
| 通常の小さなZIP | 872 B | 3 / 2 | 513 B | 0.59倍 | 0件 |
| 実行形式の拡張子 | 270 B | 2 / 0 | 54 B | 0.20倍 | 1件 |
| 二重拡張子 | 157 B | 1 / 0 | 27 B | 0.17倍 | 2件 |
| 通常の複合拡張子 | 239 B | 1 / 0 | 114 B | 0.48倍 | 1件 |
| マクロ対応Office形式 | 145 B | 1 / 0 | 27 B | 0.19倍 | 1件 |
| 入れ子ZIP | 565 B | 2 / 2 | 174 B | 0.31倍 | 1件 |
| ../を含むパス | 183 B | 1 / 0 | 27 B | 0.15倍 | 2件 |
| 絶対パス形式 | 326 B | 2 / 0 | 54 B | 0.17倍 | 2件 |
| 大文字・小文字だけの違い | 272 B | 2 / 0 | 54 B | 0.20倍 | 1件 |
| 見えにくいUnicode文字 | 163 B | 1 / 0 | 27 B | 0.17倍 | 1件 |
| 末尾のdot・space | 270 B | 2 / 0 | 54 B | 0.20倍 | 2件 |
| 21フォルダの深いパス | 311 B | 1 / 0 | 27 B | 0.09倍 | 1件 |
| 高い圧縮率 | 12,405 B | 1 / 0 | 12,582,912 B | 1,014.34倍 | 1件 |
folderは末尾slashのある明示的なフォルダentryだけを数えます。パスにフォルダ名があるだけではfolder数は増えません。小さなZIPはヘッダーなどの比率が大きく、展開倍率が1倍未満になることもあります。
各ZIPのentry名と圧縮前後サイズを見る
通常の小さなZIP
documents/— フォルダentry、圧縮後 2 B、展開後 0 Bdocuments/readme.txt— file、圧縮後 29 B、展開後 27 Bdocuments/report.pdf— file、圧縮後 224 B、展開後 414 Bimages/— フォルダentry、圧縮後 2 B、展開後 0 Bimages/photo.png— file、圧縮後 67 B、展開後 72 B
実行形式の拡張子
setup.exe— file、圧縮後 29 B、展開後 27 Breadme.txt— file、圧縮後 29 B、展開後 27 B
二重拡張子
invoice.pdf.exe— file、圧縮後 29 B、展開後 27 B
通常の複合拡張子
backup.tar.gz— file、圧縮後 115 B、展開後 114 B
マクロ対応Office形式
book.xlsm— file、圧縮後 29 B、展開後 27 B
入れ子ZIP
documents/— フォルダentry、圧縮後 2 B、展開後 0 Bdocuments/readme.txt— file、圧縮後 29 B、展開後 27 Barchives/— フォルダentry、圧縮後 2 B、展開後 0 Barchives/inner.zip— file、圧縮後 92 B、展開後 147 B
../を含むパス
../toolpipo-test-outside.txt— file、圧縮後 29 B、展開後 27 B
絶対パス形式
/tmp/toolpipo-test.txt— file、圧縮後 29 B、展開後 27 BC:\temp\toolpipo-test.txt— file、圧縮後 29 B、展開後 27 B
大文字・小文字だけの違い
Readme.txt— file、圧縮後 29 B、展開後 27 Breadme.txt— file、圧縮後 29 B、展開後 27 B
見えにくいUnicode文字
report[U+200B]final.txt— file、圧縮後 29 B、展開後 27 B
末尾のdot・space
report.— file、圧縮後 29 B、展開後 27 Bfolder/name— file、圧縮後 29 B、展開後 27 B
21フォルダの深いパス
d01/d02/d03/d04/d05/d06/d07/d08/d09/d10/d11/d12/d13/d14/d15/d16/d17/d18/d19/d20/d21/file.txt— file、圧縮後 29 B、展開後 27 B
高い圧縮率
repeated.txt— file、圧縮後 12,283 B、展開後 12,582,912 B
このToolで分からないこと
- ファイル内容がマルウェアか、開く・実行する行為が安全か。
- ファイルのCRCや中身の完全性、拡張子と実データ形式が一致するか。
- マクロの有無、入れ子ZIPの中身、実際の展開先・上書き・名前の扱い。
- 暗号化・非対応の圧縮方式・破損などで解析できないZIPの全内容。
展開後サイズはZIPに記録された値です。偽のmetadataや非対応形式もあり得るため、実際に展開した量の保証ではありません。Toolは250MBまで・10000 entriesまでのZIPを扱い、結果の表示にも上限があります。
自分のZIPを確認する
展開する前に、ファイル名・パス・サイズの確認候補を見られます。結果が0件でも、安全性の証明にはなりません。
自分のZIPを展開前に確認する再現用ファイルとダウンロードの検証
検証用に意図的に不自然なentry名を含むZIPがあります。各inner ZIPを通常展開することを目的としたファイルではありません。ToolPipoのZIP checkerで確認してください。
outer ZIPにはREADME.txt・測定スナップショットresults.json・13個のZIPを相対名で収録しました。outerのentry名に../・絶対パスはなく、実行可能なバイナリも含みません。問題条件はinner ZIPの中だけです。
- ZIP全体のbytes
- 44,602 B
- SHA-256
becd33eb67382c0c0a9ee571d1eafff160891a3e4f3f47fb3b31543fca298a9b
公開results.jsonにも最終ZIPのbytesとSHA-256を記録しています。ZIP自身の最終ハッシュをZIPの中に入れると循環参照になるため、同梱JSONはハッシュ確定前の測定スナップショットです。測定値は公開JSONと同じです。
検証条件・一次資料
生成用ソース:13条件のfixture生成・測定コード。固定日時のZIPを生成し、公開Toolと同じ解析コードで再測定しました。PKWARE資料はZIPの名前・サイズが記録される構造の確認に、OWASP資料はパスと展開処理の関係の確認に使用しました。
- PKWARE ZIP File Format Specification 6.3.10:4.3.12 Central directory structure
- OWASP WSTG:Archive Directory Traversal
- fflate 0.8.3:unzipのfilterによる展開対象の制限
一次資料のZIP構造とToolPipo独自の1000倍という目安は別の事項です。今回、展開ソフト・OSごとの挙動や内容の安全性は検証していません。