search

Found

info 概要

ドラッグしたファイルまたは貼り付けた16進数の先頭64バイトから、PNG / JPEG / PDF / ZIP など40種以上のファイル形式とMIMEタイプを判定。拡張子との不一致も自動で警告

📘 使い方

  1. ファイルを選ぶか16進数を貼り付け
  2. 先頭バイトから検出されたフォーマットとMIMEタイプを確認
  3. 拡張子と実体が食い違う場合の警告を確認

マジックバイト判定

※ 選んだファイル本体はあなたのブラウザ内だけで読み取られ、外部に送信されません。

search

ファイルをドロップするか16進数を貼り付けると、検出結果が表示されます。

※ 先頭64バイトの署名のみで判定するため、ペイロード後半に隠された二次フォーマット(ポリグロット)までは検出できません。

Article

マジックバイト判定 | 拡張子を信用せず先頭バイトでファイル種別を見抜く

config.exe という名前なのに中身は ZIP、.png を偽装した polyglot、添付された report.pdf の正体は実は SVG。拡張子と Content-Type は嘘をつくが、ファイルの先頭バイト (magic bytes / file signature) は嘘をつかない。このツールはドラッグしたファイルの先頭 64 バイトだけをブラウザ内で読み取り、PNG・JPEG・PDF・ZIP・MP4 から ELF / PE / Mach-O・SQLite・WOFF まで 40 種類以上のシグネチャと突き合わせて、本当の MIME タイプを判定する。

💡 このツールについて

ファイルアップロード機能を書くと、「拡張子チェックだけで弾ける」と思ってしまうのが最初の罠だ。ユーザーは payload.exeimage.png に rename して上げてくる。サーバー側で Content-Type を信用すると、攻撃者が multipart/form-data の boundary に好きな MIME を書いて送ってくる。残った砦が「ファイルの先頭数バイトを読んでマジックナンバーで判定する」方式で、Linux の file コマンドや Python の python-magic がやっていることそのものだ。

このツールはその判定をブラウザ内で完結させる。ファイル本体はサーバーに送信されず、FileReader.readAsArrayBuffer で先頭 64 バイトだけが読み取られる。判定された一致バイトは緑色でハイライトされ、ZIP コンテナの場合は docx / xlsx / pptx / jar / apk / epub のいずれである可能性があると追加警告が出る。

ファイル本体が手元になく forensic dump の先頭バイトだけがある場合は「16進数モード」で 89 50 4E 47 0D 0A 1A 0A のような並びを直接貼って判定できる。0x プレフィックス、スペース、カンマ、コロン、改行などの区切り文字は自動で除去される。

🧐 よくある質問

Q. なぜ 64 バイトしか読まないのか? ほとんどのフォーマットのシグネチャは先頭 16 バイト以内に収まる。ISO 9660 のように offset 0x8001 まで進む例外はあるが、その手のフォーマットは「ファイル先頭でない場所にあるマジックバイト」をすでに信用していないので、ブラウザでサクッと判定する用途には 64 バイトで十分。何より、ファイル全体をメモリに載せないので 1 GB のディスクイメージでもサクサク動く。

Q. ZIP コンテナとして検出されたが、本当に docx か xlsx かは分からないの? 分からない。docx / xlsx / pptx / odt / epub / jar / apk / kmz / kml はすべて ZIP コンテナ (PK\x03\x04) で始まる。中身の [Content_Types].xmlMETA-INF/MANIFEST.MF を見ないと区別がつかない構造になっている。このツールはコンテナ判定までで止まり、警告カードでぶら下がりフォーマット候補を列挙する。中身まで掘りたい場合は unzip して構造ファイル名を確認する。

Q. polyglot ファイルは検出できる? 専用の polyglot 検出は持っていない。シグネチャテーブルを順に走査して最初に一致したものを返す方式なので、同じバイト列が複数フォーマットとして解釈できる場合でも片方のみが報告される。ZIP コンテナ系の「中身が docx か jar か」というあいまいさだけは container 警告で別途知らせる。本格的に polyglot を掘る場合は binwalkfile -k (keep going) を併用するとよい。

Q. 拡張子の不一致警告はどういう仕組み? ファイル名から拡張子を取り出し (/\.([a-z0-9]{1,8})$/)、署名から導かれたフォーマットの拡張子候補リストに含まれていなければ赤色で警告する。例えば invoice.pdf という名前で PK\x03\x04 (= ZIP) が出てきたら「.pdf vs .zip/.docx/.xlsx/...」と表示される。

Q. テキストファイルは判定できる? プレーンテキストには固定のシグネチャがないため「既知の署名に一致なし」になる。XML / SVG のように先頭が <?xml のものや RTF ({\rtf) のように特定リテラルで始まるものは検出可能。

Q. ファイルはどこかに送信される? されない。FileReader でブラウザ内のメモリにだけ読み込み、ハッシュも取らず、サーバーにも分析サービスにも送らない。Network タブを見ても判定中のリクエストは出ない。フォレンジック調査や CTF の add-on で「外部に出せないバイナリ」を扱うシチュエーションで使える。

📚 豆知識

ファイルシグネチャ研究の参照先として一番有名なのは Gary Kessler が運営する File Signatures のリストで、2024 年時点で 700 種類以上のフォーマットがカタログ化されている。Wikipedia の "List of file signatures" もメンテされており、特に動画コンテナ (MP4 の ftyp ボックスのバリエーション、Matroska の EBML) や圧縮形式 (ZSTD の Frame Magic Number) の更新が早い。日本国内だと CASB / SIEM ベンダーが社内向けに独自のシグネチャ DB を持っており、Office 系の旧 Compound File Binary Format (CFBF、Office 97-2003) の D0 CF 11 E0 などレガシーフォーマットの判定もそこで行われている。

ZIP コンテナ系の判定で実務的に厄介なのが Android の APK と Java の JAR だ。両方とも ZIP だが、APK は META-INF/CERT.SF、JAR は META-INF/MANIFEST.MF の有無で見分ける。さらに最近の AAB (Android App Bundle) は ZIP だが構造が APK と違うので、unzip した上で BundleConfig.pb を探す必要がある。LibreOffice の ODT も ZIP で、最初のエントリ名が mimetype (無圧縮) であることが規格で決まっており、これだけは ZIP のローカルヘッダを読まずに先頭 30 バイト目あたりを見れば判定できる珍しいパターンとして知られている。