fileコマンドとファイルのマジックナンバーについて

fileコマンドとファイルのマジックナンバーについて

Oct 15, 2019

先日CTFの勉強会に参加してきた。
勉強会といっても、今回参加したのは総まとめ回だったそうで、実践演習的な回だったが、、
運営側が用意した問題をそれぞれ解いていくという形式だったが、最初の問題から解けないという体たらくっぷりであったので、他の参加者や講師の方から教えて頂いたことだけでも備忘のために書いておく。

fileコマンド #

CTFは正体不明なファイルを渡されることが多いのだが、まずはそのファイルの形式を知るということから始めることが多いと思う。
普通、ファイルには.txtや.jpgなどといったような、ファイルの形式を示す文字列である「拡張子」というのがファイル名の末尾についており、ユーザーはこれを見ることによってそのファイルが何なのかを認識しているだろう。
しかし、拡張子もファイル名の一部なので、ユーザー側で自由かつ容易に変更することは可能であり、ファイルの拡張子がそのファイルの形式を示しているとは必ずしも限りはしない。
拡張子ではなく、ファイルの内容からそのファイルが何なのかを判別するにはどうすれば良いのか?

その際に使うのがUNIXの「file」コマンドである。
fileコマンドはファイルを引数としてとり、ファイルの内容を見ることでそのファイルのファイル形式を表示してくれるコマンドである。

使用法 #

$ file [オプション] ファイル

引数にファイルを指定する。

オプション #

  • -f・・・検査するファイルの名前をリストファイルから読み込む
  • -L・・・シンボリックリンクの参照先を調べる
  • -z・・・圧縮ファイルの中も調べる
  • -b・・・出力行の最初にファイル名を表示しない
  • -N・・・出力を整列するためのファイル名への空白の追加を行わない

マジックナンバー #

fileコマンドは拡張子(ファイル名)ではなくファイルの内容を見てファイル形式を確認するとは言ったが、具体的にはどのようにして判断しているのか?
と言うより、そもそもファイルの形式って拡張子ではなくどのようにして決められているものなのか?

その秘密がこのマジックナンバーと呼ばれるものである。 マジックナンバーとはファイルの特定の位置に記載されている、ファイルの種類を判別する識別子である。

マジックナンバーとは、ファイルなどオブジェクト類の形式を識別するもの、フォーマット識別子のことである。 フォーマット識別子としてのマジックナンバーとは、ファイルの種類を識別するのに使われるファイル本文中の(内容中の)特定の位置にある特定の数値のことである。 ファイルの種類を識別する方法としてはファイルの拡張子や属性値(プロパティ)を使う場合もあるが、マジックナンバーとはそれらのことではなく、ファイルの本文中に表れる特定の数値のことである。ほとんどの場合、マジックナンバーはファイルの先頭に位置し、数バイト程度である。(Wikipediaより)

マジックナンバーはファイルの先頭数バイトに記述されており、この値によってそのファイルの形式が何であるかと言うのが決定される。 fileコマンドはファイルの内容を見るとき、このマジックナンバーを見てそのファイルが何なのであるかを判別している、と言うわけだ。

マジックナンバーの定義ファイル #

マジックナンバーのリストはUNIX系OSの場合

/usr/share/file/magic

に定義されている(ディストリビューションの違い等により、定義ファイルは異なる場合もある)

このファイル内に、各ファイル形式ごとにマジックナンバーが書かれている模様。

例えばjpegは0xffd8となっている。