Post

Comprendre la MFT, sa structure et son contenu

Hello tout le monde !

Comme vous le savez, le système d’exploitation Windows repose sur le système de fichiers NTFS qui est l’une des composantes les plus importantes. Ce système de fichier contient un fichier appelé MFT qui contient une entrée pour chacun des fichiers et des répertoires présents dans ce système NTFS. Cette table va agir comme une sorte d’index afin de garder une trace de chacun d’eux.

Pour rappel, NTFS est le système de fichiers principal pour les versions récentes de Windows et Windows Server. Il vient remplacer le système FAT qui était utilisé avant.

Pour en revenir à la MFT, cette table est mise à jour à chaque création ou modification de fichier et celle-ci va contenir différentes informations intéressantes. Dans certains cas, la table MFT peut carrément héberger le contenu des fichiers si certaines conditions sont réunies. C’est ce qu’on appellera les fichiers résidents et nous allons voir comment retrouver leurs contenus à travers cet article.

Comme nous l’avons vu, chaque fichier ou répertoire d’un système NTFS va être présent dans la MFT. Celle-ci retrace également l’emplacement des fichiers dans les répertoires mais également les emplacements physiques des fichiers dans le disque et les métadonnées que nous allons découvrir plus tard. Chaque fichier va donc constituer ce que l’on appelle une entrée dans la MFT.

Il faut également savoir que la MFT est très peu documentée par Microsoft, cela vient du fait qu’un utilisateur n’est pas censé interagir avec elle.

Étant donné que la MFT est un élément crucial pour NTFS, son emplacement doit être connu par le système. Cet emplacement est inscrit en dur dans le boot record pour la table MFT mais également pour la MFT mirror, qui est plus ou moins le même fichier à un emplacement différent afin d’éviter les problèmes.

Structure de la MFT

Nous venons de voir l’idée générale de la MFT maintenant, place à la structure !

La MFT est un fichier qui se traduit par une structure qui peut être fragmentée en partie chronique avec des entrées empilées. Chacune de ces entrées fait 1024 octets (ou multiple si besoin) avec 4 principaux attributs. Même s’il existe d’autres attributs, je vais vous présenter ici les plus intéressants et les plus courants :)

Les attributs que nous allons analyser sont les suivants :

  • Header
  • 0x10 $STANDARD_INFORMATION
  • 0x30 $FILE_NAME
  • 0x80 $DATA Dans chaque MFT, les 16 premières entrées sont réservées pour des informations spéciales telles que la table MFT elle-même ou bien des fichiers clés comme $VOLUME ou $BOOT. On ne peut pas utiliser cet espace pour faire autre chose !

Concernant la structure d’une entrée de la table MFT, celle-ci est ordonnée avec des attributs qui se suivent. En réalisant un schéma simplifié reprenant l’idée générale de cette dite entrée, nous obtenons ça :

Image

La MFT est donc un grand fichier qui contient des informations sur tous les fichiers du système NTFS ! Il faut voir cela comme une grande boîte et la prenant dans sa globalité, on peut empiler les entrées ce qui donne une grande pile pouvant être schématisée comme suit :

Image

Le premier bloc que nous allons analyser est le bloc Header. Il fait une taille de 56 octets et est reconnaissable par sa signature de début de 4 octets contenant l’indication “FILE”.

1
46 49 4C 45

Ce bloc est important puisqu’il va contenir la vraie taille de l’entrée du fichier dans la table MFT. Avec cela, cet attribut contient les différentes informations sur si le fichier (ou répertoire) est supprimé du système NTFS avec une indication puisque il faut savoir que l’entrée va rester en dur sans être effacée de la base MFT même si on le supprime de la base NTFS. C’est ce qu’on appel la réference et c’est ce qui permet de retrouver les fichiers lors d’opération plus complexe. On va également avoir les indications si l’entrée décrit un fichier ou un répertoire mais également l’Id de l’entrée qui va être importante plus tard pour retrouver les Parents ID !

0x10 ($STANDARD_INFORMATION)

La table 0x10 est la table contenant les informations standards. Elle fait une taille minimum de 48 octets avec un maximum à 72 octets !

Ce bloc va contenir des informations relatives aux timestamps ! Avec la date de création du fichier, la date de dernière modification, la date du changement dans les records (MFT) ainsi que la date de dernier accès qui peut être très utile dans les études forensic.

Voici un schéma qui reprend la structure de l’attribut 0x10 :

Image

0x30 ($FILE_NAME)

Ce bloc contient des informations sur le fichier avec sa taille logique (vraie taille) ainsi que sa taille virtuelle (dans le système de fichier). Il contient également le nom du fichier en caractère en texte Unicode.

Voici un schéma qui reprend la structure de l’attribut 0x30 :

Image

0x80 ($DATA)

Le bloc 0x80 est un bloc important car il contient les Datas ! C’est lui qui va contenir les données du fichier si celui-ci est résident ou non. Et par la même occasion, l’indication si le flag est un fichier résident.

Voici un schéma qui reprend la structure de l’attribut 0x80 :

Image

0xff (End marker)

L’attribut 0xFF indique le marqueur de fin. Cela fait référence à la fin des attributs et est le dernier attribut avant la fin de l’entrée. Il faut noter que celui-ci peut être utilisé comme remplissage si le fichier est supprimé ou si on a besoin de remplir jusqu’au 1024 octets !

Fichier résident

Les fichiers résidents sont des types de fichier ou leur contenu est stocké intégralement dans la MFT. Cela permet d’alléger le système de fichiers, pour qu’un fichier soit résident, il faut que son contenu ait une taille inférieure à 512 octets. Dans le cas contraire, le fichier sera “classique” et stocké dans le système NTFS !

Afin de savoir si notre fichier est un fichier résident, il faut mettre un marqueur sur l’attribut 0x80 puis regarder l’hexadécimal qui va comporter un Flag avec l’indication du fichier résident

En prenant la 9ème paire après le début du bloc 0x80, on va avoir 2 cas :

Fichier résident
1
80 00 00 00 XX XX 00 00 00
Fichier non résident
1
80 00 00 00 XX XX 00 00 01

Pratique

Maintenant que nous avons vu en théorie comment était constituée la table MFT, je me suis dit qu’il serait bien de voir ça avec un exemple réel pour mieux comprendre et pouvoir reproduire ça ensemble. Pour cela, nous allons utiliser FTK Imager qui est un outil Forensic pour chercher les données dans des images ou des systèmes de fichier !

Header

Nous allons arriver sur une entrée de la MFT reconnaissable grâce à l’appellation FILE au début de celle-ci !

L’appellation “FILE” est caractérisée par la suite des code hexadécimal :

1
46 49 4C 45 30 00 03 00-

Image

Étant donné que la taille du bloc header est de 56 octets, nous pouvons directement regarder grâce a FTK Imager, la taille réelle !

Become a member Ici, nous voyons bien le bloc header avec le début du bloc et sa taille de 56 octets, nous nous arrêtons directement au début du bloc 0x10 une fois ces octets parcourus.

Image

0x10

Une fois au début de ce bloc trouvé grâce au Header, nous trouvons un premier pattern qui va nous permettre de trouver la taille du bloc comme suit :

1
10 00 00 00 XX XX

Le numéro XX va nous donner la taille du bloc jusqu’à celui 0x30. Étant donné que 60 en hexadécimal nous donne 96, nous allons prendre les 96 prochains octets.

Image

A l’intérieur de ce bloc, il ne faut pas oublier qu’on peut trouver les 4 timestamps suivants !

  • La date de création du fichier
  • La date de dernière modification
  • La date du changement dans les records (MFT)
  • La date de dernier accès Nous pouvons retrouver ces 4 informations ici 🙂

Image

0x30

Grâce à la taille du bloc 0x10, nous arrivons encore une fois, au début du bloc 0x30 donc on peut connaitre la taille grâce au même pattern que pour le bloc 0x10 :

1
30 00 00 00 XX XX

Dans notre cas, nous avons une première taille de 120 octets.

Image

Cependant, lorsque nous arrivons à la fin, nous ne tombons pas sur un bloc 0x80 !

Image

Il peut y avoir plusieurs fois le bloc 0x30 donc il faut refaire le processus. En trouvant la taille :

Image

En allant voir 312 octets plus loin, nous tombons sur le début du bloc 0x80 comme espéré !

Image

0x80

Encore une fois, le procédé reste le même pour trouver la taille :

80 00 00 00 XX XX Avec une taille de 72 (48 en hexadécimal), nous tombons sur la fin du bloc

Image

Cependant, ce bloc nous indique également s’il est résident grâce au FLAG (j’espère que vous ne l’aviez pas oublié ;) ) Pour le trouver, il faut regarder depuis le début du bloc si nous avons

  • 00 pour un fichier résident
  • 01 pour un fichier non résident Sur l’emplacement :
1
80 00 00 00 48 00 00 00 XX

Dans notre cas, le fichier n’est pas résident car il contient 01 !

Image

0xff

Nous arrivons maintenant sur le bloc 0xff de fin de marqueur qui est reconnaissable par sa signature :

FF FF FF FF Nous avons donc par la suite, un remplissage des données !

Utiliser les données de la MFT

Récupérer les données

Étant donné que la visualisation de la MFT uniquement en hexadécimal est un processus long et fastidieux, nous avons besoin d’un outil qui permet de rechercher à l’intérieur de celle-ci afin d’en extraire les informations intéressantes.

Dans le cas de la MFT, nous allons avoir 2 grandes étapes dans ce processus de visualisation avec :

  • L’extraction des données sous la forme CSV
  • La visualisation de ce CSV via un outil

MFTECmd L’outil que nous allons utiliser afin d’extraire ces données se nomme MFTECmd. Il a été développé par Eric Zimmerman et son répertoire github est public et accessible via le lien suivant :

  • https://github.com/EricZimmerman/MFTECmd
Il faut savoir que cet outil fait partie d’une suite qu’Eric Zimmerman a développée très intéressante !

Une fois l’outil téléchargé, il nous suffit de l’exécuter en indiquant le fichier source et la sortie par la suite comme suit :

1
.\\MFTECmd.exe -f '{PATH VERS LA MFT}' --csv ./ [-dr]

| L’option -dr permet d’avoir les informations sur les fichiers résidents

Image

Une fois la commande exécutée, nous allons avoir le fichier de sortie CSV contenant toutes les informations nécessaires :)

Image

Visualiser les données

Une fois les données extraites et formattées en CSV, nous avons besoin d’un autre outil développé par Eric Zimmerman afin de les visualiser correctement.

Cet outil s’appelle Timeline Explorer et il est disponible via cet url :

  • https://ericzimmerman.github.io/#!index.md Une fois lancé, nous avons juste à charger le fichier CSV fraîchement créé et nous pouvons accéder aux données !

Pour ce faire, on commence par lancer l’application et cliquer sur File

Image

Cliquer sur Open

Image

Une fois le fichier sélectionné, nous avons ce résultat :

Image

Dans cette interface, nous retrouvons toutes les informations disponibles dans la MFT !

À vous d’explorer toutes les possibilités maintenant !

Conclusion

Nous venons de voir que la MFT joue un rôle central pour le système de fichiers NTFS en contenant des métadonnées sur tous les fichiers et dossiers. Avec une organisation structurée, chaque fichier comporte des attributs bien distincts que nous avons étudiés (HEADER, 0x10, 0x30, 0x80, 0xff). Cette table peut également contenir le contenu des fichiers dans un certain cas et ces fichiers sont alors appelés Résident. Cette table est importante dans les analyses forensic puisqu’elle contient des données précieuses sur les fichiers supprimés ou même consulter un historique d’accès ou de modification des fichiers !

Je vous remercie d’avoir lu cet article et si vous avez des questions, n’hésitez pas à mettre un commentaire, je me ferais une joie d’y répondre !


Ressources

https://www.youtube.com/watch?v=B4b6Ocf3wYs&t=432s https://www.futurelearn.com/info/courses/introduction-to-malware-investigations/0/steps/146826 https://www.futurelearn.com/info/courses/introduction-to-malware-investigations/0/steps/147562 https://github.com/EricZimmerman/MFTECmd https://www.exterro.com/digital-forensics-software/ftk-imager

This post is licensed under CC BY 4.0 by the author.