Master File Table

MFT

De meest opvallende bron van waardevolle informatie voor een analist uit het NTFS-bestandssysteem is de Master File Table (MFT). De locatie van de startsector van de MFT kan worden gevonden in de bootsector van de schijf, en elk bestand en elke directory in het volume heeft een entry in de MFT. Elke MFT entry is 1024 bytes groot, waardoor de MFT zeer eenvoudig te ontleden is. Elke MFT record, of entry, begint met de ASCII string “FILE” (als er een fout in de entry zit, begint deze met “BAAD”) en bestaat uit één of meer (meestal meer) attributen, elk met hun eigen identifier en structuur. Figuur 4.1 illustreert een gedeelte van een MFT-gegeven.

Figuur 4.1. De eerste 42 bytes van elke MFT-entry bestaan uit een header-structuur met 12 elementen, en de resterende 982 bytes hangen grotendeels af van de waarden in de header en de verschillende attributen die in de entry zijn opgenomen. Niet alle elementen in de header van de MFT-entry zijn onmiddellijk bruikbaar voor een forensisch analist; in figuur 4.2 worden echter vijf van de elementen geïllustreerd die onmiddellijk bruikbaar zijn.

Figuur 4.2. MFT record header items (in little Endian volgorde).

Zoals geïllustreerd in figuur 4.2 (dat een gedeelte is van figuur 4.1), zien we de “FILE” signatuur aan het begin van de record. Dan zien we het volgnummer of de waarde, die wordt verhoogd wanneer de entry wordt gealloceerd of gedeloceerd. Omdat deze specifieke MFT entry eigenlijk de eerste record is in de MFT en verwijst naar het bestand “$MFT,” is het logisch dat het sequentienummer 1 is. Vervolgens is er de link count, die verwijst naar het aantal directories die entries hebben voor deze record (hard links zorgen ervoor dat deze waarde wordt verhoogd). Vervolgens is er de offset in de record naar het eerste attribuut; als je kijkt naar offset 0x38 in de record, zul je zien dat het eerste attribuut een identifier heeft van 0x10, of 16. Tenslotte zien we de flags waarde, die ons vertelt of de entry is toegewezen (als het 0x01 bit is gezet) en of de entry een directory is (als het 0x02 bit is gezet). In het kort, uit deze twee waarden kunnen we bepalen of de entry is gealloceerd of verwijderd, en of het voor een bestand of een directory is. Wanneer de header wordt geparsed, kan de pseudocode hiervoor als volgt worden weergegeven:

if ($mft{flags} & 0x0001) – allocated; else unallocated/deleted

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

De flags waarde die zichtbaar is in Figuur 4.2 is “0x01,” wat duidt op een gealloceerd bestand. Een waarde van 0x00 duidt op een verwijderd bestand en een waarde van 0x03 op een toegewezen map.

Tip

MFT-records

MFT-records worden niet verwijderd nadat ze zijn aangemaakt; nieuwe records worden zo nodig aan de MFT toegevoegd en records voor verwijderde bestanden worden hergebruikt.

Zoals eerder vermeld, zijn alleen de eerste 42 bytes gestructureerd; daarna bestaat de rest van de MFT-invoer uit een of meer attribuutvelden. Er is geen formele specificatie of verklaring die zegt dat er specifieke attributen in een MFT entry moeten zitten, maar over het algemeen kun je verwachten dat je een $STANDARD_INFORMATION en een $FILE_NAME attribuut in de meeste MFT entries vindt. In dit onderdeel wordt gekeken naar deze twee attributen, omdat ze informatie geven over de tijdstempel, wat waardevol is voor forensische analisten. We kijken ook kort naar het $DATA attribuut en laten de overige attributen als oefening voor de geïnteresseerde en nieuwsgierige lezer.

De header van elk attribuut bevat een header van 16 bytes, die onder andere het type attribuut aangeeft, de totale lengte van het attribuut, en of het attribuut in de MFT entry is ingezeten of niet.

Note

MFT Metadata Files

De eerste 16 records van de MFT bevatten informatie over metadatabestanden; het is echter mogelijk dat ze niet allemaal worden gebruikt. De bestanden die niet worden gebruikt, blijven in een toegewezen status en bevatten alleen basisinformatie.

Met behulp van deze header-informatie kunnen we de MFT-invoer doornemen en waardevolle informatie uit elk attribuut halen. Het $STANDARD_INFORMATION-attribuut (dat altijd aanwezig is) bestaat bijvoorbeeld voor elk bestand en elke map en heeft een identificatiecode van 0x10 (d.w.z. 16). Dit attribuut bevat de bestandstijden voor de MFT entry (nou ja, drie ervan, in ieder geval) die we zien als we “dir” typen op de commando prompt; de gewijzigde tijd, laatst benaderde tijd, en de aanmaak (geboorte) datum van het bestand of de directory, ook wel aangeduid als “MAC” tijden. Het attribuut bevat een vierde tijdwaarde die de laatste keer aangeeft dat de MFT entry werd gewijzigd. Alles bij elkaar worden deze tijden aangeduid als “MACE” (met de “E” verwijzend naar de MFT entry modificatie tijd) of “MACB” (met de “C” verwijzend naar de MFT entry modificatie tijd) tijden.

Warning

File Times

NTFS bestandstijden worden vastgelegd in Universal Coordinated Time (UTC) formaat, wat analoog is aan Greenwich Mean Time. Dit geldt voor alle tijden; in elke MFT entry, zal een bestandsrecord waarschijnlijk minstens 8 tijden geassocieerd hebben; vele malen, 12 of meer. Op het FAT-bestandssysteem worden bestandstijden bijgehouden in lokale systeemtijdnotatie.

Het $FILE_NAME attribuut (identifier 0x30, of 48) wordt ook aangetroffen bij de meeste MFT-items voor bestanden en mappen; in feite zullen veel MFT-items meer dan één $FILE_NAME attribuut hebben. Net als het $STANDARD_INFORMATION attribuut, is dit attribuut altijd resident en bevat het ook vier tijdswaarden; deze tijdswaarden worden echter meestal ingesteld wanneer het bestand op het systeem wordt aangemaakt. In tegenstelling tot bestandstijden in het $STANDARD_INFORMATION attribuut, worden deze bestandstijden niet beïnvloed door normale systeemactiviteit of kwaadwillig geknoei en kunnen daarom worden gebruikt om indicatoren van kwaadwillige activiteit te bepalen, en kunnen stappen worden ondernomen om het tijdstip waarop een systeem werd geïnfecteerd te verdoezelen. Het volgende codevoorbeeld (parseSIAttr() functie) geeft een voorbeeld van hoe het $STANDARD_INFORMATION attribuut kan worden geparseerd:

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($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($content,24,8));

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

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

return %si;

}

Tip

GetTime

De getTime() functie die te zien is in de code listing voor het parseSIAttr() attribuut die zojuist is gegeven bestaat uit code geleend van Andreas Schuster die de 64-bit FILETIME object tijdstempels vertaalt naar een 32-bit Unix tijd die verder kan worden vertaald naar een menselijk leesbare tijd via de Perl ingebouwde gmtime() functie. Die code ziet er als volgt uit:

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;

}

Deze code is zeer nuttig voor het ontleden en vertalen van elk FILETIME-object, ongeacht waar het vandaan is gehaald.

Op een normaal systeem kunnen veel MFT-regels twee $FILE_NAME-attributen hebben: een voor de volledige naam van het bestand (of de directory) en een voor de DOS, 8.3 bestandsnaam. Bijvoorbeeld, als een bestand “myreallylongfile.txt” heet, zal de 8.3 bestandsnaam verschijnen als “myreal~1.txt”. Dit wordt aangehouden voor compatibiliteit met oudere bestandssystemen en systemen die geen lange bestandsnamen ondersteunen. Het is dus niet ongewoon op een normaal Windows systeem om een aantal MFT entries te hebben met twee $FILE_NAME attributen met bijna identieke inhoud. Het volgende codevoorbeeld (parseFNAttr() functie) geeft een voorbeeld van hoe een $FILE_NAME attribuut van een MFT entry kan worden geparsed en beschikbare gegevens kunnen worden geëxtraheerd:

sub parseFNAttr {

my $fn = shift;

my %fn;

my ($type,$len,$res,$naam_len,$naam_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($content,8,8));

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

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

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

my ($t0,$t1) = unpack(“VV”,substr($content,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;

}

Het laatste attribuut dat we bespreken is het $DATA attribuut (identifier 0x80, of 128). Dit attribuut bevat of verwijst naar de eigenlijke inhoud van het bestand. Als de vlag “nonresident” in de koptekst van het attribuut niet is ingesteld, dan blijft de inhoud van het bestand binnen het $DATA attribuut van de MFT invoer, na de koptekst en twee aanvullende structuren. Dit geldt in het algemeen voor korte tekstbestanden, bijvoorbeeld, of andere bestanden van minder dan 700 bytes. Als de gegevens niet-resident zijn, dan moeten “gegevensruns,” of waar de gegevens zich op de schijf bevinden, worden vertaald.

Exemplaarcode voor het parsen van $DATA attribuut gegevensruns is erg ingewikkeld en wordt hier niet gepresenteerd. Evenzo is code voor het extraheren van informatie uit ingezeten $DATA-attributen triviaal en bestaat uit het ontleden van enkele aanvullende gegevens (grootte van de inhoud en offset naar de inhoud) na de attribuutkop.

Er zijn enkele open source-tools beschikbaar voor het ontleden van de MFT (met name de attributen $STANDARD_INFORMATION en $FILE_NAME) en het beschikbaar maken van tijdsgestempelde gegevens voor de analist. Een daarvan is David Kovar’s analyzemft.py Python script, op het web te vinden onder http://www.integriography.com/projects/analyzeMFT. Een ander is het mft.pl Perl script, waaruit de parseSIAttr() en parseFNAttr() functies zijn gehaald, dat beschikbaar is in de WinForensicAnalysis Google Code projected, te vinden op het Web op http://code.google.com/p/winforensicaanalysis.

Brian Carrier’s “The SleuthKit” (TSK) tools zijn waarschijnlijk de bekendste tools voor het verzamelen van een breed scala aan bestandssysteem en bestandssysteem metadata informatie van verkregen afbeeldingen en zelfs live systemen. Om bijvoorbeeld een lijst van bestandssysteem $STANDARD_INFORMATION attribuut bestandstijden van een verkregen afbeelding te verzamelen, kan een analist een commando gebruiken dat lijkt op het volgende:

C:\tsk>fls -f ntfs -m C:/ -p -r G:\casexp.img > G:\casefilesbodyfile.txt

Dit commando produceert wat bekend staat als een “bodyfile,” wat een tussenliggend bestandsformaat is dat wordt gebruikt om deze informatie op te slaan voordat het wordt geconverteerd naar een tijdlijn van bestandssysteemactiviteit. In sommige gevallen kan het nodig zijn dat de analist de “-o” switch toevoegt om de offset te identificeren van de partitie die op het live systeem verscheen als de “C:\” drive; deze offset informatie kan handmatig worden bepaald via een hex editor of door mmls.exe te gebruiken.

Een analist kan deze zelfde informatie ook verzamelen van een live, remote systeem met behulp van F-Response. Als de analist op de juiste manier verbinding heeft gemaakt met het systeem op afstand en de C:-schijf van het systeem als F:-schijf op zijn eigen systeem heeft aangekoppeld, kan hij een commando als het volgende gebruiken om de bestandstijden van het $STANDARD_INFORMATION-attribuut voor de bestanden in de C:-partitie te verzamelen:

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

De complete set TSK tools, samen met documentatie en gebruiksinformatie, is te vinden op het web op de SleuthKit Web site, http://www.sleuthkit.org.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.