Indeks direktori ($I30)¶
Apa itu $I30¶
Setiap direktori NTFS menyimpan indeks berkas-berkas di dalamnya, yang dinamai $I30. Direktori kecil menyimpannya di
record $MFT miliknya ($INDEX_ROOT); direktori yang lebih besar juga memiliki record INDX, biasanya masing-masing 4.096 byte, di
sebuah stream $INDEX_ALLOCATION:$I30. Setiap entri indeks menyimpan salinan $FILE_NAME milik berkas: nama,
referensi MFT, direktori induk, empat timestamp, dan dua ukuran, sebagaimana kondisinya saat terakhir kali NTFS
memperbarui entri tersebut.
Ketika sebuah berkas dihapus atau di-rename keluar dari suatu direktori, NTFS menghapus entrinya dan menggeser entri-entri
setelahnya. Byte lama tetap berada di slack record INDX, melewati entri-entri yang sedang digunakan, hingga
entri-entri berikutnya menimpanya. Index slack dapat menyimpan nama, waktu, dan ukuran sebuah berkas yang
record $MFT-nya telah digunakan ulang dan record Jurnal USN-nya telah tertimpa (roll over).
Kesimpulan terbaik: sebuah nama yang ditemukan di index slack pernah, pada suatu
waktu, berada di indeks direktori ini dengan waktu dan ukuran $FILE_NAME yang tercatat. Sebuah entri slack tidak
menyatakan kapan entri itu dihapus, atau apakah berkasnya dihapus, di-rename, atau dipindahkan karena penyeimbangan ulang (rebalancing).
Lokasi dan pengumpulan¶
$I30 adalah metadata NTFS: kumpulkan dengan alat forensik yang mendukung akses raw dan dapat mengekspor stream
$I30 sebuah direktori (berkas hasil ekspor sering dinamai $I30). Juntei juga dapat mencari record INDX di image disk atau
ruang yang tidak teralokasi. Kumpulkan juga $MFT dan $J dari volume yang sama, untuk mengetahui apa
sebenarnya entri-entri slack tersebut.
Peringatan bagi analis¶
- Index slack bersifat parsial dan tidak berurutan. Entri ditimpa seiring perubahan direktori; nama yang tidak ditemukan tidak membuktikan apa pun.
- Banyak entri slack merupakan salinan dari entri yang masih digunakan, tertinggal ketika entri dipindahkan.
CopyOfEntryInUsemenandainya. Nama terhapus yang sama juga dapat muncul di slack beberapa kali. - Waktu di sebuah entri indeks adalah waktu
$FILE_NAMEsebagaimana kondisinya pada pembaruan terakhir entri tersebut. Waktu ini dapat berbeda dari waktu$STANDARD_INFORMATIONmaupun waktu$FILE_NAMEdi record$MFTmilik berkas. AllocatedSizedanRealSizejuga merupakan nilai pada pembaruan terakhir entri, dan dapat sudah usang.FileEntry(atauParentEntry) sebuah entri slack bisa hilang jika byte yang ditulis kemudian menimpanya. Jika ada, record MFT yang dirujuknya mungkin telah digunakan ulang sejak saat itu: bandingkan sequence number-nya.parse-ntfs i30membaca record INDX. Indeks direktori kecil hanya ada di record$MFT-nya ($INDEX_ROOT); berkas-berkasnya ada di$MFT.
Mengurai dengan 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
Ringkasan mencantumkan record INDX (dan berapa banyak yang hanya tertulis sebagian), entri yang digunakan dan yang berada di slack, serta nama-nama entri slack yang bukan salinan persis dari entri yang digunakan. Nama-nama tersebut merupakan kandidat berkas yang dihapus atau di-rename, bukan kesimpulan dengan sendirinya.
Field keluaran CSV¶
| Field | Interpretasi |
|---|---|
SourcePath |
Berkas input; membedakan host dan direktori. |
RecordOffset, EntryOffset |
Offset byte record INDX dan entri di dalam input. Penting untuk validasi dan untuk record yang ditemukan di image disk. |
RecordVCN, RecordLSN |
Posisi record di dalam stream indeks dan sequence number $LogFile-nya. |
FromSlack |
True untuk entri yang ditemukan melewati entri-entri yang digunakan. |
CopyOfEntryInUse |
Entri slack dengan nama, namespace, berkas (jika diketahui), induk, dan waktu yang sama dengan entri yang digunakan di indeks direktori yang sama. Biasanya merupakan sisa dari pemindahan entri, bukan berkas yang dihapus. |
Filename |
Nama di dalam direktori. |
Namespace |
win32, dos (nama pendek 8.3), win32_and_dos, atau posix. |
FileEntry, FileSequence |
Referensi MFT milik berkas. Kosong untuk entri slack yang header-nya telah ditimpa. |
ParentEntry, ParentSequence |
Referensi MFT milik direktori. Kosong jika byte lain telah menimpanya. |
CreatedUTC, ModifiedUTC, MFT-ModifiedUTC, AccessedUTC |
Waktu $FILE_NAME, dengan presisi 100 ns, sebagaimana kondisinya pada pembaruan terakhir entri. |
AllocatedSize, RealSize |
Ukuran yang disalin NTFS ke dalam entri; lihat peringatan di atas. |
FileAttributes |
Nama-nama atribut yang digabungkan dengan | (hidden|archive); is_directory untuk subdirektori. Bit yang tidak dinamai oleh versi Juntei ini dipertahankan dalam heksadesimal (0x00800000). |
ReparseValue |
Tag reparse atau ukuran extended attribute dari $FILE_NAME. |
Problems |
Kerusakan pada record, seperti sektor yang hanya tertulis sebagian. Entri dari record yang rusak tetap layak ditinjau, dengan hati-hati. |
JSON/JSONL memiliki field yang sama dalam snake_case, dengan problems sebagai list dan null untuk nilai
yang tidak diketahui.
Bagaimana entri slack ditemukan¶
Slack dipindai pada setiap batas 8 byte, tempat entri dimulai, untuk mencari entri utuh,
atribut $FILE_NAME yang header entrinya telah ditimpa, dan, di awal slack, sebuah
$FILE_NAME yang referensi induknya ditimpa oleh akhir entri-entri yang digunakan. Sebuah kandidat harus menyerupai
apa yang ditulis Windows: nama UTF-16 yang valid tanpa karakter kontrol atau pemisah path, empat
waktu antara tahun 1980 dan 2100, namespace yang dikenal, dan flag atribut yang dikenal. Referensi induk yang melampaui
32 bit merupakan byte yang ditimpa dan dibiarkan kosong.
Update sequence array setiap record diterapkan. Sektor yang tidak diakhiri dengan nilai update sequence
hanya tertulis sebagian; Juntei membaca record apa adanya dan menyebutkan sektor-sektor tersebut di Problems.
Strategi investigasi¶
- Mulailah dengan nama-nama di slack yang bukan salinan dari ringkasan, lalu filter dengan
--slack-only --no-copies. - Cari
FileEntrydi$MFT.FileSequenceyang sama berarti berkas yang sama; nilai yang lebih tinggi berarti record tersebut telah dibebaskan sejak saat itu, dan mungkin digunakan ulang. - Cari nama tersebut di Jurnal USN untuk mengetahui kapan berkas itu dihapus atau di-rename.
- Bandingkan waktu
$FILE_NAMEdengan waktu$STANDARD_INFORMATIONdi$MFTuntuk mendeteksi timestomping. - Korelasikan dengan Prefetch, LNK, Jump Lists, dan log peristiwa untuk mengetahui bagaimana berkas tersebut digunakan.
Detail lebih lanjut¶
- Microsoft: Master File Table
- libfsntfs: Dokumentasi format NTFS
- dfir_ntfs
- INDXRipper
- ys-ntfs-parser (modul
i30dari cratemft-nya)