# Analyse d'images mémoire

L'analyse d'images mémoire ou dumps mémoire (memory dump en anglais) est une pratique qui consiste à récupérer, acquérir le contenu de la mémoire volatile d'un système et à en extraire des informations pertinentes.
Le système d'exploitation peut fournir à l'investigateur nombreuses informations lors de l'analyse de la mémoire parmi lesquelles on trouve la liste des processus, des connexions réseaux, des préférences utilisateur, etc. Cette technique se développe rapidement depuis une dizaine d'années et plus particulièrement à la suite du concours Digital Forensic Research Workshop 2005 dont le thème Memory analysis challenge, a fait émerger une nouvelle branche dans le domaine de l'investigation digitale.

## Objectifs

Parmi les différents objectifs de l'analyse d'image mémoire, on peut trouver :
* la possibilité de compléter l'analyse traditionnelle de stockages persistant (disques durs, supports de stockage amovibles, , etc.) ;
* la difficulté de l'analyse traditionnelle due à la croissance importante des capacités des périphériques stockage ;
* l'analyse de malwares ou autres données comme les conversations électroniques qui résident en mémoire uniquement ;
* l'extraction de clés de chiffrement de périphériques de stockage.

## Acquisition d'image mémoire

Selon la RFC3227, l'ordre de la volatilité impose à l'investigateur d'effectuer une sauvegarde de l'état actuel du système en cas de compromission de celui-ci dans l'ordre cache, registres, mémoire centrale, système de fichiers temporaires et enfin support de stockage persistant. L'acquisition a pour but de préserver l'état du système à un instant donné pour permettre une analyse post-mortem ou de réponse aux incidents. Il existe plusieurs moyens d'acquérir la mémoire d'un système que cela soit sur un environnement serveur ou de bureau. Il est possible de définir plusieurs critères qui permettent de savoir à quel point une image mémoire est solide ou fiable. La fiabilité d'une image mémoire est :
* correcte si l'image contient exactement les valeurs qui étaient stockées dans la mémoire au moment de l'acquisition (le degré de correction est un pourcentage de la mémoire qui a été acquis avec succès par rapport la taille totale de mémoire).
* atomique si l'image n'est affectée par aucune activité concurrente (le degré d'atomicité est le pourcentage cohérent de l'image mémoire).
* intègre si l'outil d'acquisition ne contamine pas l'image de la mémoire (par exemple, les outils logiciels modifient obligatoirement l'image mémoire car ils doivent être chargés avant d'être exécutés).
Ainsi, il est possible d'établir un classement des méthodes d'acquisition en marquant différentes régions de la mémoire cible avec des tags. Ces tags pourront être étudiés après acquisition et permettront de savoir avec quelle fiabilité l'image a été acquise. Les tags sont de simples horodatages incrémentés de manière constante par le système cible. En comparant les différentes valeurs des tags acquis, on constate le temps écoulé entre le début et la fin de l’acquisition.
Les différentes techniques d'acquisition peuvent être soit matérielles ou logicielles.

### Acquisition matérielle
#### Cold boot attack

Contrairement à ce que l'on pourrait penser, la DRAM utilisée de nos jours dans la majeure partie des ordinateurs peut retenir son contenu pendant plusieurs secondes sans alimentation et cela même à une température ambiante tout en étant débranchée de leur carte mère. Bien que le contenu de la DRAM devient moins fiable si celle-ci n'est pas alimentée, il n'est pas immédiatement effacé et peut persister suffisamment longtemps pour permettre une acquisition matérielle de l'ensemble de la mémoire d'un ordinateur. Avec des températures faibles, la DRAM conserve son contenu encore plus longtemps. Le pourcentage d'erreur de l'image acquise lorsque la DRAM est refroidis par de l'air comprimés appliqué directement sur les chips est de 1% après 10 minutes sans alimentation (image correct à 99%), alors que le pourcentage d'erreur lorsque l'image est refroidie par de l'azote liquide est de 0.17 % après 60 minutes sans alimentation (image correcte à 99.83 %).
Ainsi, il est possible d'utiliser un mini-système sur un support bootable comme une clé USB dont l'unique but est de faire une image de la mémoire après avoir fait un redémarrage à froid de la cible lorsque l'on souhaite faire l'acquisition. Il est également possible, si l'ordinateur cible ne permet pas de choisir le périphérique de démarrage, de débrancher les chips de mémoires pour en acquérir l'image sur un système où l'investigateur a un accès suffisant. Bien que ce mini-système doit néanmoins être chargé en mémoire pour pouvoir s’exécuter, il est possible de configurer le secteur d'amorçage de manière à charger le système à un emplacement de la mémoire physique dont on sait que les informations sont déjà connues et ont une moindre valeur lors de l'acquisition. Par conséquent, le degré d'intégrité est dans ce cas de 100 %. Le degré d'atomicité ici est de 100 % car plus aucune activité relative au système cible ne s’exécute lors de l'acquisition.
Des mécanismes ont été développés et incorporés dans les architectures de microprocesseur depuis la DDR3 empêchant l'acquisition par une cold boot attaque. Un de ces mécanismes appelé brouillage des données de la mémoire (memory data scrambling) est basé sur un masque généré de manière aléatoire et sur le fait d'effectuer un OU exclusif (XOR) avec la donnée avant être incorporé dans la DRAM3. Ainsi une acquisition telle que définie ci-dessus ne permet de récupérer que des données brouillées et inutilisable en tant que telle. L'étape inverse du brouillage des données de la mémoire consiste donc simplement en la récupération de la donnée de la DRAM3, puis en l'application à nouveau du masque un OU exclusif pour extraire l'information en claire. Des études ont montré que ce type de protection est toutefois inefficace si l'on connaît uniquement une petite partie (128bits) de données en claire. Des architectures récentes de microprocesseur comme la 6e génération de microprocesseur Intel Skylake qui adoptent le brouillage des données de la mémoire sont également vulnérables par ce type d'attaque.

#### Direct Memory Access

La mémoire peut être acquise via la DMA (Direct Memory Access). Cette acquisition utilise un bus système tel que celui des cartes PCI pour copier la mémoire sur un stockage externe. Une des limitations de cette approche est que la carte doit être installée sur une interface PCI avant le démarrage du système. Lors du démarrage du POST, la carte s'initialise et éteint son contrôleur PCI de manière à cacher sa présence. La carte reste inactive en attente d'une acquisition via un interrupteur situé sur la carte. Cette carte est donc difficilement détectable par un potentiel malware cherchant à se dissimuler lorsqu'un tel périphérique est détecté. Avant l'acquisition, le CPU est en pause de manière à empêcher un potentiel malware de modifier le déroulement correct de l'acquisition. Par conséquent, le degré d'atomicité de l'image mémoire est également de 100 % lorsque le CPU est stoppé. Une autre limitation de cette technique d'acquisition est qu'elle ne permet pas d'acquérir l'ensemble de la mémoire. En effet, certaines régions de la mémoire, notamment l'UMA, sont utilisées par le BIOS. Lors d'une tentative d'acquisition de cette zone, la procédure bloque sans qu'aucune interaction puisse la relancer sauf un redémarrage ou le passage de la zone générant le blocage. Dans ce dernier cas, l'intégrité de l'image mémoire ne peut être de 100 % et correspond à l'espace des zones acquises sans blocage par rapport à la capacité totale de la mémoire du système cible.
L'acquisition matérielle ne fait pas de différence quant au système d'exploitation en cours d’exécution sur la machines. Elle peut être préférée à l'acquisition logicielle car elle ne modifie pas le contenu de la mémoire du système cible. Cependant, le principal inconvénient est le coût de l'équipement nécessaire.

### Acquisition logicielle

L'acquisition logicielle est une technique d'acquisition qui est peu coûteuse, généralement gratuite et disponible aisément. Ces raisons font que les outils d'acquisition logicielle sont préférés à l'acquisition matérielle.

#### Système Linux

Sur les systèmes d'exploitation Linux, il existe deux périphériques nommés /dev/mem et /dev/kmem qui manipulent et permettent d'accéder respectivement à la mémoire physique et à la mémoire virtuelle du kernel. Historiquement, ces deux périphériques pouvait être lus en utilisant le programme dd natif sur Linux. Cependant, sur les versions récentes du système d'exploitation Linux, des protections empêchent par défaut l'utilisation de ces périphériques et il est nécessaire d'avoir compilé son noyau Linux avec une configuration particulière pour accéder à cette fonctionnalité.
Fmem est un projet open source qui permet l'acquisition de la mémoire physique sur un système Linux. Ce dernier est basé sur l'installation d'un module au noyau qu'il faut compiler permettant donc d'avoir accès à l'ensemble de la mémoire physique. L'outil créé un périphérique nommé /dev/fmem qui reprend les mêmes bases que /dev/mem sans les protections dernièrement ajoutées. LiME (anciennement DMD) est une variante de Fmem fonctionnelle sur les systèmes d'exploitation Linux mais également sur les variantes du système d'exploitation Android. Cet outil présente certains avantages comparé à Fmem, outre le fait que Fmem ne peut pas être utilisé sur Android. Lime utilise l'installation du module avec certains paramètres pour immédiatement extraire l'ensemble de la mémoire physique vers un fichier ou vers une socket TCP.

#### Système Windows

Une technique commune pour acquérir l'image mémoire d'un système Windows est de s'appuyer sur l’objet \\.\Device\PhysicalMemory qui représente une abstraction de la mémoire physique vue par le système. Pour des raisons de sécurité, cependant, les droits d'accès en tant que simple utilisateur ont été révoqués à la suite de l'introduction de Microsoft Windows Server 2003 Service Pack 1. Pour cette raison, il est nécessaire de disposer d'un module/driver installé sur le système cible ainsi qu'un programme associé en mode administrateur pour permettre l'acquisition. Si les droits permettant l'acquisition de l'image mémoire du système ne sont pas suffisants, il reste possible d'acquérir individuellement les processus de l'utilisateur courant. L'accès à la mémoire d'un processus en cours d'exécution est même fourni nativement par le système d'exploitation Windows. Cependant, les structures internes du système ainsi que la mémoire privée allouée pour d'autres processus sont inaccessibles.
Une étude met en évidence les performances de différents outils logiciels d'acquisition open source (une modification mineure du code est nécessaire pour l'étude) en se basant sur les critères définis par Vömel et Freiling. L'environnement défini par l'expérimentation utilise Bochs, un émulateur similaire à QEMU dans lequel le système invité est capable de communiquer avec l’émulateur via des hypercalls. Ces hypercalls utilisent le registre EAX ainsi que l'interruption INT 3 pour indiquer un événement particulier. Parmi les événements, il est décrit le début de l'acquisition, le début de l'acquisition d'une page, la fin de l'acquisition d'une page ou encore la fin de l'acquisition. L'interruption générée est traitée par l’émulateur sans que le système invité ne soit altéré dans son fonctionnement. Toutefois, il est nécessaire d'apporter des modifications aux outils d'acquisition logicielle permettant ainsi de déclencher ces hypercalls et donc de mesurer les performances.
Trois outils d'acquisition d'acquisition open source ont été testés :
* wind32dd
* ManTech Memory DD
* WinPMEM
Les trois outils révèlent des degrés de fiabilité (correctness) de plus de 99 % dans tous les cas (capacité de la mémoire du système cible de 512 Mo, 1 024 Mo ou 2 048 Mo). Le degré d'atomicité lui est compris entre 60.45 % et 62.71 % pour une capacité de mémoire de 512 Mo et de 25 % pour une capacité de mémoire de 2 048 Mo. Le manque d'atomicité avec l'augmentation de la capacité de la mémoire est dû au temps mis par l'acquisition de la mémoire et à l’exécution d'activités concurrentes qui modifient le contenu de la mémoire pendant l'acquisition et donc augmentent les chances d'avoir des incohérences entre les données des pages acquises. Le degré d'intégrité est inversement meilleur avec l'augmentation de la capacité de la mémoire. Il est compris entre 72.627 % et 71.413 % pour une capacité de la mémoire de 512 Mo et entre 82.095 % et 81.553 % pour une capacité de 2 048 Mo. Pour les trois outils d'acquisition open source wind33dd, ManTech Memory dd et WinPMEM, on constate que le degré d'intégrité, de fiabilité et d'atomicité est équivalent.
Cependant, d'autres outils propriétaires permettent d'acquérir la mémoire d'un système. Vömel et Freiling exposent plusieurs de ces outils et tentent de classer les outils non pas entre eux individuellement mais plutôt entre catégories (hardware acquisition, kernel-level acquisition, virtualisation/emulation). Certains des outils propriétaires ont été testés parmi lesquels figurent :
* FTK Imager
* DumpIt
Il est possible d'effectuer sur toutes les versions de Windows un dump de la mémoire physique incluant les dumps dits kernel dump ou complete dump grâce à une fonctionnalité fournie par Windows. En effet, un BugCheck (plus connu sous le nom de Blue Screen Of Death) peut être généré manuellement par l'utilisateur soit par une configuration à effectuer dans le registre du système permettant de déclencher le BugCheck avec une combinaison de touches du clavier, soit en lançant un programme appelé NotMyFault.exe développé par Mark Russinovich. Le BugCheck génère automatiquement un dump mémoire. Le dump mémoire généré n'est pas une image RAW mais une image modifiée de celle-ci avec certaines structures ajoutées de manière à être directement utilisable par le debugger Windows WinDBG.

### Acquisition via machine virtuelle

QEMU est un logiciel libre de machine virtuelle, pouvant émuler un processeur et, plus généralement, une architecture différente si besoin. Il est possible de récupérer via l'option -monitor stdio la mémoire utilisée par le système cible. Il est possible de faire l'acquisition de la mémoire en utilisant la commande pmemsave <starting_physical_address> <size> <output_file >.
VirutalBox est un logiciel de virtualisation de systèmes d'exploitation. De la même manière qu'avec QEMU, il est possible de récupérer l'image de la mémoire avec une commande vboxmanage debugvm <vmname> dumpguestcore --filename <output_file>. L'image générée par VirtualBox n'est pas un copie exacte octet par octet de la mémoire mais un format core dump binaire destiné notamment à des fins de debuggage. Il existe cependant des outils qui permettent de convertir le fichier généré au format RAW (c'est-à-dire un fichier dont chaque octet représente physiquement le contenu acquis). L’outil Volatility permet de faire une telle conversion ou de traiter/analyser directement le fichier au format core dump. Durant la phase d'acquisition, le système cible est en pause. Par conséquent, l’atomicité, l'intégrité ainsi que la fiabilité de l'acquisition (correct image) sont de 100 %. Dans tous les cas de virtualisation/émulation, c'est l'hyperviseur qui permet d'extraire le contenu de la mémoire et cela sans que le système invité ne soit interrompu dans son exécution.

## Analyse de l'image mémoire

Une fois l'image de la mémoire d'un système effectuée, la phase d'analyse peut commencer. Plusieurs méthodes d'analyse de la mémoire ont été créées.

### Analyse non structurée

L'analyse de l'image mémoire a commencé au début du XXIe siècle lorsque les investigateurs forensic ont réalisé qu'ils pouvaient obtenir la mémoire directement d'un système en cours d’exécution via les interfaces d'acquisition cités plus haut. À l'époque, on pouvait déjà trouver rootkits difficile voire impossible à détecter sur un système en cours d’exécution ainsi que des techniques anti-forensic pouvant tromper les outils dynamiques d'analyse (live analysis). Cependant, durant cette période, on ne pouvait trouver de framework ou d'outils plus matures que l'utilisation d'outils tels que la recherche de chaîne de caractères (via les commandes strings et grep) ou encore les éditeurs hexadécimaux pour trouver des données intéressantes. Ces techniques sont de nos jours qualifiées d'analyse non structurée.

### Analyse structurée

Au début de l'année 2005, le Digital Forensic Research WorkShop a divulgué son challenge annuel. Ce challenge demandait aux investigateurs participant d'effectuer une analyse de l'image mémoire d'un système Windows fourni. Le challenge a mené à la réalisation de plusieurs outils développés dans les années suivantes dont KntTools, Comae (anciennement MoonSols), FATKit ou le plus connu, Volatility (anciennement VolaTools).

#### Énumération des processus via méta-données

Deux outils qui analysent les images mémoires systèmes Windows ont été proposés lors du DFRWS de 2005. Le premier, appelé MemParser, permet une énumération des processus actifs ainsi que le dump de la mémoire spécifique à un processus particulier. Le deuxième, appelé Kntlist, produit une liste conséquente des processus, threads, handles et d'autres objets générés depuis plusieurs listes et tables du noyau. Ces travaux s'appuient tous sur le parcours de méta-données type listes et tables pour extraire les informations des images mémoires. Ces métadonnées sont généralement trouvées via un point d'entrée dans l'image mémoire qui correspond en général à une variable globale du noyau$^,$.

##### Limitations pour les processus terminées

Lorsqu'un processus est terminé ou détruit, le système retire le processus en question de la liste des processus en cours d'exécution et désalloue la mémoire attribuée processus. Par conséquent, une énumération de processus via les méta-données (listes, tables) ne permettra pas de retourner les processus récemment terminés ou détruits.

##### Limitation pour les processus malicieux

Certaines manipulations dans l'espace d'adressage du noyau par des malware ou rootkits peuvent masquer leur présence en dissimulant un processus en cours d’exécution. En effet, ces malwares disposant d'un accès suffisant pour manipuler de telles listes pour s'extraire de la liste des processus actifs. Ce type de techniques visant à dissimuler l'exécution d'un processus malveillant est plus connue sous le nom de Direct Kernel Object Manipulation.

#### Énumération des processus via recherche de patterns/signature

Dans le cas où la mémoire attribuée à un processus est désallouée, le système ne réécrit pas sur les plages d'adresses et ces plages d'adresses peuvent demeurer ainsi avec leurs contenus plusieurs jours. Dans le cas d'une attaque de type DKOM, la mémoire allouée au processus malveillant est toujours présente. Il est proposé dans une autre étude de ne pas parcourir uniquement les listes fournies par le système mais d'effectuer à la place une recherche linéaire de l'image mémoire pour trouver des structures de données représentant un processus ou des structures de données représentant un thread.
Dans le cas de Windows, qui est un système basé sur l'objet, tous les objets sont définis par une structure de données nommée Object_Header. Parmi les membres de cette structure figure un pointeur vers une structure Object_Type nommée Type. Pour déterminer quelles sont la valeur que doit prendre ce Type, l'auteur propose d'effectuer pour chaque version différente du système une récupération des valeurs associées à deux Object_Type nommé PsProcessType et PsThreadType. Ces deux Object_Type sont les valeurs associées respectivement à un objet de type processus et à un objet de type thread. L'auteur définit une liste de règle ou signature qui spécifie comment ces structures (et d'autres comme Dispatcher_Header, Eprocess, Ethread ou encore Pool_Header) sont organisées entre elles, à quels endroits elles peuvent être trouvées grâce à un total de 20 règles. L'analyse de l'image mémoire proposé lors du challenge de 2005 a permis de confirmer que ce type d'analyse via des règles est fiable en récupérant la même liste des processus que le vainqueur du challenge. Le programme utilisé pour effectuer cette analyse est PTFinder (pour Process and Thread Finder). Il a également été récupéré plusieurs processus non détectés par le programme du vainqueur du challenge car correspondant à des programmes anciens précédant un redémarrage de la machine sur laquelle a été acquis l'image mémoire. Les structures de données de ces processus ont persisté après le redémarrage dans la mémoire acquise.

#### Pool Scanning

Sur les systèmes d'exploitation Windows, le gestionnaire de mémoire (Memory Manager) est chargé d'attribuer la mémoire pour les applications utilisateurs mais aussi pour les structures de données internes au système. Du fait de leur importance pour le bon fonctionnement du système, ces structures de données sont allouées dans des sections mémoires similaires à des tas (heap) appelées pools d'allocation non paginable. Il existe deux types de pool d'allocation, le pool paginable et non paginable. Le pool non paginable est un ensemble de pages qui restent dans la mémoire et ne peuvent être paginées sur un support de stockage persistant. Le gestionnaire de mémoire préfixe chacune des allocations avec une structure de données Pool_Header. Dans cette structure de données est défini le type pool utilisé (paginable ou non paginable) ainsi qu'un pool tag. Le pool tag est utilisé pour spécifier quelle est le type de structure de données sous-jacent à l'allocation. Le pool tag est représenté sur 4 octets correspondant à des caractères ASCII bien spécifiques en fonction de la structure de données allouée. Parmi les pool tags du système, on peut trouver celui des processus, des thread mais aussi celui des connexions actives.
Le pool Scanning est une technique et parcourt linéairement le fichier image de la mémoire pour trouver des pool des structures de données recherchées. De la même manière que pour la rechercher via signature, il est nécessaire de spécifier plusieurs règles pour écarter au maximum les faux positifs.

#### Extraction des connexions actives

Le pool tag utilisé pour la technique du pool scanning peut également servir par exemple à extraire la liste des connexions réseaux actives sur un système Windows (Windows 7 64bits dans notre cas). L'extraction repose sur la recherche d'une chaîne de caractères TcpETcpE, puis à l'ajout d'un offset depuis l'adresse retournée pour récupérer une adresse virtuelle. La translation de cette adresse virtuelle vers une adresse physique permet de récupérer la base de la structure de données représentant une structure nommée Tcp_Endpoint ou TCB. Un des membres de cette structure est une liste doublement chainée qui parcourt l'ensemble des structures TCB associées aux connexions actives.

#### Framework d'analyse d'image mémoire

Une des difficultés rencontrées lors d'analyse d'image mémoire est la complexité des données acquises. Sur un système multitâche classique, un espace d'adressage physique contient fréquemment du code machine, des données initialisées ou non, et des structures de données spécifiques à une architecture logicielle pour une multitude de programmes différents. De plus plusieurs processeurs supportent la virtualisation de la mémoire, où chaque programme ou système d'exploitation peut avoir une vision différente de l'espace d’adressage. Par exemple, la famille de microprocesseurs x386 propose deux types de virtualisation de la mémoire, la pagination et la segmentation. Des parties de l'espace d'adressage virtuel peuvent se trouver dans la mémoire physique, sur disque, ou peuvent ne pas exister du tout. De plus, suivant l'implémentation de chacun, les programmes peuvent s'organiser de manière quasi-aléatoire. Les différences de langages de programmation, de compilateurs, d'API (Application Programming Interface), des bibliothèques systèmes rendent chaque système sensiblement différent. La moindre modification de l'organisation de l'image mémoire à la suite d'une modification lors d'une de ces étapes peut empêcher un système d'analyse mémoire de fonctionner. L'outil d'analyse doit donc être redéfini peut-être même entièrement pour permettre le fonctionnement sur la nouvelle version du système.

##### Framework FATKit

Par conséquent, le besoin d'un framework stable à partir duquel il n'est plus nécessaire de redéfinir toute cette chaîne de dépendance pour le rendre compatible avec une nouvelle version d'un système se fait ressentir. Dans cette optique, FATKit est développé avec l'idée d'apporter une abstraction des systèmes ciblés. Ainsi sont définis diverses fonctionnalités pour chaque niveau d'abstraction parmi lesquelles on peut trouver la mémoire physique, la mémoire virtuelle ou les structures de données propre à une application. FATKit est framework modulaire qui définit des abstractions initiales qu'il est possible d'étendre via d'autre modules d'abstractions définissant d'autres types de systèmes. L’architecture du framework se compose de :
* la classe AddressSpace utilisée comme base pour l'implémentation de modules d'espace d'adressage supporté par un processeur ;
* d'objets et de profils définissant les types de données qui peuvent être trouvées à un certain espace d’adressage ainsi que leur représentation pour une certaine version d'un système (en fonction d'un programme, d'un langage, ou d'une architecture) ;
* de modules de vue des données qui ne définissent pas comment les données sont organisées mais plutôt où sont-elles situées ;
* de modules d'analyse des données permettant d'automatiser certaines tâches en se basant sur les données récupérées depuis le modèle de vue ;
* et de modules de visualisation dont l'unique but de présenter le résultat depuis le module d'analyse.

###### Génération automatique de profils

Il est possible de générer le modules des objets et profiles automatiquement à condition de disposer du code source C d'un programme à l'aide d'une fusion (merger) de code source C et d'un générateur de profils. Le profil généré peut être inclus dans le framework et peut être utilisé dès lors.