Файл лежит в C:Windows и уверяет, что появился там пять лет назад. Проводник верит. PowerShell тоже показывает старую дату. Я бы не верил ни одному из них, пока не посмотрел на $MFT и историю файловой системы. В NTFS время файла хранится не в одном месте, а операция подмены даты оставляет следы, которые значительно сложнее согласованно переписать.
Timestomping в терминологии MITRE ATT&CK относится к технике T1070.006. Базовая проверка сравнивает временные метки $STANDARD_INFORMATION и $FILE_NAME. Но для нормального расследования я добавляю USN Journal и доступные снимки VSS. Причём есть важная ловушка. USN_REASON_BASIC_INFO_CHANGE сам по себе не доказывает вызов SetFileTime, а USN_RECORD_V4, вопреки иногда встречающимся схемам, вообще не содержит полей TimeStamp и FileAttributes.
Материал посвящён цифровой криминалистике и расследованию инцидентов на системах, к которым у исследователя есть законный доступ. Изменять метаданные чужих систем или уничтожать журналы ради сокрытия активности не следует.
Почему одного сравнения $SI и $FN уже мало
В записи $MFT у обычного файла есть два набора временных меток. $STANDARD_INFORMATION, сокращённо $SI, содержит время создания, изменения содержимого, доступа и изменения самой MFT-записи. Именно эти значения обычно видят Windows API и пользовательские программы.
SetFileTime позволяет приложению с правом FILE_WRITE_ATTRIBUTES менять время создания, последнего доступа и записи файла. Поэтому простейший timestomping выглядит почти банально. Вредоносная программа берёт даты старого системного файла и назначает их своему пейлоаду. В проводнике новый файл внезапно становится ровесником Windows.
Вторая копия временных меток находится в $FILE_NAME, сокращённо $FN. Обычный вызов SetFileTime напрямую её не переписывает. Поэтому ситуация вроде следующей выглядит подозрительно.
$STANDARD_INFORMATION
Created: 2021-04-11 08:32:14
$FILE_NAME
Created: 2026-09-30 22:17:51
Файл как будто существовал в $SI за пять лет до появления, которое отражает $FN. Для классического timestomping такой разрыв очень характерен.
Но превращать любое несовпадение $SI и $FN в автоматический вердикт нельзя. Операции перемещения, переименования и работы с жёсткими ссылками могут обновлять $FN. Некоторые варианты так называемого double timestomping используют именно свойства NTFS при переименовании, чтобы добиться гораздо более правдоподобного набора метаданных. Резервное восстановление, синхронизация, миграция данных и специализированные программы тоже способны создавать необычные временные последовательности.
Поэтому я рассматриваю $SI/$FN как первый слой проверки, а не как последний.
Как я проверяю подозрительный файл через USN Journal
USN Change Journal хранит последовательность изменений объектов NTFS. Сначала полезно проверить, существует ли журнал и какой диапазон USN ещё сохранился.
fsutil usn queryjournal C:
Для первичного просмотра записей можно использовать встроенный fsutil. Я ограничиваю версии V2 и V3, если мне нужны обычные записи с временной меткой.
fsutil usn readjournal minver=2 maxver=3 startusn=0 C:
В реальном расследовании удобнее работать не с консольной простынёй, а с извлечёнными $J и $MFT. Например, MFTECmd умеет разобрать их вместе и восстановить пути по MFT.
MFTECmd.exe -f "C:Evidence$J" -m "C:Evidence$MFT" --csv "C:Evidenceout"
MFTECmd.exe -f "C:Evidence$MFT" --csv "C:Evidenceout" --at
Ключевой для timestomping флаг имеет значение 0x00008000.
USN_REASON_BASIC_INFO_CHANGE = 0x00008000
Microsoft описывает BASIC_INFO_CHANGE как изменение одного или нескольких атрибутов файла либо временных меток. Причиной действительно может быть SetFileTime, но тем же флагом отмечаются изменения таких свойств, как read-only, hidden, system, archive или sparse. Поэтому логика «есть BASIC_INFO_CHANGE, значит злоумышленник скрутил дату» неверна.
Намного интереснее последовательность событий для одного FileReferenceNumber. Допустим, $MFT сообщает, что файл создан в 2021 году. В $J я нахожу его реальное появление на томе в сентябре 2026 года, а через несколько секунд для того же файлового объекта возникает BASIC_INFO_CHANGE. После операции $SI внезапно уезжает в 2021 год. Такая комбинация уже намного сильнее одиночного расхождения $SI/$FN.
Поле TimeStamp в USN_RECORD_V2 содержит UTC-время самой записи журнала. SetFileTime не позволяет приложению подставить туда желаемую дату файла. Но я не называл бы значение абсолютными часами истины. USN использует системное время компьютера, а системные часы тоже можно изменить. Кроме того, Reason-флаги могут накапливаться до закрытия объекта, поэтому время USN-записи не всегда равно моменту конкретного API-вызова с точностью до миллисекунды.
Отдельная ошибка встречается в описаниях USN_RECORD_V4. У структуры V4 есть Reason, SourceInfo и сведения о диапазонах изменений, но нет TimeStamp, FileAttributes и имени файла. V4 используется для USN range tracking и не является расширенной версией V2 со всеми прежними полями.
| Артефакт | Что показывает | Насколько силён сигнал |
|---|---|---|
| $SI против $FN | Несогласованные временные метки | Хороший первичный индикатор |
| USN FILE_CREATE | Появление объекта на томе | Сильный элемент временной линии |
| USN BASIC_INFO_CHANGE | Изменение метаданных или времени | Требует контекста |
| EDR / API telemetry | Вызов SetFileTime или NtSetInformationFile | Очень сильная корреляция |
| VSS | Предыдущее состояние MFT и файла | Сильный независимый источник |
Что добавляет VSS diffing
USN Journal не вечен. Журнал имеет ограниченный размер, старые записи со временем уходят, а сам журнал можно пересоздать. Поэтому второй независимый источник для меня гораздо ценнее красивого одиночного IOC.
Сначала проверяю, какие теневые копии вообще существуют.
vssadmin list shadows /for=C:
VSS представляет состояние тома в определённый момент времени. Встроенный системный провайдер Windows использует copy-on-write. Перед изменением блока исходное содержимое сохраняется в области различий, благодаря чему VSS может позднее представить старое состояние тома. Сам VSS как архитектура допускает и другие типы провайдеров, поэтому утверждение «любая VSS-копия представляет собой COW-дифф» слишком широкое.
Для расследования мне интересен не столько внутренний формат diff area, сколько результат. Я сравниваю MFT-запись исследуемого файла в историческом снимке и в текущем состоянии.
Представим временную линию. Файл сейчас заявляет Created = 2021-04-11. Существует снимок VSS от августа 2026 года, где файла ещё нет. В сентябре USN фиксирует появление соответствующего объекта, затем BASIC_INFO_CHANGE, после которого $SI показывает 2021 год. Подобная цепочка практически уничтожает доверие к текущей дате создания.
Но отсутствие файла в старом VSS я всё равно не называю самостоятельным доказательством атаки. Файл могли восстановить из резервной копии с сохранением исходных временных меток, перенести специализированной программой или развернуть из образа. VSS становится действительно ценным, когда совпадает с USN, $MFT и другой телеметрией.
Ещё интереснее случай, когда файл присутствует в двух снимках. В старой копии $SI содержит дату 2026 года, а в текущей записи та же метка неожиданно превращается в 2021 год. Тут уже можно непосредственно увидеть изменение метаданных между двумя состояниями тома.
Когда я считаю Timestomping подтверждённым
Я не строю детект на одном условии. Практическое правило выглядит примерно так.
- Нахожу подозрительную временную последовательность в $SI и $FN.
- Привязываю файл к
FileReferenceNumber, а не только к имени и пути. - Ищу в $J создание, переименование, перемещение и
BASIC_INFO_CHANGE. - Сравниваю временную линию USN с текущими значениями $MFT.
- Проверяю доступные VSS-снимки.
- При наличии EDR ищу процесс, который менял метаданные файла через
SetFileTime,NtSetInformationFileили родственные механизмы.
Сильная картина выглядит не как «даты отличаются», а как причинная цепочка. Новый объект появляется на диске, через короткий промежуток меняет basic information, после чего приобретает временные метки старого легитимного бинарника. Исторический снимок подтверждает прежнее состояние, а процессная телеметрия связывает изменение с конкретным процессом.
Есть и пределы метода. Прямое офлайн-редактирование NTFS может обойти обычную последовательность USN. Очистка или переполнение журнала уничтожает старые записи. Удалённый файл может получить новую MFT-запись, а старые File Reference Numbers со временем переиспользуются. Подмена системных часов влияет на временную линию нескольких источников сразу. Продвинутый timestomping способен уменьшить различия $SI/$FN через операции с именами и ссылками.
Поэтому лучший детектор здесь не одна сигнатура, а независимые часы. $MFT рассказывает, что файл утверждает о себе сейчас. USN Journal показывает, какие операции NTFS видел раньше. VSS даёт состояние тома до изменения. EDR добавляет процесс, который инициировал операцию. Чем больше независимых линий сходятся в одной точке, тем меньше шансов объяснить аномалию обычной работой Windows.
FAQ
USN_REASON_BASIC_INFO_CHANGE точно означает SetFileTime?
Нет. Флаг означает изменение базовой информации файла, куда входят временные метки и ряд файловых атрибутов. Для вывода о timestomping нужны дополнительные признаки.
Почему нельзя просто сравнить $STANDARD_INFORMATION и $FILE_NAME?
Несовпадение полезно как индикатор, но переименование, перемещение, восстановление данных и другие нормальные операции тоже меняют отношения между временными метками. Double timestomping дополнительно пытается устранить такой индикатор.
Есть ли TimeStamp в USN_RECORD_V4?
Нет. USN_RECORD_V4 содержит USN, Reason, SourceInfo и данные range tracking, но не содержит TimeStamp и FileAttributes. Временная метка присутствует в классических структурах V2 и V3.
Можно ли считать время USN абсолютно достоверным?
Нет. SetFileTime не управляет временем USN-записи, но сама запись зависит от системных часов Windows. При расследовании нужно учитывать возможную смену системного времени и особенности накопления Reason-флагов.
USN Journal хранит всю историю тома?
Нет. Размер журнала ограничен. NTFS постепенно удаляет старые записи, поэтому отсутствие события в текущем $J не доказывает, что события никогда не было.
Что делать, если VSS отсутствует?
Сопоставлять $MFT, $UsnJrnl, EDR, Sysmon, журналы Security, Prefetch, Amcache и другие доступные артефакты. VSS усиливает расследование, но не является обязательным условием.
Какой признак я бы проверил первым?
Сначала посмотрел бы все временные метки $SI и $FN, затем нашёл тот же файловый объект в USN Journal. Такая последовательность быстро показывает, есть ли смысл тратить время на VSS и глубокую корреляцию.
Мой вывод простой. Для старого примитивного timestomping сравнение $SI и $FN по-прежнему отлично работает, но современное расследование не должно на нём останавливаться. Самый полезный уровень начинается при корреляции $MFT, USN Journal и VSS. При этом BASIC_INFO_CHANGE нельзя выдавать за прямое доказательство SetFileTime, а поля V2 нельзя механически переносить на USN_RECORD_V4. Если временная линия из трёх независимых источников сходится, поддельной дате файла становится гораздо труднее притворяться историей.