ファイル情報はどこまで改竄できるか?

なるほど!touchコマンド一つで、こんなことができるのか。早速、試してみる。

作業環境

touchコマンド

$ touch test_file

$ getfileinfo test_file
file: "/Users/zari/Desktop/test_file"
type: "\0\0\0\0"
creator: "\0\0\0\0"
attributes: avbstclinmedz
created: 12/10/2010 04:14:48
modified: 12/10/2010 04:14:48

$ touch -t 199901011234.56 test_file

$ getfileinfo test_file
file: "/Users/zari/Desktop/test_file"
type: "\0\0\0\0"
creator: "\0\0\0\0"
attributes: avbstclinmedz
created: 01/01/1999 12:34:56
modified: 01/01/1999 12:34:56

$ touch -t 200001010123.45 test_file

$ getfileinfo test_file
file: "/Users/bebe/Desktop/test_file"
type: "\0\0\0\0"
creator: "\0\0\0\0"
attributes: avbstclinmedz
created: 01/01/1999 12:34:56
modified: 01/01/2000 01:23:45
  • できた、できた。-tオプションでYYYYMMDDhhmm.SS(年月日日時.秒) と指定すればその日時に修正されるのだ。(簡単!)
  • ところが、作成日時の入力が間違っていて、実は12:34:56ではなく12:43:56だったとしたら修正できるだろうか?(悩む...)
    • -aオプションは、アクセス日時*1のみ変更する。
    • -mオプションは、更新日時*2のみ変更する。

あれ、ファイルの作成日時を変更するオプションがない!

  • よくよく考えてみると、コマンド名はtouch、つまり「触る」という意味。
  • きっとtouchコマンドは、そのファイルに触るだけなのである。
  • -tオプションで日時を指定したら、その日時に触るだけ。
  • 日時を更新しているのは、あくまでOS側なのである。

だから... 

  • 指定した日時が作成日時よりも古ければ、作成日時・更新日時・アクセス日時を更新する。
  • 指定した日時が作成日時よりも新しければ、作成日時はそのまま。更新日時・アクセス日時のみ更新する。
  • たとえ-aや-mを指定しても、作成日時より古い日時であると、作成日時も更新する。

SetFileコマンド

では、一旦古い作成日時を設定してしまうと、より新しい作成日時への修正は出来なくなってしまうのだろうか?

  • 実は別のコマンドが用意されていた。
$ setfile -d '01/01/1999 12:43:56' test_file

$ getfileinfo test_file
file: "/Users/bebe/Desktop/test_file"
type: "\0\0\0\0"
creator: "\0\0\0\0"
attributes: avbstclinmedz
created: 01/01/1999 12:43:56
modified: 01/01/2000 01:23:45

無事、修正できた!

  • どうやら、setfileコマンド自体がファイル情報をダイレクトに書き換えるようだ。
  • なんと、作成日時が更新日時よりも新しい、という矛盾する設定も出来てしまった。
  • -mオプションで、更新日時を修正することもできる。
  • その他、以下のファイル属性情報も修正できる。
$ setfile -h
Usage: SetFile [option...] file...
    -a attributes     # attributes (lowercase = 0, uppercase = 1)*
    -c creator        # file creator
    -d date           # creation date (mm/dd/[yy]yy [hh:mm[:ss] [AM | PM]])*
    -m date           # modification date (mm/dd/[yy]yy [hh:mm[:ss] [AM | PM]])*
    -P		      # perform action on symlink instead of following it
    -t type           # file type
...(中略)...
  • ここまで、作成日時・更新日時については自由に変更できるようになった。
  • 普段OSXのFinderで眺めていると、それだけで十分な気がするが、ファイルを操作した時に更新される日時はまだあった。

アクセス日時

  • そもそも、touchコマンドの -aオプションはアクセス日時のみ更新するオプションであった。
  • アクセス日時とは、ファイルを開いた時に更新される日時。以下のタイミングで更新された。
    • アプリケーションでファイルを開いた時。
    • Finderの「情報を見る」を開いている時。
    • Finderでファイル名を変更した時。
    • Finder・mvコマンドで別のフォルダへ移動した時。
    • touchコマンドを実行した時。(変更日も修正される)
  • lsコマンドの -luTオプションで、アクセス日時を秒単位まで確認できる。
$ ls -luT test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:12:02 2010 test_file
  • ところで、アクセス日時も-atオプションで指定できるのかと思っていたら、以下のようになった。
$ touch -at 199901011234.56 test_file
$ ls -luT test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:15:12 2010 test_file
  • 指定した -tオプションの日時は無視され、おそらくコマンドを実行した日時が設定された。
  • 任意のアクセス日時を指定することはできないのだろうか?

ステータス更新日時

  • さらに、ステータス更新日時という概念もあるらしい。
  • ファイルを保存、あるいはinodeデータを変更した時に更新される日時。
  • HFS+にはinodeという概念はないが、以下のタイミングで更新された。
    • ファイルのアクセス権を変更した時。
    • ハードリンクを作成・削除した時。
    • touchコマンドを実行した時。(変更日時も修正される)
    • 「情報を見る」で、Spotlightコメント:、ラベル:、ひな形:、ロック:、共有とアクセス権:を変更した時。
    • 「情報を見る」で、このアプリケーションで開く:を変更した時。(変更日も修正される)
  • lsコマンドの -lcTオプションで、ステータス更新日時を秒単位まで確認できる。
$ ls -lcT test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:12:02 2010 test_file

4つの日時

  • ここまで、ファイルにまつわる4つの日時があることがわかった。
    • 作成日時(ls -lU)
    • 更新日時(ls -l)
    • アクセス日時(ls -lu)
    • ステータス更新日時(ls -lc)
  • 全部まとめて、lsコマンドで確認してみようと思う。
$ n='test_file'; ls -lUT $n; ls -lT $n; ls -luT $n; ls -lcT $n;
 -rw-r--r--  1 zari  staff  0  1  1 12:34:56 1999 test_file
 -rw-r--r--  1 zari  staff  0  8  8 12:34:56 2000 test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:24:04 2010 test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:24:04 2010 test_file
  • 4つの日時の中で、アクセス日時とステータス更新日時については、任意の日時に設定する方法が分からなかった...。


  • statコマンド、というのがあった。
  • 左から、アクセス日時(atime)、更新日時(mtime)、ステータス更新日時(ctime)、作成日時のようだ。
$ stat ~/Desktop/test_file 
234881026 2238428 -rw-r--r-- 1 bebe staff 0 1 "Dec 26 05:40:28 2010" "Dec 26 05:30:01 2010" "Dec 26 05:40:20 2010" "Dec 26 05:21:30 2010" 4096 8 0 /Users/bebe/Desktop/test_file

$ stat -t "%Y-%m-%d %H:%M:%S" ~/Desktop/test_file 
234881026 2238428 -rw-r--r-- 1 bebe staff 0 1 "2010-12-26 05:40:28" "2010-12-26 05:30:01" "2010-12-26 05:40:20" "2010-12-26 05:21:30" 4096 8 0 /Users/bebe/Desktop/test_file

mdls

  • OSX 10.4以降、Spotlightという検索システムの仕組みが出来た。
  • それを実現するために、ファイルは常時監視され、メタデータがデータベースに記録されることとなった。
  • 新規にファイルを作成すると、以下のメタデータが付属する。
$ rm test_file
$ touch -t 199901011234.56 test_file

$ n='test_file'; ls -lUT $n; ls -lT $n; ls -luT $n; ls -lcT $n;
 -rw-r--r--  1 bebe  staff  0  1  1 12:34:56 1999 test_file
 -rw-r--r--  1 bebe  staff  0  1  1 12:34:56 1999 test_file
 -rw-r--r--  1 bebe  staff  0 12 10 05:37:00 2010 test_file
 -rw-r--r--  1 bebe  staff  0 12 10 05:37:00 2010 test_file

$ mdls test_file
kMDItemContentCreationDate     = 1999-01-01 12:34:56 +0900
kMDItemContentModificationDate = 1999-01-01 12:34:56 +0900
kMDItemContentType             = "public.data"
kMDItemContentTypeTree         = (
    "public.data",
    "public.item"
)
kMDItemDisplayName             = "test_file"
kMDItemFSContentChangeDate     = 1999-01-01 12:34:56 +0900
kMDItemFSCreationDate          = 1999-01-01 12:34:56 +0900
kMDItemFSCreatorCode           = ""
kMDItemFSFinderFlags           = 0
kMDItemFSHasCustomIcon         = 0
kMDItemFSInvisible             = 0
kMDItemFSIsExtensionHidden     = 0
kMDItemFSIsStationery          = 0
kMDItemFSLabel                 = 0
kMDItemFSName                  = "test_file"
kMDItemFSNodeCount             = 0
kMDItemFSOwnerGroupID          = 20
kMDItemFSOwnerUserID           = 501
kMDItemFSSize                  = 0
kMDItemFSTypeCode              = ""
kMDItemKind                    = "書類"
kMDItemLastUsedDate            = 1999-01-01 12:34:56 +0900
kMDItemUsedDates               = (
    "1999-01-01 00:00:00 +0900"
)
  • 更新してみる。
$ touch -t 200012310123.45 test_file

$ n='test_file'; ls -lUT $n; ls -lT $n; ls -luT $n; ls -lcT $n;
 -rw-r--r--  1 zari  staff  0  1  1 12:34:56 1999 test_file
 -rw-r--r--  1 zari  staff  0 12 31 01:23:45 2000 test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:38:10 2010 test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:38:09 2010 test_file

$ mdls test_file
kMDItemContentCreationDate     = 1999-01-01 12:34:56 +0900
kMDItemContentModificationDate = 2000-12-31 01:23:45 +0900
kMDItemContentType             = "public.data"
kMDItemContentTypeTree         = (
    "public.data",
    "public.item"
)
kMDItemDisplayName             = "test_file"
kMDItemFSContentChangeDate     = 2000-12-31 01:23:45 +0900
kMDItemFSCreationDate          = 1999-01-01 12:34:56 +0900
kMDItemFSCreatorCode           = ""
kMDItemFSFinderFlags           = 0
kMDItemFSHasCustomIcon         = 0
kMDItemFSInvisible             = 0
kMDItemFSIsExtensionHidden     = 0
kMDItemFSIsStationery          = 0
kMDItemFSLabel                 = 0
kMDItemFSName                  = "test_file"
kMDItemFSNodeCount             = 0
kMDItemFSOwnerGroupID          = 20
kMDItemFSOwnerUserID           = 501
kMDItemFSSize                  = 0
kMDItemFSTypeCode              = ""
kMDItemKind                    = "書類"
kMDItemLastUsedDate            = 2000-12-31 01:23:45 +0900
kMDItemUsedDates               = (
    "1999-01-01 00:00:00 +0900",
    "2000-12-31 00:00:00 +0900"
)
  • mdlsの出力下部 kMDItemUsedDates に注目。
  • 利用履歴として上書きされず、追加された。
  • さらに更新してみる。
$ touch -t 200105050654.32 test_file

$ n='test_file'; ls -lUT $n; ls -lT $n; ls -luT $n; ls -lcT $n;
 -rw-r--r--  1 zari  staff  0  1  1 12:34:56 1999 test_file
 -rw-r--r--  1 zari  staff  0  5  5 06:54:32 2001 test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:39:56 2010 test_file
 -rw-r--r--  1 zari  staff  0 12 10 05:39:56 2010 test_file

$ mdls test_file
kMDItemContentCreationDate     = 1999-01-01 12:34:56 +0900
kMDItemContentModificationDate = 2001-05-05 06:54:32 +0900
kMDItemContentType             = "public.data"
kMDItemContentTypeTree         = (
    "public.data",
    "public.item"
)
kMDItemDisplayName             = "test_file"
kMDItemFSContentChangeDate     = 2001-05-05 06:54:32 +0900
kMDItemFSCreationDate          = 1999-01-01 12:34:56 +0900
kMDItemFSCreatorCode           = ""
kMDItemFSFinderFlags           = 0
kMDItemFSHasCustomIcon         = 0
kMDItemFSInvisible             = 0
kMDItemFSIsExtensionHidden     = 0
kMDItemFSIsStationery          = 0
kMDItemFSLabel                 = 0
kMDItemFSName                  = "test_file"
kMDItemFSNodeCount             = 0
kMDItemFSOwnerGroupID          = 20
kMDItemFSOwnerUserID           = 501
kMDItemFSSize                  = 0
kMDItemFSTypeCode              = ""
kMDItemKind                    = "書類"
kMDItemLastUsedDate            = 2001-05-05 06:54:32 +0900
kMDItemUsedDates               = (
    "1999-01-01 00:00:00 +0900",
    "2000-12-31 00:00:00 +0900",
    "2001-05-05 00:00:00 +0900"
)
  • kMDItemUsedDates には3件の利用履歴が記録されている。
  • さらに今度はtest_fileをダブルクリックして開いて、すぐ閉じてみた。(テキストエディットが起動した)
$ mdls test_file
kMDItemContentCreationDate     = 1999-01-01 12:34:56 +0900
kMDItemContentModificationDate = 2001-05-05 06:54:32 +0900
kMDItemContentType             = "public.data"
kMDItemContentTypeTree         = (
    "public.data",
    "public.item"
)
kMDItemDisplayName             = "test_file"
kMDItemFSContentChangeDate     = 2001-05-05 06:54:32 +0900
kMDItemFSCreationDate          = 1999-01-01 12:34:56 +0900
kMDItemFSCreatorCode           = ""
kMDItemFSFinderFlags           = 0
kMDItemFSHasCustomIcon         = 0
kMDItemFSInvisible             = 0
kMDItemFSIsExtensionHidden     = 0
kMDItemFSIsStationery          = 0
kMDItemFSLabel                 = 0
kMDItemFSName                  = "test_file"
kMDItemFSNodeCount             = 0
kMDItemFSOwnerGroupID          = 20
kMDItemFSOwnerUserID           = 501
kMDItemFSSize                  = 0
kMDItemFSTypeCode              = ""
kMDItemKind                    = "書類"
kMDItemLastUsedDate            = 2010-12-10 05:54:31 +0900
kMDItemUsedDates               = (
    "1999-01-01 00:00:00 +0900",
    "2000-12-31 00:00:00 +0900",
    "2001-05-05 00:00:00 +0900",
    "2010-12-10 00:00:00 +0900"
)
  • なんと、アクセスするだけで利用履歴に追加されていくのだ!
  • OSXでは基本的にファイル監視され、メタデータベースに記録されているので、メタデータの履歴のことも考えておく必要がある。
  • GetFileInfoやlsコマンドで上書きされる日時の辻褄が合っていても、メタデータとして利用履歴が残っているかもしれないのだ。

記録メディアの状態

さらに、さらに、

  • 仮に、もし上記の状態をすべて任意の日時に設定できたとしても、まだ改竄の足跡は残る。
  • ハードディスク、USBメモリフロッピーディスク等に記録されているデータ(バイトコード)の並びを見られるかもしれない。
  • もし、上書きされたものであるなら、元メディアのデータの並びとは異なっているはずである。(すぐバレる)
    • 俗に言うデフラグとは、何度も上書きされて、データの並びが飛び飛びになってしまった状態を解消することである。

しかし、

  • 発想を変えれば、余分なことを考えずにメディアのデータの並びさえ同一にしておけば、
  • あとは必要な部分のバイトコードを書き換えるだけで改竄できるということかもしれない。

そうだとしても、

  • 必要な部分がどこか、任意の情報はどんなバイトコードになるのか、それが問題だ...。

発想の転換

  • MacBookをネットワークから切り離して、OS自体の現在時刻を過去に戻してしまう方法もありかもしれない。
  • でも、任意の日時を秒単位まで合わせるのは結構大変かも。

所感

  • すべての整合性を保って改竄するには、それなりの技術と知識が必要だ。


完璧に改竄できる人は、おそらく ハッカー と呼ばれるのだろう。

*1:ファイルを開いた時(readした時)に更新される日時

*2:ファイルを保存した時(writeした時)に更新される日時