Master File Table

MFT

La source la plus notable d’informations précieuses pour un analyste provenant du système de fichiers NTFS est la Master File Table (MFT). L’emplacement du secteur de départ de la MFT se trouve dans le secteur de démarrage du disque, et chaque fichier et répertoire du volume possède une entrée dans la MFT. Chaque entrée MFT a une taille de 1024 octets, ce qui rend le MFT très simple à analyser. Chaque enregistrement MFT, ou entrée, commence par la chaîne ASCII « FILE » (s’il y a une erreur dans l’entrée, elle commencera par « BAAD ») et se compose d’un ou plusieurs (le plus souvent, plusieurs) attributs, chacun ayant son propre identifiant et sa propre structure. La figure 4.1 illustre une partie d’une entrée MFT.

Figure 4.1. Extrait d’un enregistrement MFT, ou entrée.

Les 42 premiers octets de chaque entrée MFT comprennent une structure d’en-tête avec 12 éléments, et les 982 octets restants dépendent en grande partie des valeurs dans l’en-tête et des divers attributs contenus dans l’entrée. Tous les éléments de l’en-tête de l’entrée MFT ne sont pas immédiatement utiles à un analyste judiciaire ; cependant, la figure 4.2 illustre cinq des éléments qui sont immédiatement utiles.

Figure 4.2. Éléments d’en-tête d’enregistrement MFT (dans l’ordre little Endian).

Comme l’illustre la figure 4.2 (qui est une partie extraite de la figure 4.1), nous voyons la signature « FILE » visible au début de l’enregistrement. Ensuite, nous voyons le numéro ou la valeur de la séquence, qui est incrémenté lorsque l’entrée est allouée ou désallouée. Comme cette entrée MFT particulière est en fait le premier enregistrement dans le MFT et qu’elle se réfère au fichier « $MFT », il est logique que le numéro de séquence soit 1. Vient ensuite le nombre de liens, qui se réfère au nombre de répertoires qui ont des entrées pour cet enregistrement (les liens durs font augmenter cette valeur). Ensuite, il y a le décalage du premier attribut dans l’enregistrement ; si vous regardez le décalage 0x38 dans l’enregistrement, vous verrez que le premier attribut a un identifiant de 0x10, soit 16. Enfin, nous voyons la valeur flags, qui nous indique si l’entrée est allouée (si le bit 0x01 est activé) et si l’entrée est un répertoire (si le bit 0x02 est activé). En bref, à partir de ces deux valeurs, nous pouvons déterminer si l’entrée est allouée ou supprimée, et si elle concerne un fichier ou un répertoire. Lorsque l’en-tête est analysé, le pseudocode pour cela peut être représenté comme suit:

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

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

La valeur des drapeaux visible dans la figure 4.2 est « 0x01 », ce qui indique un fichier alloué. Une valeur de 0x00 indiquerait un fichier supprimé, et une valeur de 0x03 indiquerait un répertoire alloué.

Tip

Enregistrements MFT

Les enregistrements MFT ne sont pas supprimés une fois qu’ils ont été créés ; de nouveaux enregistrements sont ajoutés au MFT au besoin, et les enregistrements pour les fichiers supprimés sont réutilisés.

Comme mentionné précédemment, seuls les 42 premiers octets sont structurés ; après cela, le reste de l’entrée MFT consiste en un ou plusieurs champs d’attributs. Il n’existe pas de spécification ou d’énoncé formel indiquant qu’il doit y avoir des attributs spécifiques dans une entrée MFT, mais dans la plupart des cas, vous pouvez vous attendre à trouver un attribut $STANDARD_INFORMATION et un attribut $FILE_NAME dans la plupart des entrées MFT. Cette section s’intéresse à ces deux attributs, car ils fournissent des informations sur l’horodatage, qui sont précieuses pour les analystes judiciaires. Nous jetterons également un bref coup d’œil à l’attribut $DATA et laisserons les autres attributs comme un exercice pour le lecteur intéressé et curieux.

L’en-tête de chaque attribut contient un en-tête de 16 octets, qui identifie le type d’attribut, la longueur globale de l’attribut, et si l’attribut est résident de l’entrée MFT ou non, parmi d’autres éléments.

Note

Fichiers de métadonnées MFT

Les 16 premières entrées du MFT contiennent des informations sur les fichiers de métadonnées ; cependant, elles ne sont pas forcément toutes utilisées. Ceux qui ne sont pas utilisés sont laissés dans un état alloué et ne contiennent que des informations de base.

En utilisant ces informations d’en-tête, nous pouvons analyser l’entrée MFT et extraire des informations précieuses de chaque attribut. Par exemple, l’attribut $STANDARD_INFORMATION (qui est toujours résident) existe pour chaque entrée de fichier et de répertoire et a un identifiant de 0x10 (c’est-à-dire 16). Cet attribut contient les heures de fichier pour l’entrée MFT (enfin, trois d’entre elles) que nous voyons lorsque nous tapons « dir » à l’invite de commande ; l’heure de modification, l’heure du dernier accès et la date de création (née) du fichier ou du répertoire, également appelées heures « MAC ». L’attribut contient une quatrième valeur temporelle qui indique la dernière fois que l’entrée MFT a été modifiée. Tous ensemble, ces temps sont appelés temps « MACE » (avec le « E » faisant référence à l’heure de modification de l’entrée MFT) ou « MACB » (avec le « C » faisant référence à l’heure de modification de l’entrée MFT).

Avertissement

Temps des fichiers

Les temps des fichiers NTFS sont enregistrés au format temps universel coordonné (UTC), qui est analogue au temps moyen de Greenwich. Ceci est vrai pour toutes les heures ; dans chaque entrée MFT, un enregistrement de fichier aura probablement au moins 8 heures associées à lui ; de nombreuses fois, 12 ou plus. Sur le système de fichiers FAT, les heures des fichiers sont maintenues au format de l’heure du système local.

L’attribut $FILE_NAME (identifiant 0x30, ou 48) se trouve également avec la plupart des entrées MFT de fichiers et de répertoires ; en fait, de nombreuses entrées MFT auront plus d’un attribut $FILE_NAME. Comme l’attribut $STANDARD_INFORMATION, cet attribut est toujours résident et contient également quatre valeurs temporelles ; cependant, ces valeurs temporelles sont généralement définies lorsque le fichier est créé sur le système. Contrairement aux heures des fichiers de l’attribut $STANDARD_INFORMATION, ces heures ne sont pas affectées par l’activité normale du système ou par une altération malveillante et peuvent donc être utilisées pour déterminer les indicateurs d’une activité malveillante, et des mesures peuvent être prises pour masquer le moment où un système a été infecté. L’échantillon de code suivant (fonction parseSIAttr()) fournit un exemple de la manière dont l’attribut $STANDARD_INFORMATION peut être analysé :

sub parseSIAttr {

mon $si = shift;

mon %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

La fonction getTime() vue dans le listing de code pour l’attribut parseSIAttr() qui vient d’être donné consiste en un code emprunté à Andreas Schuster qui traduit les horodatages 64 bits de l’objet FILETIME en un temps Unix 32 bits qui peut être ensuite traduit en un temps lisible par l’homme via la fonction Perl intégrée gmtime(). Ce code apparaît comme suit :

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;

}

Ce code est très utile pour analyser et traduire tout objet FILETIME, indépendamment de l’endroit d’où il est extrait.

Sur un système normal, de nombreuses entrées MFT peuvent avoir deux attributs $FILE_NAME : un pour contenir le nom complet du fichier (ou du répertoire) et un pour contenir le nom de fichier DOS, 8.3. Par exemple, si un fichier est nommé « myreallylongfile.txt », le nom de fichier 8.3 sera « myreal~1.txt ». Ceci est conservé pour la compatibilité avec les anciens systèmes de fichiers et ceux qui ne supportent pas les noms de fichiers longs. Il n’est donc pas rare, sur un système Windows normal, d’avoir un certain nombre d’entrées MFT avec deux attributs $FILE_NAME au contenu presque identique. L’exemple de code suivant (fonction parseFNAttr()) fournit un exemple de la façon dont un attribut $FILE_NAME d’une entrée MFT peut être analysé et les données disponibles extraites :

sub parseFNAttr {

mon $fn = shift;

mon %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{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;

}

Le dernier attribut que nous abordons est l’attribut $DATA (identifiant 0x80, ou 128). Cet attribut contient ou fait référence au contenu réel du fichier. Si l’indicateur non résident de l’en-tête de l’attribut n’est pas activé, le contenu du fichier est résident dans l’attribut $DATA de l’entrée MFT, après l’en-tête et deux structures supplémentaires. C’est généralement le cas pour les fichiers texte courts, par exemple, ou d’autres fichiers de moins de 700 octets. Si les données ne sont pas résidentes, alors les « parcours de données », ou l’endroit où les données sont situées sur le disque, doivent être traduits.

Le code d’exemple pour analyser les parcours de données de l’attribut $DATA est très impliqué et n’est pas présenté ici. De même, le code pour extraire des informations des attributs $DATA résidents est trivial et consiste à analyser quelques informations supplémentaires (taille du contenu et décalage vers le contenu) après l’en-tête de l’attribut.

Certains outils open source sont disponibles pour analyser le MFT (spécifiquement, les attributs $STANDARD_INFORMATION et $FILE_NAME) et mettre à disposition de l’analyste des données horodatées. L’un d’entre eux est le script Python analyzemft.py de David Kovar, disponible sur le Web à l’adresse http://www.integriography.com/projects/analyzeMFT. Un autre est le script Perl mft.pl, duquel ont été extraites les fonctions parseSIAttr() et parseFNAttr(), qui est disponible dans le WinForensicAnalysis Google Code projected, situé sur le Web à l’adresse http://code.google.com/p/winforensicaanalysis.

Les outils « The SleuthKit » (TSK) de Brian Carrier sont probablement les outils les plus connus pour collecter un large éventail d’informations sur le système de fichiers et les métadonnées du système de fichiers à partir d’images acquises et même de systèmes en direct. Par exemple, afin de collecter une liste des heures de fichiers d’attributs $STANDARD_INFORMATION du système de fichiers à partir d’une image acquise, un analyste peut utiliser une commande similaire à la suivante :

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

Cette commande produit ce que l’on appelle un « bodyfile », qui est un format de fichier intermédiaire utilisé pour stocker ces informations avant de les convertir en une chronologie de l’activité du système de fichiers. Dans certains cas, l’analyste peut avoir besoin d’ajouter le commutateur « -o » afin d’identifier le décalage de la partition qui est apparue sur le système vivant comme le lecteur « C:\ » ; cette information de décalage peut être déterminée manuellement via un éditeur hexadécimal ou en utilisant mmls.exe.

Un analyste peut également collecter ces mêmes informations à partir d’un système vivant et distant en utilisant F-Response. Si l’analyste s’est correctement connecté au système distant et a monté le lecteur C:\ du système en tant que F:\ sur son propre système, il peut alors utiliser une commande similaire à la suivante afin de collecter les temps de fichier de l’attribut $STANDARD_INFORMATION pour les fichiers de la partition C:\:

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

L’ensemble complet d’outils TSK, ainsi que la documentation et les informations d’utilisation, sont disponibles sur le Web sur le site Web SleuthKit, http://www.sleuthkit.org.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.