Gli operatori che si curano del loro mestiere non si limitano a cancellare le prove. Camuffano ciò che lasciano dietro. La mossa più comune è il timestomping — riscrivere i timestamp di un file NTFS così che il file appaia innocente, o invecchi fuori dalla finestra di indagine. Funzionava in modo affidabile. Con il USN journal acceso, com'è di default su ogni host Windows moderno, lascia una firma così distintiva che un singolo filtro e una risoluzione di percorso padre la faranno emergere.
Questo post percorre cosa fa il timestomping al disco, come il journal lo espone, e quali altre mosse anti-forensi puoi catturare con lo stesso artefatto gratis.
Un rapido ripasso sui timestamp NTFS
Ogni entry MFT porta timestamp in due attributi:
$STANDARD_INFORMATION(SI). I timestamp che gli strumenti user-space e la maggior parte delle API leggono e scrivono.dir, Explorer,Get-ChildItem,os.stat,GetFileTime— tutti restituiscono SI. Microsoft documenta il layout nella reference dei NTFS file times.$FILE_NAME(FN). I timestamp che NTFS imposta internamente per ogni attributo$FILE_NAME(un file può avere nomi multipli se è hard-linkato). I valori FN sono molto più difficili da cambiare — si aggiornano solo su operazioni specifiche e il kernel non espone un'API pulita per riscriverli.
Gli strumenti di timestomping mirano a SI di default. Il vecchio timestomp.exe di Metasploit, SetMACE e dozzine di impianti custom scritti da operatori con anche un mestiere modesto riscrivono tutti $STANDARD_INFORMATION via NtSetInformationFile con un payload FileBasicInformation. Gli impianti moderni (il comando timestomp di Cobalt Strike tra essi) possono anche riscrivere FN manipolando la MFT direttamente, che è più impegnativo e produce prove $LogFile aggiuntive.
In ogni caso, l'atto di scrivere l'entry MFT accende il journal.
Cosa il journal registra per una modifica di timestamp
Quando i timestamp SI sono scritti, NTFS emette un record BasicInfoChange | Close sulla FileReferenceNumber del file. Quel record è il diagnostico:
- Un tocco legittimo produce
BasicInfoChange | Closeinsieme a unDataExtendoDataOverwritedalla scrittura effettiva che ha innescato l'aggiornamento del timestamp. - Un timestomp produce un
BasicInfoChange | Closenudo senza scrittura precedente sulla stessaFileReferenceNumber.
Quando vedi BasicInfoChange | Close senza DataOverwrite, DataExtend, FileCreate o rename nella stessa sessione di handle, stai guardando manipolazione di metadati. La stragrande maggioranza è timestomping; il resto sono commutazioni di attributi (+H, +R, compressione on/off) e cambiamenti di stato EFS.
Il confronto SI vs FN
La rilevazione di timestomping più autoritativa confronta i timestamp SI di ogni file con i suoi timestamp FN. Il pattern risale alle prime ricerche di forense Windows di Mandiant ed è coperto in File System Forensic Analysis di Brian Carrier. Le forme che dovrebbero farti fermare:
- SI antecedente a FN. Un file non può essere stato legittimamente modificato prima che esistesse il suo nome. Questa è la pistola fumante canonica.
- SI nel futuro di FN con un margine irrealistico. Operatore che spinge l'età apparente in avanti per sembrare un file di sistema di un'installazione pulita.
- Sia SI che FN appaiono impossibilmente puliti — secondi tondi, valori M/A/C/B identici, tutti coincidenti con una data di installazione Windows nota. Vale la pena uno sguardo più ravvicinato anche quando nessuna coppia individuale segnala.
Il journal complementa il confronto piuttosto che sostituirlo. Il confronto MFT ti dice che qualcosa ha manomesso i timestamp. Il journal ti dice esattamente quando è avvenuta la riscrittura SI, che è il timestamp che metti nel report. Abbina i due e il caso si scrive da solo:
- Il confronto MFT segnala SI < FN su
\Windows\System32\drivers\suspicious.sys. - Il journal ha un
BasicInfoChange | ClosesullaFileReferenceNumberdel file alle2026-04-12 03:08:14Zsenza scritture circostanti. - Quel timestamp è quando l'operatore ha eseguito il suo comando
timestomp. Correla con Sysmon evento 1 e hai il processo.
$LogFile e il journal dovrebbero concordare
Il journal registra scritture al livello per-file. $LogFile registra le transazioni MFT sottostanti al livello di scrittura-di-metadati. Un timestomp produce:
- Una transazione di scrittura MFT in
$LogFile, modificando l'attributo$STANDARD_INFORMATIONdell'entry obiettivo. - Un
BasicInfoChange | Closenel journal.
Se $LogFile mostra una transazione di aggiornamento MFT su un file senza un BasicInfoChange | Close corrispondente nel journal, l'operatore potrebbe aver cancellato il record del journal pulendo $UsnJrnl e creandone uno nuovo. Quella manovra è possibile (fsutil usn deletejournal /D /N C: seguito da fsutil usn createjournal /m ... /a ... C:), ma è di per sé rumorosa.
Altre mosse anti-forensi che il journal cattura
Disabilitare o pulire il journal
fsutil usn deletejournal /D /N C: rimuove il journal del tutto. Dopo che gira:
- Il file journal viene ricostruito vuoto. I record pre-chiamata sono spariti per sempre.
- L'entry MFT di
$UsnJrnlviene riscritta nuova, cosa che$LogFileregistra. - Il log Security registra un evento Sensitive Privilege Use per
SeRestorePrivilegeoSeManageVolumePrivilege, se le SACL erano configurate (cosa che di solito non erano).
Il journal non può dirti cosa conteneva, ma l'atto di disabilitarlo è di per sé un forte segnale anti-forensico. Microsoft documenta i comandi di gestione nella reference fsutil usn.
Gli operatori che sanno che il journal esiste tendono a fare una di due cose: pulirlo all'uscita (rumoroso), o evitare selettivamente di lasciare prove in esso (più difficile, richiede di stare fuori dal disco). Su un host dove il journal è sospettosamente vuoto attorno a una finestra di incidente nota, trattalo come un'ipotesi da testare.
Flussi di dati alternativi
Nascondere cose in ADS è più vecchio di me, e il journal lo registra in modo pulito. Il bit Reason StreamChange si attiva quando un flusso di dati alternativo viene aggiunto, rinominato o rimosso su un file. Filtra per StreamChange e ogni evento di creazione/modifica ADS sul volume emerge.
Falsi positivi attesi: flussi Zone.Identifier legittimi da download del browser (abbinati al FileCreate del file host), flussi Mark-of-the-Web da client di posta, e stato SmartScreen. Tutto il resto che produce record StreamChange su binari di sistema firmati, su file in \Windows\System32\, o su binari del profilo utente fuori dal flow normale di download del browser merita uno sguardo.
Trucchi di hard-link
HardLinkChange si attiva quando vengono aggiunti o rimossi hard link. Gli operatori a volte usano hard link per rendere un binario malevolo accessibile via due padri, il che può sconfiggere le regole AppLocker e i controlli EDR basati sul percorso. Pivota sulla FileReferenceNumber per vedere tutti i padri per un dato inode.
Abuso di reparse point
ReparsePointChange si accende quando un reparse point — junction, symbolic link, mount point — viene aggiunto, modificato o rimosso. Cerca reparse point creati in \$Recycle.Bin\, \Users\Default\, \ProgramData\ o altri posti dove normalmente non esisterebbero. Il parser del cestino è l'artefatto complementare per il lato $Recycle.Bin.
Cambiamenti di sicurezza e Object ID
SecurityChange espone riscritture di ACL e owner. ObjectIdChange espone le manipolazioni di Object ID più rare. Entrambi sono silenziosi su un host sano. Raffiche di uno o dell'altro su binari del profilo utente o su file di sistema valgono la pena di essere investigate.
Una procedura di scan pratica
Lo screening più veloce per il timestomping usando un journal parsato:
- Filtra ai record la cui maschera Reason è esattamente
BasicInfoChange | Close. La maggior parte dei parser fa default a "contiene il bit"; tu vuoi corrispondenza esatta per questo scan. - Per ogni candidato, guarda i cinque minuti precedenti di record sulla stessa
FileReferenceNumber. Se non c'èDataOverwrite,DataExtend,FileCreateo rename, segnala il record. - Per i record segnalati, calcola il delta SI vs FN nella MFT. Ordina per delta assoluto.
La cima della lista è il tuo timestomping. Le entry segnalate restanti sono di solito invocazioni di attrib +H o attrib +R, o script che commutano il read-only — dipendenti dal contesto, raramente interessanti per un'indagine IR tipica, ma vale la pena tenerli nell'output classificato per completezza.
Il parser su questa pagina espone il filtro per maschera esatta. Per il passo 3, ti serve un $MFT parsato aperto accanto — la maggior parte degli analisti usa MFTECmd di Eric Zimmerman per l'export CSV e pivota in un foglio di calcolo.
Cosa non puoi catturare in questo modo
Una breve lista di mosse anti-forensi che aggirano del tutto il journal:
- Bootare da media esterni e riscrivere il disco. Non ha mai toccato l'OS vivo, non ha mai scritto al journal.
- Riscritture di file in userland che preservano la dimensione del contenuto allo stesso offset senza aggiornamento SI. Produce record
DataOverwritema perde il contenuto originale. Il journal vede la scrittura, non cosa c'era prima. - Disabilitare il journal prima di fare qualsiasi altra cosa. Il journal può solo registrare ciò che è successo mentre era in esecuzione.
Per quelli, ti serve $LogFile, Volume Shadow Copy, telemetria off-host, o un dump RAM acquisito abbastanza vicino all'incidente da contenere ancora lo stato rilevante.
Letture aggiuntive
- Microsoft Learn — File Times e la reference dell'API
NtSetInformationFile. Quest'ultima è la syscall che ogni strumento di timestomping finisce per chiamare. - MFTECmd di Eric Zimmerman — il parser offline canonico per i timestamp SI e FN in un CSV piatto.
- Documentazione libfsntfs di Joachim Metz — il riferimento aperto più approfondito sugli interni di
$LogFile, che è il secondo testimone quando il journal da solo non basta. - Brian Carrier, File System Forensic Analysis — il capitolo sugli attributi di metadati NTFS è ancora il riferimento canonico su come SI e FN si comportano sotto diverse operazioni.