Master File Table

MFT

La fonte più notevole di informazioni preziose per un analista dal file system NTFS è la Master File Table (MFT). La posizione del settore iniziale della MFT può essere trovata nel settore di avvio del disco, e ogni file e directory nel volume ha una voce nella MFT. Ogni voce MFT ha una dimensione di 1024 byte, rendendo l’MFT molto semplice da analizzare. Ogni record MFT, o voce, inizia con la stringa ASCII “FILE” (se c’è un errore nella voce, inizierà con “BAAD”) e consiste di uno o più (più spesso, più) attributi, ognuno con il proprio identificatore e struttura. La figura 4.1 illustra una porzione di una voce MFT.

Figura 4.1. I primi 42 byte di ogni voce MFT comprendono una struttura di intestazione con 12 elementi, e i restanti 982 byte dipendono in gran parte dai valori all’interno dell’intestazione e dai vari attributi contenuti nella voce. Non tutti gli elementi all’interno dell’intestazione della voce MFT sono immediatamente utili per un analista forense; tuttavia, la Figura 4.2 illustra cinque degli elementi che sono immediatamente utili.

Figura 4.2. Come illustrato nella figura 4.2 (che è una porzione estratta dalla figura 4.1), vediamo la firma “FILE” visibile all’inizio del record. Poi vediamo il numero di sequenza o valore, che viene incrementato quando la voce viene allocata o disallocata. Poiché questa particolare voce MFT è in realtà il primo record all’interno del MFT e si riferisce al file “$MFT,” è logico che il numero di sequenza sia 1. Poi c’è il numero di link, che si riferisce al numero di directory che hanno voci per questo record (gli hard link causano l’incremento di questo valore). Poi c’è l’offset nel record del primo attributo; se guardate l’offset 0x38 nel record, vedrete che il primo attributo ha un identificatore di 0x10, o 16. Infine, vediamo il valore di flags, che ci dice se la voce è allocata (se il bit 0x01 è impostato) e se la voce è una directory (se il bit 0x02 è impostato). In breve, da questi due valori, possiamo determinare se la voce è allocata o cancellata, e se è per un file o una directory. Quando l’intestazione viene analizzata, lo pseudocodice per questo può essere rappresentato come segue:

if ($mft{flags} & 0x0001) – allocato; else non allocato/cancellato

if ($mft{flags} & 0x0002) – cartella/directory; else file

Il valore di flags visibile nella Figura 4.2 è “0x01,” che indica un file allocato. Un valore di 0x00 indicherebbe un file cancellato, e un valore di 0x03 indicherebbe una directory allocata.

Tip

Registri MFT

I registri MFT non vengono cancellati una volta che sono stati creati; nuovi registri vengono aggiunti al MFT quando necessario, e i registri per i file cancellati vengono riutilizzati.

Come detto in precedenza, solo i primi 42 byte sono strutturati; dopo di che, il resto della voce MFT consiste in uno o più campi attributo. Non c’è una specifica formale o una dichiarazione che dice che ci devono essere attributi specifici in una voce MFT, ma per la maggior parte, ci si può aspettare di trovare un attributo $STANDARD_INFORMATION e un $FILE_NAME nella maggior parte delle voci MFT. Questa sezione esamina questi due attributi, in quanto forniscono informazioni sull’orario, che sono preziose per gli analisti forensi. Daremo anche un breve sguardo all’attributo $DATA e lasceremo i restanti attributi come esercizio per il lettore interessato e curioso.

L’intestazione di ogni attributo contiene un header di 16 byte, che identifica il tipo di attributo, la lunghezza complessiva dell’attributo, e se l’attributo è residente alla voce MFT o no, tra gli altri elementi.

Note

File di metadati MFT

Le prime 16 voci dell’MFT contengono informazioni sui file di metadati; tuttavia, non tutti possono essere usati. Quelli che non sono usati sono lasciati in uno stato allocato e contengono solo informazioni di base.

Utilizzando queste informazioni di intestazione, possiamo analizzare la voce MFT ed estrarre informazioni preziose da ogni attributo. Per esempio, l’attributo $STANDARD_INFORMATION (che è sempre residente) esiste per ogni voce di file e directory e ha un identificatore di 0x10 (cioè, 16). Questo attributo contiene i tempi del file per la voce MFT (beh, tre di loro, comunque) che vediamo quando digitiamo “dir” al prompt dei comandi; il tempo modificato, il tempo dell’ultimo accesso, e la data di creazione (nata) del file o della directory, chiamati anche tempi “MAC”. L’attributo contiene un quarto valore temporale che specifica l’ultima volta che la voce MFT è stata alterata. Tutti insieme, questi tempi sono indicati come tempi “MACE” (con la “E” che si riferisce al tempo di modifica della voce MFT) o “MACB” (con la “C” che si riferisce al tempo di modifica della voce MFT).

Attenzione

Tempi dei file

I tempi dei file NTFS sono registrati in formato Universal Coordinated Time (UTC), che è analogo al Greenwich Mean Time. Questo è vero per tutti i tempi; in ogni voce MFT, un record di file avrà probabilmente almeno 8 tempi associati ad esso; molte volte, 12 o più. Sul file system FAT, i tempi dei file sono mantenuti nel formato dell’ora del sistema locale.

L’attributo $FILE_NAME (identificatore 0x30, o 48) si trova anche con molte voci MFT di file e directory; infatti, molte voci MFT avranno più di un attributo $FILE_NAME. Come l’attributo $STANDARD_INFORMATION, questo attributo è sempre residente e contiene anche quattro valori temporali; tuttavia, questi valori temporali sono solitamente impostati quando il file viene creato sul sistema. A differenza dei tempi dei file nell’attributo $STANDARD_INFORMATION, questi tempi dei file non sono influenzati dalla normale attività del sistema o da manomissioni malevole e possono quindi essere usati per determinare indicatori di attività nefasta, e possono essere prese misure per offuscare il tempo in cui un sistema è stato infettato. Il seguente esempio di codice (funzione parseSIAttr()) fornisce un esempio di come l’attributo $STANDARD_INFORMATION può essere analizzato:

sub parseSIAttr {

my $si = shift;

my %si;

my ($type,$len,$res,$name_len,$name_ofs,$flags,$id,$sz_content,$ofs_content)

= unpack(“VVCCvvvVv”,substr($si,0,22));

my $content = substr($si,$ofs_content,$sz_content);

my ($t0,$t1) = unpack(“VV”,substr($contenuto,0,8));

$si{c_time} = getTime($t0,$t1);

my ($t0,$t1) = unpack(“VV”,substr($contenuto,8,8));

$si{m_time} = getTime($t0,$t1);

my ($t0,$t1) = unpack(“VV”,substr($contenuto,16,8));

$si{mft_m_time} = getTime($t0,$t1);

my ($t0,$t1) = unpack(“VV”,substr($contenuto,24,8));

$si{a_time} = getTime($t0,$t1);

$si{flags} = unpack(“V”,substr($contenuto,32,4));

return %si;

}

Tip

GetTime

La funzione getTime() vista all’interno dell’elenco di codice per l’attributo parseSIAttr() appena dato consiste in codice preso in prestito da Andreas Schuster che traduce i timbri di tempo dell’oggetto FILETIME a 64 bit in un tempo Unix a 32 bit che può essere ulteriormente tradotto in un tempo leggibile dall’uomo tramite la funzione integrata Perl gmtime(). Questo codice appare come segue:

sub getTime($$) {

my $lo = shift;

my $hi = shift;

my $t;

if ($lo == 0 && $hi == 0) {

$t = 0;

} else {

$lo -= 0xd53e8000;

$hi -= 0x019db1de;

$t = int($hi*429.4967296 + $lo/1e7);

};

$t = 0 if ($t < 0);

return $t;

}

Questo codice è molto utile per analizzare e tradurre qualsiasi oggetto FILETIME, indipendentemente da dove viene estratto.

In un sistema normale, molte voci MFT possono avere due attributi $FILE_NAME: uno per contenere il nome completo del file (o della directory) e uno per contenere il nome del file DOS, 8.3. Per esempio, se un file si chiama “myreallylongfile.txt”, il nome del file 8.3 apparirà come “myreal~1.txt”. Questo è mantenuto per compatibilità con i vecchi file system e con quelli che non supportano nomi di file lunghi. Quindi non è insolito su un normale sistema Windows avere un certo numero di voci MFT con due attributi $FILE_NAME con contenuti quasi identici. Il seguente esempio di codice (funzione parseFNAttr()) fornisce un esempio di come un attributo $FILE_NAME da una voce MFT può essere analizzato e i dati disponibili estratti:

sub parseFNAttr {

my $fn = shift;

my %fn;

my ($type,$len,$res,$name_len,$name_ofs,$flags,$id,$sz_content,$ofs_content)

= unpack(“VVCCvvvVv”,substr($fn,0,22));

my $content = substr($fn,$ofs_content,$sz_content);

$fn{parent_ref} = unpack(“V”,substr($content,0,4));

$fn{parent_seq} = unpack(“v”,substr($content,6,2));

my ($t0,$t1) = unpack(“VV”,substr($contenuto,8,8));

$fn{c_time} = getTime($t0,$t1);

my ($t0,$t1) = unpack(“VV”,substr($contenuto,16,8));

$fn{m_time} = getTime($t0,$t1);

my ($t0,$t1) = unpack(“VV”,substr($contenuto,24,8));

$fn{mft_m_time} = getTime($t0,$t1);

my ($t0,$t1) = unpack(“VV”,substr($content,32,8));

$fn{a_time} = getTime($t0,$t1);

$fn{flags} = unpack(“V”,substr($content,56,4));

$fn{len_name} = unpack(“C”,substr($content,64,1));

$fn{namespace} = unpack(“C”,substr($contenuto,65,1));

$fn{len_name} = $fn{len_name} * 2 if ($fn{namespace} > 0);

$fn{nome} = substr($contenuto,66,$fn{len_nome});

$fn{nome} = cleanStr($fn{nome}) if ($fn{namespace} > 0);

$fn{nome} =~ s/\x0c/\x2e/g;

$fn{nome} =~ s///g;

return %fn;

}

L’ultimo attributo che discutiamo è l’attributo $DATA (identificatore 0x80, o 128). Questo attributo contiene o si riferisce al contenuto effettivo del file. Se il flag non residente nell’intestazione dell’attributo non è impostato, allora il contenuto del file è residente nell’attributo $DATA della voce MFT, dopo l’intestazione e due strutture aggiuntive. Questo è generalmente vero per file di testo brevi, per esempio, o altri file inferiori a 700 byte. Se i dati non sono residenti, allora i “giri di dati”, o dove i dati si trovano sul disco, devono essere tradotti.

Il codice di esempio per analizzare i giri di dati dell’attributo $DATA è molto complesso e non è presentato qui. Allo stesso modo, il codice per estrarre informazioni dagli attributi $DATA residenti è banale e consiste nell’analizzare alcune informazioni aggiuntive (dimensione del contenuto e offset al contenuto) dopo l’intestazione dell’attributo.

Sono disponibili alcuni strumenti open source per analizzare l’MFT (in particolare, gli attributi $STANDARD_INFORMATION e $FILE_NAME) e rendere disponibili all’analista dati con data e ora. Uno è lo script Python analyzemft.py di David Kovar, che si trova sul web a http://www.integriography.com/projects/analyzeMFT. Un altro è lo script mft.pl Perl, da cui sono state estratte le funzioni parseSIAttr() e parseFNAttr(), che è disponibile nel progetto WinForensicAnalysis Google Code, che si trova sul Web all’indirizzo http://code.google.com/p/winforensicaanalysis.

Gli strumenti “The SleuthKit” (TSK) di Brian Carrier sono probabilmente gli strumenti più noti per raccogliere una vasta gamma di informazioni sui metadati di file system e file system da immagini acquisite e persino sistemi live. Per esempio, per raccogliere un elenco di tempi di file system $STANDARD_INFORMATION da un’immagine acquisita, un analista può usare un comando simile al seguente:

C:\tsk>fls -f ntfs -m C:/ -p -r G:\case\xp.img > G:\case\files\bodyfile.txt

Questo comando produce quello che è conosciuto come un “bodyfile,” che è un formato di file intermedio usato per memorizzare queste informazioni prima di convertirle in una linea temporale di attività del file system. In alcuni casi, l’analista potrebbe aver bisogno di aggiungere lo switch “-o” per identificare l’offset della partizione che è apparsa sul sistema live come l’unità “C:\”; queste informazioni di offset possono essere determinate manualmente tramite un editor esadecimale o usando mmls.exe.

Un analista può anche raccogliere queste stesse informazioni da un sistema live e remoto usando F-Response. Se l’analista si è connesso correttamente al sistema remoto e ha montato l’unità C:\ del sistema come F:\ sul proprio sistema, può usare un comando simile al seguente per raccogliere i tempi dei file con attributo $STANDARD_INFORMATION per i file nella partizione C:\:

C:\tsk>fls -f ntfs -m C:/ -p -r \\.\F: > g:\case\files\bodyfile.txt

Il set completo di strumenti TSK, insieme alla documentazione e alle informazioni d’uso, può essere trovato sul web al sito SleuthKit, http://www.sleuthkit.org.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.