Індекси каталогів ($I30)¶
Що таке $I30¶
Кожен каталог NTFS зберігає індекс файлів, що в ньому містяться, під назвою $I30. Невеликий каталог зберігає його у
своєму записі $MFT ($INDEX_ROOT); більший також має записи INDX, зазвичай по 4 096 байтів кожен, у
потоці $INDEX_ALLOCATION:$I30. Кожен запис індексу містить копію $FILE_NAME файлу: його
ім'я, посилання MFT, батьківський каталог, чотири часові мітки та два розміри — станом на момент, коли NTFS
востаннє оновила запис.
Коли файл видаляють або перейменовують із переміщенням з каталогу, NTFS вилучає його запис і зсуває записи,
що йдуть після нього. Старі байти залишаються в slack запису INDX, за межами записів, що використовуються, доки
їх не перезапишуть пізніші записи. Index slack може зберігати ім'я, час і розмір файлу, чий
запис $MFT було повторно використано і чиї записи журналу USN уже перезаписано циклічно.
Найобґрунтованіший висновок: ім'я, знайдене в index slack, у певний
момент було в індексі цього каталогу із зазначеними часом і розмірами $FILE_NAME. Запис зі slack
не повідомляє, коли його вилучено, а також чи було файл видалено, перейменовано або переміщено під час перебалансування.
Розташування та збирання¶
$I30 — це метадані NTFS: збирайте їх криміналістичним інструментом із підтримкою сирого доступу, який може експортувати потік
$I30 каталогу (експортовані файли часто мають назву $I30). Juntei також може шукати записи INDX в образі диска або
в нерозподіленому просторі. Зберіть також $MFT і $J того самого тому, щоб з'ясувати, чим
були записи зі slack.
Застереження для аналітика¶
- Index slack є неповним і невпорядкованим. Записи перезаписуються зі змінами каталогу; відсутність імені нічого не доводить.
- Багато записів зі slack є копіями записів, що досі використовуються, залишеними під час переміщення записів.
CopyOfEntryInUseпозначає їх. Те саме видалене ім'я також може бути у slack кілька разів. - Час у записі індексу — це час
$FILE_NAMEстаном на останнє оновлення запису. Він може відрізнятися як від часу$STANDARD_INFORMATION, так і від часу$FILE_NAMEу записі$MFTфайлу. AllocatedSizeіRealSizeтакож відображають стан на момент останнього оновлення запису і можуть бути застарілими.FileEntry(абоParentEntry) запису зі slack може бути відсутнім, якщо його перезаписали пізніші байти. Якщо він присутній, запис 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 (і скільки з них записано частково), записи, що використовуються і що перебувають у slack, а також імена записів зі slack, які не є точними копіями записів, що використовуються. Ці імена є кандидатами на видалені або перейменовані файли, а не остаточним висновком самі по собі.
Поля виводу 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 нс станом на останнє оновлення запису. |
AllocatedSize, RealSize |
Розміри, які NTFS скопіювала в запис; див. застереження вище. |
FileAttributes |
Назви атрибутів, об'єднані через | (hidden|archive); is_directory для підкаталогу. Біти, яким ця версія Juntei не дає назви, зберігаються в шістнадцятковому вигляді (0x00800000). |
ReparseValue |
Тег точки повторного розбору або розмір розширених атрибутів із $FILE_NAME. |
Problems |
Пошкодження в записі, наприклад частково записані сектори. Записи з пошкодженого запису все одно заслуговують на перегляд, з обережністю. |
JSON/JSONL мають ті самі поля в snake_case, із problems у вигляді списку та null для невідомих
значень.
Як знаходять записи зі slack¶
Slack сканується на кожній 8-байтовій межі, де починаються записи, у пошуку цілих записів, атрибутів
$FILE_NAME, заголовок запису яких перезаписано, а на початку slack — атрибута
$FILE_NAME, батьківське посилання якого перезаписав кінець записів, що використовуються. Кандидат має виглядати
як те, що записує Windows: коректне ім'я UTF-16 без керівних символів і роздільників шляху, чотири
значення часу між 1980 і 2100 роками, відомий простір імен і відомі прапорці атрибутів. Батьківське посилання понад
32 біти — це перезаписані байти, і його залишають порожнім.
До кожного запису застосовується масив послідовності оновлення. Сектор, який не закінчується значенням послідовності
оновлення, записано частково; Juntei читає запис як є і називає ці сектори в Problems.
Стратегія розслідування¶
- Почніть з імен у slack, які у зведенні позначено як не копії, потім відфільтруйте за допомогою
--slack-only --no-copies. - Знайдіть
FileEntryу$MFT. Той самийFileSequenceозначає той самий файл; більший означає, що запис відтоді звільнено і, можливо, повторно використано. - Шукайте ім'я в журналі USN, щоб дізнатися, коли файл було видалено або перейменовано.
- Порівняйте час
$FILE_NAMEз часом$STANDARD_INFORMATIONу$MFT, щоб виявити timestomping. - Зіставте з Prefetch, LNK, Jump Lists і журналами подій, щоб з'ясувати, як використовувався файл.
Додаткові відомості¶
- Microsoft: Master File Table
- libfsntfs: документація формату NTFS
- dfir_ntfs
- INDXRipper
- ys-ntfs-parser (модуль
i30його крейтаmft)