Перейти до змісту

Журнал транзакцій NTFS ($LogFile)

Що це таке і чому це важливо

NTFS — файлова система, яку Windows зазвичай використовує для системного тому. Щоб відновлюватися після збою, вона записує зміни, які збирається внести в метадані файлової системи, у прихований файл тому з назвою $LogFile. Кожне оновлення може містити байти redo (новий стан) і байти undo (попередній стан, потрібний для відкату зміни). Цей журнал відокремлений від журналів подій Windows, файлів .LOG1 реєстру та журналу USN.

Для слідчого попередній стан особливо корисний. Запис undo може зберігати ім'я файлу до перейменування, видалений запис каталогу або часові позначки до оновлення метаданих. Деякі записи також містять байти, які NTFS записала до журналу USN, зокрема записи, яких уже немає в зібраному $J. Однак багато транзакцій стосуються звичайної активності операційної системи і не описують атаку.

Приклад: видалений запис індексу згадує report.txt; пізніше доданий запис згадує report.txt.encrypted. Зіставлення повного посилання на файл, батьківського каталогу, ланцюжка транзакцій та інших артефактів може підтвердити перейменування. Самі лише ці два імені не ідентифікують програму-вимагача, її оператора чи точний час шифрування.

Розташування та збирання

C:\$LogFile
D:\$LogFile

Кожен том NTFS має власний журнал. Отримуйте його інструментом, який читає метадані NTFS або експортує їх із криміналістичного образу чи знімка; звичайне копіювання файлів у Windows може не мати до нього доступу. Збирайте $MFT і $Extend\$UsnJrnl:$J того самого тому якомога ближче в часі. Зберігайте вихідні файли та хеші. Пізніше отриманий журнал може містити інший відрізок активності.

$LogFile — це циклічний журнал: нові записи перезаписують старі. Тривалість зберігання залежить від розміру журналу та навантаження і може становити лише хвилини або години. Відсутність імені файлу чи операції не є доказом того, що їх ніколи не було.

Що доводить запис, і застереження

  • Оновлення фіксує метадані, які NTFS записала в журнал для відновлення. Окремий запис redo не доводить, що вся дія вищого рівня завершилася або що її ініціювала певна особа. Зіставляйте пов'язані записи, завершення транзакції, результуючу файлову систему та незалежні докази.
  • Загальної часової позначки транзакції немає. Вбудовані часові позначки описують метадані файлу, іноді застарілі, скопійовані або змінені зловмисником. Не наносьте CreatedOn на хронологію інциденту як час перейменування чи зміни часової позначки. Записи USN можуть надати окрему часову позначку.
  • LSN (log sequence numbers, порядкові номери журналу) упорядковують записи в межах журналу одного тому. Це не час годинника, і їх не можна порівнювати між хостами чи томами. Записи зі старіших проходів циклічного буфера можуть зберігатися поруч із новішою активністю.
  • Комірка таблиці транзакцій використовується повторно. Групуйте за TransactionFirstLsn, TransactionId, ідентичністю клієнта та джерелом, а не лише за TransactionId. Ланцюжки можуть вказувати за межі збережених даних.
  • Посилання на файли містять номер запису і порядковий номер. Інакше повторне використання запису MFT може змусити не пов'язані між собою файли виглядати як той самий файл.
  • Шляхи, надані $MFT, описують стан зібраної MFT, а не відтворений історичний шлях. Juntei зіставляє порядкові номери й явно залишає невідомі компоненти. Батьківський каталог міг бути перейменований після транзакції, а жорсткі посилання можуть давати більше одного поточного імені.
  • TargetInferred означає, що зіставлення відкритого атрибута походить з іншого відрізка журналу. Ставтеся до такого зіставлення з додатковою обережністю. Невизначені записи індексу можуть бути декодовані лише за їхньою структурою; перевіряйте їхні імена за необробленими байтами та іншими джерелами.
  • Розірвана (torn) сторінка пропускається; читабельні сусідні записи залишаються доступними. Truncated позначає запис, продовження якого відсутнє. Перш ніж вважати вивід повним, перегляньте діагностику парсера. Вхідні дані нульової довжини — помилка; незаписаний журнал, що повністю складається з FF, закономірно не має рядків.
  • Парсер не відтворює транзакції для реконструкції історичної MFT. Він не відновлює довільний нерезидентний вміст файлів і не виконує жодних зібраних даних. Сторінки із захистом DAX CRC не підтримуються. Перевірка на реальних доказах переважно охоплює сторінки журналу розміром 4 KiB.

Аналіз за допомогою Juntei

# Single log, current paths from an adjacent $MFT when present
juntei parse-ntfs logfile -f '$LogFile' -o logfile.csv

# Explicit MFT from the SAME volume
juntei parse-ntfs logfile -f '$LogFile' -m '$MFT' -t jsonl -o logfile.jsonl

# Multiple collected logs; SourceFile distinguishes every input
juntei parse-ntfs logfile -d evidence -o collected-logs.csv

# Preserve the underlying payloads for low-level validation
juntei parse-ntfs logfile -f '$LogFile' --raw-data -t jsonl -o logfile-raw.jsonl

# Automatic per-computer output
juntei auto-parse -d evidence -o parsed

Усі параметри див. у довіднику команд. Пошук у каталогах приймає $LogFile, LogFile, їхні форми .bin та імена на кшталт C_$LogFile або C_$LogFile.bin без урахування регістру. Окремий файл, переданий через -f, може мати будь-яке ім'я.

Автоматичне зіставлення з MFT враховує префікс тому в експорті: C_$LogFile використовує C_$MFT, а D_$LogFile.bin спершу пробує D_$MFT.bin, потім D_$MFT. Журнали з префіксом ніколи не використовують простий $MFT як запасний варіант. LogFile без префікса також приймає MFT або $MFT. Використовуйте -m разом із -f, щоб явно вибрати відповідну MFT, якщо ваш експорт має іншу схему іменування.

Вивід містить один запис на LSN, включно із записами оновлень, контрольних точок і невідомих клієнтів. JSON — це потік відформатованих об'єктів; JSONL містить один об'єкт на рядок. CSV має ті самі назви полів; масиви та структуровані поля подаються як компактний JSON усередині комірки CSV. Невідомі скалярні значення порожні в CSV і мають значення null у JSON. Порожні масиви означають, що жодного елемента не декодовано, а не доказ того, що їх не існувало.

Одночасно в пам'яті зберігається один цілий журнал і його проаналізовані записи. Визначення шляхів MFT потребує додаткової пам'яті та роботи. --raw-data може значно збільшити розмір виводу. В auto-parse використовуйте -T, щоб обмежити кількість паралельних процесів парсерів на комп'ютері з обмеженою пам'яттю.

Якщо суміжну MFT неможливо прочитати, Juntei видає попередження та експортує журнал без шляхів; MftSource тоді залишається null. Ця невдача збагачення не відкидає читабельних первинних доказів. Відсутні або неоднозначні збіги MFT також спричиняють попередження та лічильник Logs without a matching MFT у підсумку; вони не вважаються збоями аналізу.

Поля виводу

Ідентичність, цілісність і походження запису

Поле Значення та інтерпретація
SourceFile, FileOffset Вхідний шлях і зміщення в байтах, за яким було прочитано заголовок цього запису; використовуйте їх для перевірки байтів.
LSN Порядковий номер запису в журналі. Великі значення — цілі числа, а не часові позначки.
PreviousLSN, UndoNextLSN Посилання на попередній запис і запис відкату. Нуль означає відсутність посилання; ненульові посилання можуть вказувати за межі збережених даних.
TransactionID, TransactionFirstLSN Комірка таблиці транзакцій і найраніший LSN, пов'язаний із цією транзакцією; сама комірка не є унікальною.
RecordType ClientRecord (оновлення), ClientRestart (контрольна точка) або Other.
ClientIndex, ClientSequence Ідентичність клієнта журналу; зазвичай NTFS. Це не обліковий запис користувача і не ідентифікатор процесу.
Flags, SpansPages Необроблені прапорці запису і те, чи продовжуються дані клієнта на іншій сторінці. Охоплення кількох сторінок — нормальне явище.
Truncated True, якщо парсер виявив відсутнє продовження для цього LSN. Не підсумовує всі пошкодження в усьому файлі.
ClusterSize, ClusterSizeSource Кількість байтів у кластері, що використовується для зміщень цілі; джерело — Caller, Checkpoint або Inferred. Якщо справжнє значення відоме, вкажіть його через --cluster-size.
LogVersion Версія з останньої читабельної сторінки перезапуску, зазвичай 1.1 або 2.0; null, якщо жодна читабельна сторінка перезапуску не збереглася.
MFT-Source MFT, використана для збагачення поточними шляхами, якщо вона є. Вона має належати тому самому тому.

У JSON/JSONL з auto-parse додаються Comp і Artifact, як і для інших парсерів. Журнал завдання .txt містить діагностику; маніфести показують, чи завдання виконано успішно, із помилкою, чи його пропущено. Пошкодження, які можна обійти, можуть дати успішне завдання з ненульовим лічильником Parse problems у його журналі.

Операції та ціль

Поле Значення та інтерпретація
RedoOperation, UndoOperation Назви операцій NTFS або шістнадцяткове значення для невідомого коду. Redo описує заплановане оновлення; undo — обернену до нього операцію.
TargetEntryNumber, TargetSequenceNumber Для операції із записом файлу: номер ураженого запису MFT без виведеного порядкового номера. В інших випадках: посилання на файл, якому належить визначений відкритий атрибут. Вбудоване оновлення індексу каталогу спрямоване на каталог, а не на дочірній елемент, описаний його записом.
TargetAttributeType, TargetAttributeName Числовий тип і назва відкритого атрибута, використаного операцією. Для операцій із записами файлів це зазвичай $DATA з $MFT. Поширені типи: 16 ($STANDARD_INFORMATION), 48 ($FILE_NAME), 128 ($DATA), 144 ($INDEX_ROOT), 160 ($INDEX_ALLOCATION), 176 ($BITMAP).
TargetPath Поточний шлях MFT, якщо повне посилання на ціль відоме, або невідомі компоненти. Порожнє для операцій із записами файлів, історичне покоління яких невідоме; сам лише номер запису не повинен визначатися як його поточний власник.
OpenAttributeEntryNumber, OpenAttributeSequenceNumber, OpenAttributePath Файл, якому належить відкритий атрибут, через який операція виконує запис, з його поточним шляхом MFT. Для операцій із записами файлів ці поля зберігають контекст $MFT окремо від ураженого запису.
TargetAttribute Зміщення в таблиці відкритих атрибутів журналу; відрізняється від типу атрибута або ідентифікатора MFT.
TargetInferred True, якщо зіставлення цілі походить з іншого відрізка журналу. Ціль null залишається невизначеною, навіть якщо цей прапорець false.
TargetVCN, Lcns Віртуальний кластер у цілі та номери фізичних кластерів; корисні для низькорівневої перевірки, а не для визначення часу.
RecordOffset, AttributeOffset Зміщення атрибута/запису та оновлення в ньому.
ClusterBlockOffset, TargetBlockSize Зміщення та розмір цілі в одиницях по 512 байтів.
OffsetInTarget Обчислене зміщення в байтах в ураженому записі файлу або нерезидентному потоці. Залежить від розмірів кластера та запису MFT.
RedoLength, UndoLength Заявлені довжини даних. Операція обнулення може заявляти довжину, не містячи такої кількості байтів корисного навантаження.
RedoBytesAvailable, UndoBytesAvailable Байти корисного навантаження, фактично доступні для декодування. Порівнюйте із заявленими довжинами та семантикою операції.

Зручні стовпці метаданих файлу

Ці стовпці показують одне пріоритетне ім'я файлу не у форматі DOS зі сторони redo, а за його відсутності — зі сторони undo. Якщо жодна сторона не містить імені файлу, поля оновлення часових позначок надають перевагу часовим позначкам redo, потім undo. Оновлення записів каталогу також безпосередньо показують свої час, розмір і прапорці, надаючи перевагу redo перед undo. Декодовані атрибути $DATA показують свій розмір, навіть якщо імені файлу немає. Розмір безіменного $DATA декодованого запису файлу має пріоритет над можливо застарілим розміром з імені файлу. Ці стовпці — допоміжний засіб для перегляду; для повного порівняння «до/після» використовуйте окремі поля сторін.

Поле Значення та інтерпретація
MetadataSide Redo або Undo — сторона, що надає зручні стовпці імені файлу/часових позначок.
EntryNumber, SequenceNumber Файл, описаний декодованими метаданими імені файлу/запису файлу/атрибута або частковим оновленням часових позначок $STANDARD_INFORMATION, з порядковим номером, якщо він відомий. Порожнє для оновлення запису каталогу, яке не ідентифікує дочірній елемент, а також для необроблених оновлень розміру/списку відрізків (run list). Для ураженого запису використовуйте TargetEntryNumber.
Filename Пріоритетне декодоване ім'я; усі імена залишаються в масивах сторін, включно з псевдонімами DOS і жорсткими посиланнями.
ParentEntryNumber, ParentSequenceNumber, ParentPath Посилання на батьківський каталог і поточний шлях MFT; не реконструкція історичного шляху.
CreatedOn, ContentModifiedOn, RecordModifiedOn, LastAccessedOn Час метаданих в UTC з точністю до 100 нс. Це не часові позначки транзакцій. Відсутній/некоректний час залишається порожнім/null.
FileSize, FileAttributes Розмір і числові прапорці Windows з вибраних метаданих; значення записів каталогу можуть бути застарілими. Атрибути $DATA і декодовані записи файлів можуть надати безпосередніший розмір.
AttrType Числовий тип декодованого запису атрибута; 48 для декодованого оновлення метаданих запису каталогу. Відрізняється від відкритого атрибута, на який спрямована операція.

Повні метадані та корисні навантаження redo/undo

Поле Значення та інтерпретація
RedoFileNames, UndoFileNames Масиви всіх декодованих $FILE_NAME на цій стороні, що зберігають розрізнення доданих/нових і видалених/старих імен.
RedoTimes, UndoTimes Часові позначки $STANDARD_INFORMATION, записані кожною стороною; часткові оновлення залишають незмінені часові позначки відсутніми, а не вгадують їх.
RedoDecoded, UndoDecoded Структуровані відомості про запис файлу, атрибут, запис індексу або запис каталогу, ідентифіковані за Kind. Null може означати непідтримувану операцію або недостатню кількість байтів.
JournalWriteOffset, JournalWriteLength Зміщення та кількість байтів даних redo, що записують $DATA:$J. Це вказує на можливе джерело інакше втрачених записів USN; реконструйований журнал при цьому не експортується.
Checkpoint Версія контрольної точки, початковий LSN, розмір кластера, а також LSN/довжина дампів таблиці відкритих атрибутів, назв атрибутів, «брудних» сторінок і таблиці транзакцій.
OtherRecordType Необроблений тип запису клієнта для нерозпізнаного або недекодованого тіла.
RedoData, UndoData, OtherData Шістнадцяткові корисні навантаження лише з --raw-data; інакше null/порожнє. Зберігайте їх для перевірки непідтримуваних або пошкоджених структур.

Кожен об'єкт імені файлу містить посилання на файл і батьківський каталог (Raw, EntryNumber, SequenceNumber), Name, NameEscaped, Namespace, поточний ParentPath, чотири часові позначки, Size, AllocatedSize, Attr і ReparseValue. NameEscaped позначає некоректний UTF-16, представлений екранованими послідовностями. Значення reparse може бути тегом точки повторного розбору (reparse tag) або розміром розширених атрибутів.

Об'єкти часових позначок зберігають і Utc, і цілочисельний Filetime; сигнальне або некоректне значення може мати null-представлення UTC, зберігаючи при цьому своє вихідне ціле число. RedoTimes і UndoTimes містять Created, Modified, Changed і Accessed; значення відсутніх членів — null.

Декодовані об'єкти FileRecord містять номер, порядковий номер, кількість жорстких посилань, прапорці, базове посилання, ознаку того, чи зберігся лише заголовок, і наявні атрибути. Кожен декодований атрибут зберігає тип, назву, резидентність, прапорці, ідентифікатор, розмір і виділений розмір. $STANDARD_INFORMATION додає чотири часові позначки, атрибути, ідентифікатори власника/безпеки, квоту та USN; ці ідентифікатори потребують окремого визначення і не доводять, хто з користувачів змінив файл. Записи індексу містять прапорці, довжину ключа та необов'язкове ім'я файлу. Оновлення записів каталогу зберігають чотири часові позначки, розміри, атрибути та значення reparse, навіть якщо саме ім'я не було записано в журнал.

Робочий процес розслідування

  1. Перегляньте діагностику щодо відсутніх сторінок перезапуску, розірваних сторінок і усічених записів.
  2. Шукайте підозріле ім'я файлу або розширення як у RedoFileNames, так і в UndoFileNames.
  3. Зіставляйте номери записів і порядкові номери, потім досліджуйте ланцюжок LSN та операції транзакції.
  4. Порівнюйте часові позначки redo та undo, щоб виявити зміни. Звичайне копіювання, розпакування та відновлення також можуть змінювати часові позначки; розбіжність — це зачіпка, а не автоматичний вердикт про timestomping.
  5. Зіставляйте з журналом USN, $MFT і $I30. Використовуйте журнали подій, Prefetch і артефакти активності користувача, щоб встановити виконання або атрибуцію.

Наприклад, знайдіть усі записи, що містять зашифроване ім'я файлу на будь-якій стороні:

jq 'select(any(.RedoFileNames[]?, .UndoFileNames[]?;
  .Name | endswith(".encrypted"))) |
  {Lsn, TransactionId, TransactionFirstLsn, RedoOperation, UndoOperation,
   RedoFileNames, UndoFileNames}' logfile.jsonl

Це пошук за іменем файлу, а не повноцінний детектор програм-вимагачів. Щоб дослідити корисні навантаження журналу, експортуйте з --raw-data і виберіть записи з ненульовим (non-null) JournalWriteOffset; шістнадцяткові дані RedoData представляють байти, записані за цим зміщенням. Аналіз і усунення дублікатів цих вбудованих записів USN — окремий крок. Juntei поки що не об'єднує їх із виводом parse-ntfs usn-journal.

Додаткові відомості