MFT
Cea mai notabilă sursă de informații valoroase pentru un analist din sistemul de fișiere NTFS este Master File Table (MFT). Locația sectorului de pornire al MFT poate fi găsită în sectorul de boot al discului, iar fiecare fișier și director din volum are o intrare în MFT. Fiecare intrare MFT are o dimensiune de 1024 de octeți, ceea ce face ca MFT să fie foarte simplu de analizat. Fiecare înregistrare MFT, sau intrare, începe cu șirul ASCII „FILE” (dacă există o eroare în intrare, aceasta va începe cu „BAAD”) și constă din unul sau mai multe (cel mai adesea, mai multe) atribute, fiecare cu propriul identificator și structură. Figura 4.1 ilustrează o parte a unei intrări MFT.
Primii 42 de octeți ai fiecărei intrări MFT cuprind o structură de antet cu 12 elemente, iar restul de 982 de octeți depind în mare măsură de valorile din antet și de diferitele atribute conținute în intrare. Nu toate elementele din cadrul antetului intrării MFT sunt imediat utile pentru un analist criminalistic; totuși, figura 4.2 ilustrează cinci dintre elementele care sunt imediat utile.
După cum este ilustrat în figura 4.2 (care este o porțiune extrasă din figura 4.1), vedem semnătura „FILE” vizibilă la începutul înregistrării. Apoi vedem numărul sau valoarea secvenței, care este incrementată atunci când înregistrarea este alocată sau nealocată. Deoarece această anumită intrare MFT este de fapt prima înregistrare din MFT și se referă la fișierul „$MFT”, este logic că numărul de secvență este 1. Urmează numărul de legături, care se referă la numărul de directoare care au intrări pentru această înregistrare (legăturile permanente determină creșterea acestei valori). Urmează decalajul din înregistrare până la primul atribut; dacă vă uitați la decalajul 0x38 din înregistrare, veți vedea că primul atribut are un identificator de 0x10, adică 16. În cele din urmă, vedem valoarea „flags”, care ne spune dacă intrarea este alocată (dacă bitul 0x01 este setat) și dacă intrarea este un director (dacă bitul 0x02 este setat). Pe scurt, din aceste două valori, putem determina dacă intrarea este alocată sau ștearsă și dacă este vorba despre un fișier sau un director. Atunci când antetul este analizat, pseudocodul pentru acest lucru poate fi reprezentat după cum urmează:
if ($mft{flags} & 0x0001) – alocat; else unallocated/deleted
if ($mft{flags} & 0x0002) – folder/directory; else file
Valoarea flags vizibilă în figura 4.2 este „0x01”, care indică un fișier alocat. O valoare de 0x00 ar indica un fișier șters, iar o valoare de 0x03 ar indica un director alocat.
Tip
Înregistrări MFT
Înregistrările MFT nu sunt șterse odată ce au fost create; noi înregistrări sunt adăugate la MFT în funcție de necesități, iar înregistrările pentru fișiere șterse sunt reutilizate.
După cum s-a menționat anterior, numai primii 42 de octeți sunt structurați; după aceea, restul înregistrării MFT este format din unul sau mai multe câmpuri de atribute. Nu există o specificație sau o declarație formală care să spună că trebuie să existe atribute specifice în cadrul unei intrări MFT, dar, în cea mai mare parte, vă puteți aștepta să găsiți un atribut $STANDARD_INFORMATION și un atribut $FILE_NAME în majoritatea intrărilor MFT. Această secțiune analizează aceste două atribute, deoarece ele furnizează informații despre marcajul de timp, care sunt valoroase pentru analiștii criminaliști. De asemenea, vom arunca o scurtă privire asupra atributului $DATA și vom lăsa restul atributelor ca exercițiu pentru cititorul interesat și curios.
În antetul fiecărui atribut conține un antet de 16 octeți, care identifică tipul de atribut, lungimea totală a atributului și dacă atributul este sau nu rezident al intrării MFT, printre alte elemente.
Nota
Fișiere de metadate MFT
Primele 16 intrări ale MFT conțin informații despre fișierele de metadate; cu toate acestea, este posibil să nu fie utilizate toate. Cele care nu sunt utilizate sunt lăsate într-o stare alocată și conțin doar informații de bază.
Utilizând aceste informații de antet, putem analiza intrarea MFT și extrage informații valoroase din fiecare atribut. De exemplu, atributul $STANDARD_INFORMATION (care este întotdeauna rezident) există pentru fiecare intrare de fișier și director și are un identificator de 0x10 (adică 16). Acest atribut conține orele de fișier pentru intrarea MFT (în fine, trei dintre ele, oricum) pe care le vedem atunci când tastăm „dir” la promptul de comandă; ora de modificare, ultima oră de accesare și data de creare (naștere) a fișierului sau a directorului, denumite și ore „MAC”. Atributul conține o a patra valoare de timp care specifică ultima dată la care intrarea MFT a fost modificată. Împreună, aceste ore sunt denumite ore „MACE” (cu „E” referindu-se la ora de modificare a intrării MFT) sau „MACB” (cu „C” referindu-se la ora de modificare a intrării MFT).
Avertisment
Oratele fișierelor
Oratele fișierelor NTFS sunt înregistrate în formatul Universal Coordinated Time (UTC), care este analog cu Greenwich Mean Time. Acest lucru este valabil pentru toate orele; în fiecare intrare MFT, o înregistrare de fișier va avea probabil cel puțin 8 ore asociate cu ea; de multe ori, 12 sau mai multe. Pe sistemul de fișiere FAT, orele fișierelor sunt menținute în formatul de timp al sistemului local.
Atributul $FILE_NAME (identificatorul 0x30, sau 48) se găsește, de asemenea, cu majoritatea intrărilor MFT de fișiere și directoare; de fapt, multe intrări MFT vor avea mai mult de un atribut $FILE_NAME. Ca și atributul $STANDARD_INFORMATION, acest atribut este întotdeauna rezident și conține, de asemenea, patru valori de timp; cu toate acestea, aceste valori de timp sunt, de obicei, setate atunci când fișierul este creat pe sistem. Spre deosebire de timpii fișierelor din atributul $STANDARD_INFORMATION, acești timpi ai fișierelor nu sunt afectați de activitatea normală a sistemului sau de manipulările rău intenționate și, prin urmare, pot fi utilizați pentru a determina indicatorii unei activități rău intenționate și pot fi luate măsuri pentru a ascunde momentul în care un sistem a fost infectat. Următoarea mostră de cod (funcția parseSIAttr()) oferă un exemplu de analiză a atributului $STANDARD_INFORMATION:
sub parseSIAttr {
my $si = shift;
my %si;
my ($type,$len,$res,$name_len,$name_ofs,$flags,$id,$sz_content,$ofs_content)
= unpack(„VVCCvvvvVv”,substr($si,0,22));
my $content = substr($si,$ofs_content,$sz_content);
my ($t0,$t1) = unpack(„VV”,substr($content,0,8));
$si{c_time} = getTime($t0,$t1);
my ($t0,$t1) = unpack(„VV”,substr($content,8,8));
$si{m_time} = getTime($t0,$t1);
my ($t0,$t1) = unpack(„VV”,substr($content,16,8));
$si{mft_m_time} = getTime($t0,$t1);
my ($t0,$t1) = unpack(„VV”,substr($contenit,24,8));
$si{a_time} = getTime($t0,$t1);
$si{flags} = unpack(„V”,substr($contenit,32,4));
return %si;
}
Tip
GetTime
Funcția getTime() văzută în cadrul listei de cod pentru atributul parseSIAttr() tocmai prezentată constă în cod împrumutat de la Andreas Schuster care traduce timbrele de timp ale obiectului FILETIME pe 64 de biți într-un timp Unix pe 32 de biți care poate fi tradus ulterior într-un timp lizibil pentru oameni prin intermediul funcției integrate Perl gmtime(). Acest cod apare după cum urmează:
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;
}
Acest cod este foarte util pentru analiza și traducerea oricărui obiect FILETIME, indiferent de locul de unde este extras.
Într-un sistem normal, multe intrări MFT pot avea două atribute $FILE_NAME: unul pentru a conține numele complet al fișierului (sau al directorului) și unul pentru a conține numele DOS, 8.3 al fișierului. De exemplu, dacă un fișier se numește „myreallylongfile.txt”, numele de fișier 8.3 va apărea ca „myreal~1.txt”. Acest lucru este păstrat pentru compatibilitate cu sistemele de fișiere mai vechi și cu cele care nu acceptă nume de fișiere lungi. Așadar, nu este neobișnuit ca pe un sistem Windows normal să existe un număr de intrări MFT cu două atribute $FILE_NAME cu conținut aproape identic. Următoarea mostră de cod (funcția parseFNAttr()) oferă un exemplu despre cum poate fi analizat atributul $FILE_NAME dintr-o intrare MFT și cum pot fi extrase datele disponibile:
sub parseFNAttr {
my $fn = shift;
my %fn;
my ($type,$len,$res,$name_len,$name_ofs,$flags,$id,$sz_content,$ofs_content)
= unpack(„VVCCvvvvVv”,substr($fn,0,22));
my $content = substr($fn,$ofs_content,$sz_content);
$fn{ref_părinte} = unpack(„V”,substr($content,0,4));
$fn{seq_părinte} = unpack(„v”,substr($content,6,2));
my ($t0,$t1) = unpack(„VV”,substr($content,8,8));
$fn{c_time} = getTime($t0,$t1);
my ($t0,$t1) = unpack(„VV”,substr($conținut,16,8));
$fn{m_time} = getTime($t0,$t1);
my ($t0,$t1) = unpack(„VV”,substr($conținut,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($content,65,1));
$fn{len_name} = $fn{len_name} * 2 if ($fn{namespace} > 0);
$fn{name} = substr($content,66,$fn{len_name});
$fn{name} = cleanStr($fn{name}) if ($fn{namespace} > 0);
$fn{name} =~ s/\x0c/\x2e/g;
$fn{name} =~ s///g;
return %fn;
}}
Atributul final pe care îl discutăm este atributul $DATA (identificatorul 0x80, sau 128). Acest atribut conține sau se referă la conținutul real al fișierului. În cazul în care stegulețul nerezident din antetul atributului nu este setat, atunci conținutul fișierului este rezident în atributul $DATA al intrării MFT, după antet și două structuri suplimentare. Acest lucru este valabil, în general, pentru fișierele text scurte, de exemplu, sau pentru alte fișiere mai mici de 700 de octeți. Dacă datele nu sunt rezidente, atunci trebuie traduse „execuțiile de date”, sau locul în care sunt localizate datele pe disc.
Codul de exemplu pentru analizarea execuțiilor de date din atributul $DATA este foarte complicat și nu este prezentat aici. În mod similar, codul pentru extragerea informațiilor din atributele $DATA rezidente este trivial și constă în analizarea unor informații suplimentare (dimensiunea conținutului și decalajul față de conținut) după antetul atributului.
Există câteva instrumente open source pentru analiza MFT (în special, atributele $STANDARD_INFORMATION și $FILE_NAME) și pentru a pune la dispoziția analistului date cu marcaj temporal. Unul dintre acestea este scriptul Python analyzemft.py al lui David Kovar, care se găsește pe web la adresa http://www.integriography.com/projects/analyzeMFT. Un altul este scriptul Perl mft.pl, din care au fost extrase funcțiile parseSIAttr() și parseFNAttr(), care este disponibil în proiecția WinForensicAnalysis Google Code, aflată pe Web la http://code.google.com/p/winforensicaanalysis.
Instrumentele „The SleuthKit” (TSK) ale lui Brian Carrier sunt probabil cele mai cunoscute instrumente de colectare a unei game largi de informații despre metadatele sistemului de fișiere și ale sistemului de fișiere din imaginile achiziționate și chiar din sistemele live. De exemplu, pentru a colecta o listă a timpilor fișierelor cu atributele sistemului de fișiere $STANDARD_INFORMATION dintr-o imagine achiziționată, un analist poate utiliza o comandă similară cu următoarea:
C:\tsk>fls -f ntfs -m C:/ -p -r G:\case\xp.img > G:\case\files\bodyfile.txt
Această comandă produce ceea ce este cunoscut sub numele de „bodyfile”, care este un format de fișier intermediar utilizat pentru a stoca aceste informații înainte de a le converti într-o cronologie a activității sistemului de fișiere. În unele cazuri, este posibil ca analistul să fie nevoit să adauge comutatorul „-o” pentru a identifica decalajul față de partiția care a apărut pe sistemul live ca fiind unitatea „C:\”; această informație de decalaj poate fi determinată manual prin intermediul unui editor hexazecimal sau folosind mmls.exe.
Un analist poate, de asemenea, să colecteze aceleași informații de pe un sistem live, la distanță, folosind F-Response. Dacă analistul s-a conectat la sistemul de la distanță în mod corespunzător și a montat unitatea C:\\ a sistemului ca F:\ pe propriul sistem, acesta poate folosi o comandă similară cu următoarea pentru a colecta timpii fișierelor cu atributul $STANDARD_INFORMATION pentru fișierele din partiția C:\:
C:\tsk>fls -f ntfs -m C:/ -p -r \\.\F: > g:\case\files\bodyfile.txt
Setul complet de instrumente TSK, împreună cu documentația și informațiile de utilizare, pot fi găsite pe Web la site-ul SleuthKit, http://www.sleuthkit.org.
.