ディレクトリインデックス ($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 の時刻とサイズとともに存在していました。スラックエントリだけでは、取り除かれた時刻や、削除・名前変更・インデックスの再配置のどれによるものかは判断できません。
保存場所と収集¶
$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 のセクタに名前を付けます。
調査戦略¶
- スラック内のサマリーの非コピー名から始めて、
--slack-only --no-copiesでフィルターします。 $MFTでFileEntryを調べます。同じFileSequenceは同じファイルを意味します。値が大きいほど、レコードがその後解放され、おそらく再利用されたことを意味します。- USN Journal で名前を検索し、いつ削除または名前変更されたかを確認します。
- タイムストンピングの
$FILE_NAME時間と$MFTの$STANDARD_INFORMATION時間を比較します。 - ファイルがどのように使用されたかについて、Prefetch、LNK、Jump Lists、およびイベント ログと関連付けます。
さらに詳しい情報¶
- Microsoft: マスター ファイル テーブル
- libfsntfs: NTFS 形式のドキュメント
- dfir_ntfs
- INDXリッパー
- ys-ntfs-parser (
mftクレートのi30モジュール)