コンテンツにスキップ

ディレクトリインデックス ($I30)

$I30とは

すべての NTFS ディレクトリには、$I30 という名前のファイルのインデックスが保持されます。小さなディレクトリの $MFT レコード ($INDEX_ROOT) に保存されます。より大きなレコードには、$INDEX_ALLOCATION:$I30 ストリーム内に INDX レコード (通常はそれぞれ 4,096 バイト) が含まれます。各インデックス エントリには、ファイルの $FILE_NAME のコピー (NTFS が最後にエントリを更新した時点の名前、MFT 参照、親ディレクトリ、4 つのタイムスタンプ、および 2 つのサイズ) が保持されます。

ファイルがディレクトリから削除されるか、名前が変更されると、NTFS はそのエントリを削除し、その後にエントリを移動します。古いバイトは、使用中のエントリを超えて、後のエントリで上書きされるまで、INDX レコードの slack に残ります。インデックス スラックは、$MFT レコードが再利用され、USN ジャーナル レコードがロールオーバーされたファイルの名前、時刻、サイズを保持できます。

この証拠から判断できること: インデックススラック内の名前は、過去のある時点で、このディレクトリのインデックスに、記載された $FILE_NAME の時刻とサイズとともに存在していました。スラックエントリだけでは、取り除かれた時刻や、削除・名前変更・インデックスの再配置のどれによるものかは判断できません。

保存場所と収集

C:\<directory>:$I30:$INDEX_ALLOCATION

$I30 は NTFS メタデータです。ディレクトリの $I30 ストリームをエクスポートできる RAW 対応フォレンジック ツールを使用して収集します (エクスポートされたファイルの名前は、$I30 であることがよくあります)。 Juntei は、ディスク イメージまたは未割り当て領域で INDX レコードを検索することもできます。同じボリュームの $MFT と $J も収集して、スラック エントリが何であったかを確認します。

分析時の注意点

  • インデックス スラックは partial および unordered です。ディレクトリが変更されると、エントリは上書きされます。名前がなくなっても何も証明されません。
  • スラック エントリの多くは、エントリが移動したときに残された、まだ使用されているエントリのコピーです。 CopyOfEntryInUse はそれらをマークします。削除された同じ名前が複数回スラックに存在することもあります。
  • インデックス エントリの時間は、エントリの最終更新時点での $FILE_NAME 時間です。これらは、ファイルの $MFT レコードの $STANDARD_INFORMATION 時間と $FILE_NAME 時間の両方とは異なる場合があります。
  • AllocatedSize と RealSize もエントリの最終更新時点のものであり、古い可能性があります。
  • スラック エントリの FileEntry (または ParentEntry) は、後のバイトによって上書きされると失われる可能性があります。存在する場合、その名前が付けられている MFT レコードが再利用されている可能性があります。シーケンス番号を比較してください。
  • parse-ntfs i30 は INDX レコードを読み取ります。小さなディレクトリのインデックスは、$MFT レコード ($INDEX_ROOT) にのみ存在します。そのファイルは $MFT にあります。

Juntei で解析する

Usage: juntei parse-ntfs i30 <INPUT> [OPTIONS]

Input:
  -d, --directory <DIR>  Recursively find $I30 files (with $I30 in their name, or starting with an INDX record)
  -f, --file <FILE>      Parse one $I30 stream, or any file holding INDX records (a disk image, unallocated space)

Filtering:
      --slack-only  Only the entries found in slack
      --no-copies   Leave out the slack entries that copy an entry in use

Output:
  -o, --output <FILE>       Save every entry
  -t, --output-type <TYPE>  csv, json, or jsonl
juntei parse-ntfs i30 -f 'Users_$I30'
juntei parse-ntfs i30 -d evidence/ -o i30.csv
juntei parse-ntfs i30 -f 'Users_$I30' --slack-only --no-copies -t jsonl
juntei parse-ntfs i30 -f disk.raw -o carved-i30.csv

概要には、INDX レコード (および部分的に書き込まれたレコードの数)、使用中およびスラック中のエントリ、および使用中のエントリの正確なコピーではないスラック エントリの名前がリストされます。これらの名前は削除または名前変更されたファイルの候補であり、それ自体が判断を下すものではありません。

CSV 出力フィールド

フィールド 解釈
SourcePath 入力ファイル。ホストとディレクトリを区別します。
RecordOffset, EntryOffset INDX レコードと入力のエントリのバイト オフセット。検証およびディスク イメージ内で見つかったレコードに不可欠です。
RecordVCN, RecordLSN インデックス ストリーム内のレコードの位置とその $LogFile シーケンス番号。
FromSlack 使用中のエントリの後に見つかったエントリの True。
CopyOfEntryInUse 同じディレクトリ インデックスを使用するエントリと同じ名前、名前空間、ファイル (既知の場合)、親、および時刻を持つ Slack エントリ。通常は、削除されたファイルではなく、移動したエントリの残り物です。
Filename ディレクトリ内の名前。
Namespace win32、dos (8.3 の短縮名)、win32_and_dos、または posix。
FileEntry, FileSequence ファイルの MFT 参照。ヘッダーが上書きされた Slack エントリの場合は空です。
ParentEntry, ParentSequence ディレクトリの MFT 参照。他のバイトが上書きされた場合は空になります。
CreatedUTC, ModifiedUTC, MFT-ModifiedUTC, AccessedUTC エントリの最終更新時点で、$FILE_NAME 倍から 100 ns まで。
AllocatedSize, RealSize サイズ NTFS がエントリにコピーされます。上記の注意事項を参照してください。
FileAttributes | (hidden|archive) で結合された属性名。サブディレクトリの場合は is_directory。この Juntei バージョンに名前が付けられていないビットは、16 進数 (0x00800000) で保持されます。
ReparseValue $FILE_NAME からのタグまたは拡張属性のサイズを再解析します。
Problems 部分的に書き込まれたセクターなど、レコードの損傷。破損したレコードからのエントリは、慎重にレビューする必要があります。

JSON/JSONL には、snake_case に同じフィールドがあり、problems はリストとして、null は不明な値を表します。

スラックエントリーの発見方法

スラックは、8 バイト境界ごとにスキャンされます。エントリ全体の場合、エントリ ヘッダーが上書きされた $FILE_NAME 属性の場合、およびスラックの開始時に、使用中のエントリの末尾が親参照によって上書きされた $FILE_NAME の場合、エントリが開始されます。候補は、Windows が書き込むものと同じである必要があります。つまり、制御文字やパス区切り文字を含まない有効な UTF ~ 16 名、1980 と 2100 の間に 4 回ある、既知の名前空間、既知の属性フラグです。 32 ビット以降の親参照はバイトで上書きされ、空のままになります。

各レコードの更新順序配列が適用されます。更新シーケンス値で終わらないセクターが部分的に書き込まれました。 Juntei はレコードをそのまま読み取り、Problems のセクタに名前を付けます。

調査戦略

  1. スラック内のサマリーの非コピー名から始めて、--slack-only --no-copies でフィルターします。
  2. $MFT で FileEntry を調べます。同じ FileSequence は同じファイルを意味します。値が大きいほど、レコードがその後解放され、おそらく再利用されたことを意味します。
  3. USN Journal で名前を検索し、いつ削除または名前変更されたかを確認します。
  4. タイムストンピングの $FILE_NAME 時間と $MFT の $STANDARD_INFORMATION 時間を比較します。
  5. ファイルがどのように使用されたかについて、Prefetch、LNK、Jump Lists、およびイベント ログと関連付けます。

さらに詳しい情報