Sleuth Kit パーティション解析入門

背景

先日CTFの問題に初めて取り組んだ際、Digital Forensic の業界で有名な Sleuth Kit (TSK) というツールを使ってハードディスクのパーティションを覗いてみたので紹介します。
またTSKを使わずに物理で殴るやり方でTSKと同じ結果が得られる事を確認します。

ゴール

Dos パーティションを確認できるようになる。

準備

  • 作業用の端末:MacBookPro(15.3.0 Darwin
  • Sleuth Kit(v4.6.2)
  • hexdump
  • 解析対象のイメージファイル

作業端末の用意

Macを使います。
フォレンジックツールはMacだとCLIのものが多いのですが、
WindowsだとGUIが用意されてものが多いです。
ちなみにSleuth Kit の GUI版は Autopsy (Win/Mac対応)というものがあるみたいです。

Sleuth Kitのインストール

  1. ターミナルを開く
  2. 以下実行
    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
  3. 以下実行
    brew install sleuthkit --with-libewf --with-afflib

引用元:http://macappstore.org/sleuthkit/

今回は解析対象のイメージファイルがEncase形式なので、オプションの --with-libewf は必須となります。

解析対象のイメージファイルのダウンロード

  1. Daily Blog #451: Defcon DFIR CTF 2018 Open to the Publicにアクセス
  2. "Download Links" から Image1 だけをダウンロード
    ※およそ 11〜12GB のサイズです。容量に余裕を持ってください。
  3. 解凍する

ダウンロードファイルを解凍したものの中にHRServer_Disk0.e01というイメージファイルが含まれているはずです。 これが解析対象となります。

解析

TSK

mmlsコマンドを使います。パーティションレイアウトを確認できます。

$ mmls -i ewf HRServer_Disk0.e01 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0001026047   0001026048   Unallocated
002:  000:000   0001026048   0104857599   0103831552   NTFS / exFAT (0x07)

この結果からイメージの相対的な0001026048バイト目がファイルシステムの開始地点だとわかりました。

力技

素直にバイト列を眺めてみます。

encaseフォーマットだとよくわからないのでまず生のデータを取り出します。
パーティションレイアウトは最初の1セクタ分に格納されているので最初のセクタだけ取り出します。

$ img_cat -b 512 -e 1 -i ewf HRServer_Disk0.e01 > image.raw

次にhexdumpを使ってバイト列を表示します。

$ hexdump image.raw 
0000000 33 c0 8e d0 bc 00 7c 8e c0 8e d8 be 00 7c bf 00
0000010 06 b9 00 02 fc f3 a4 50 68 1c 06 cb fb b9 04 00
0000020 bd be 07 80 7e 00 00 7c 0b 0f 85 0e 01 83 c5 10
0000030 e2 f1 cd 18 88 56 00 55 c6 46 11 05 c6 46 10 00
0000040 b4 41 bb aa 55 cd 13 5d 72 0f 81 fb 55 aa 75 09
0000050 f7 c1 01 00 74 03 fe 46 10 66 60 80 7e 10 00 74
0000060 26 66 68 00 00 00 00 66 ff 76 08 68 00 00 68 00
0000070 7c 68 01 00 68 10 00 b4 42 8a 56 00 8b f4 cd 13
0000080 9f 83 c4 10 9e eb 14 b8 01 02 bb 00 7c 8a 56 00
0000090 8a 76 01 8a 4e 02 8a 6e 03 cd 13 66 61 73 1c fe
00000a0 4e 11 75 0c 80 7e 00 80 0f 84 8a 00 b2 80 eb 84
00000b0 55 32 e4 8a 56 00 cd 13 5d eb 9e 81 3e fe 7d 55
00000c0 aa 75 6e ff 76 00 e8 8d 00 75 17 fa b0 d1 e6 64
00000d0 e8 83 00 b0 df e6 60 e8 7c 00 b0 ff e6 64 e8 75
00000e0 00 fb b8 00 bb cd 1a 66 23 c0 75 3b 66 81 fb 54
00000f0 43 50 41 75 32 81 f9 02 01 72 2c 66 68 07 bb 00
0000100 00 66 68 00 02 00 00 66 68 08 00 00 00 66 53 66
0000110 53 66 55 66 68 00 00 00 00 66 68 00 7c 00 00 66
0000120 61 68 00 00 07 cd 1a 5a 32 f6 ea 00 7c 00 00 cd
0000130 18 a0 b7 07 eb 08 a0 b6 07 eb 03 a0 b5 07 32 e4
0000140 05 00 07 8b f0 ac 3c 00 74 09 bb 07 00 b4 0e cd
0000150 10 eb f2 f4 eb fd 2b c9 e4 64 eb 00 24 02 e0 f8
0000160 24 02 c3 49 6e 76 61 6c 69 64 20 70 61 72 74 69
0000170 74 69 6f 6e 20 74 61 62 6c 65 00 45 72 72 6f 72
0000180 20 6c 6f 61 64 69 6e 67 20 6f 70 65 72 61 74 69
0000190 6e 67 20 73 79 73 74 65 6d 00 4d 69 73 73 69 6e
00001a0 67 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74
00001b0 65 6d 00 00 00 63 7b 9a 0d 87 2c 5c 00 00 80 dd
00001c0 1f 3f 07 fe ff ff 00 a8 0f 00 00 58 30 06 00 00
00001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
0000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000400

ここでDosパーティションの構成は以下となっていますので

バイト範囲 意味
0-445 ブートコード
446-461 パーティションエントリ①
462-477 パーティションエントリ②
478-493 パーティションエントリ③
494-509 パーティションエントリ④
510-511 シグネチャ

さきほどの結果に当てはめてみるとこうなります。

バイト範囲 意味
0-445 ブートコード
446-461 パーティションエントリ① 80 DD 1F 3F 07 FE FF FF 00 A8 0F 00 00 58 30 06
462-477 パーティションエントリ② 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
478-493 パーティションエントリ③ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
494-509 パーティションエントリ④ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
510-511 シグネチャ 55 AA

どうやらパーティションエントリ①にしか値が格納されていないという事がわかりました。

次にパーティションエントリのバイト列がどういう意味をもつかというと

バイト範囲 意味
0-0 起動可能かを示すフラグ
1-3 CHS方式での開始アドレス
4-4 パーティションタイプ
5-7 CHS方式での終了アドレス
8-11 LBA方式での開始アドレス
12-15 セクタのサイズ

となっていますので、パーティションエントリ①のバイト列に適用するとこうなります。

バイト範囲 意味
0-0 起動可能かを示すフラグ 80
1-3 CHS方式での開始アドレス DD 1F 3F
4-4 パーティションタイプ 07
5-7 CHS方式での終了アドレス FE FF FF
8-11 LBA方式での開始アドレス 00 A8 0F 00
12-15 セクタのサイズ 00 58 30 06

まずパーティションタイプ07ファイルシステムNTFSであることを示しています。

次にLBA方式の開始アドレスを確認します。
このアドレスはリトルエンディアンなので左右をひっくり返した後に10進数に変換します。
00 A8 0F 00
-> 000FA800(16進)
-> 1026048(10進)

またセクタのサイズもリトルエンディアンで格納されているらしく、
同様に以下の10進数の値が得られます。
00 58 30 06
-> 06305800(16進)
-> 103831552(10進)

最初にmmlsコマンドを使って取得した結果と同じになっていますね。
ひとまずmmlsが何をしているか分かり満足です。

終わり。