Lewati ke isi

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

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

$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. CopyOfEntryInUse menandainya. Nama terhapus yang sama juga dapat muncul di slack beberapa kali.
  • Waktu di sebuah entri indeks adalah waktu $FILE_NAME sebagaimana kondisinya pada pembaruan terakhir entri tersebut. Waktu ini dapat berbeda dari waktu $STANDARD_INFORMATION maupun waktu $FILE_NAME di record $MFT milik berkas.
  • AllocatedSize dan RealSize juga merupakan nilai pada pembaruan terakhir entri, dan dapat sudah usang.
  • FileEntry (atau ParentEntry) 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 i30 membaca 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

  1. Mulailah dengan nama-nama di slack yang bukan salinan dari ringkasan, lalu filter dengan --slack-only --no-copies.
  2. Cari FileEntry di $MFT. FileSequence yang sama berarti berkas yang sama; nilai yang lebih tinggi berarti record tersebut telah dibebaskan sejak saat itu, dan mungkin digunakan ulang.
  3. Cari nama tersebut di Jurnal USN untuk mengetahui kapan berkas itu dihapus atau di-rename.
  4. Bandingkan waktu $FILE_NAME dengan waktu $STANDARD_INFORMATION di $MFT untuk mendeteksi timestomping.
  5. Korelasikan dengan Prefetch, LNK, Jump Lists, dan log peristiwa untuk mengetahui bagaimana berkas tersebut digunakan.

Detail lebih lanjut