Challenge SSTIC et analyse de la mémoire physique des systèmes Linux
Signature : | Mis en ligne le : 18/12/2012
Catégorie(s) :
  • Misc
  • | Domaine :
    Commentez creative commons
    Article publié dans :
    Page 1/3
    Page suivante »

    À l’occasion du SSTIC 2010, l’ANSSI a conçu un challenge de forensics. Le but était d’analyser une copie de la mémoire physique (dump) d’un téléphone Android, afin d’y retrouver une adresse e-mail. Plusieurs solutions ont été trouvées pour résoudre ce challenge [SOL{1,2,3,4}]. L’une d’entre elles consiste à reconstituer la mémoire virtuelle de chaque application. Cette étape est certes difficile, mais non nécessaire, et a été contournée par un bon nombre de compétiteurs. En effet, l’outil de référence dans le domaine, Volatility [VY]Volatility, https://www.volatilesystems.com/default/volatility , ne fonctionne que pour les dumps mémoire provenant de Windows XP ; il ne gère pas les systèmes Linux. Cet article présente comment il est néanmoins possible d’y arriver, et détaille l’implémentation de Volatilitux [VUX]Volatilitux: Physical memory analysis of Linux systems, http://www.segmentationfault.fr/projets/volatilitux-physical-memory-analysis-linux-systems/ , outil open source réalisé par l’auteur à cette occasion.

    1. Introduction

    La mémoire physique correspond à la RAM d'une machine, qui contient l'ensemble des objets manipulés par le système au moment où l'acquisition est effectuée. On y retrouve notamment les fichiers ouverts (mappés), mais de par le mécanisme de pagination, ceux-ci ne sont pas forcément contigus en mémoire.

    Lors de l'analyse de la RAM, la première difficulté est que l'on ne dispose pas des registres du processeur. Nous n'avons donc pas directement accès aux tables de traduction permettant de retrouver les espaces mémoire virtuels des différents processus. Ce problème peut être partiellement contourné en ce qui concerne la mémoire noyau, car fort heureusement, le noyau Linux est mappé toujours au début de la RAM de façon linéaire. Cela permet d'accéder aux principales structures et, par exemple, de lister les processus et leurs propriétés (nom, PID, ...).

    Une autre difficulté, certes moindre, est de déterminer la taille des pages mémoire. Celle-ci dépend principalement de l'architecture utilisée. S'agissant ici d'un processeur ARM, la taille standard est de 4 kilo-octets.

    Vient alors un troisième obstacle : les offsets des champs contenus dans ces structures sont susceptibles de varier en fonction de la version du noyau et de sa configuration, a priori inconnues. Cela est dû à la présence de nombreuses macros et autres directives de compilation conditionnelle dans le code source du noyau. Retrouver les valeurs de ces différents offsets nécessite donc d'explorer un grand nombre de combinaisons possibles, qui dépend de la taille du dump mémoire. Celle-ci peut d'ailleurs être assez conséquente, variant d'une centaine de méga-octets (comme c'est le cas pour le challenge) à plusieurs giga-octets, ce qui peut s'avérer décourageant.

    Pour être en mesure d'analyser un dump, on suit donc une méthodologie en deux temps. La première est de déterminer les offsets des champs contenus dans les structures noyau. Deux méthodes permettant d'y parvenir sont détaillées ci-après. Une fois ces offsets calculés, nous pouvons alors localiser les structures, les parcourir, et en extraire des informations. Ces deux étapes ont été implémentées dans l'outil Volatilitux [VUX]Volatilitux: Physical memory analysis of Linux systems, http://www.segmentationfault.fr/projets/volatilitux-physical-memory-analysis-linux-systems/ , qui est présenté plus loin.

    2. Structures du noyau

    2.1. Processus

    Sous Linux, la structure noyau task_struct représente un processus. Voici un extrait de sa définition dans sched.h :

    Les champs pid et comm correspondent respectivement au PID du processus et au nom de l'exécutable. Le parent du processus est pointé par parent. Ces structures forment une liste doublement chaînée, chacune d'entre elles possédant une structure list_head. Celle-ci contient deux pointeurs, next et prev, qui pointent vers les éléments suivant et précédent. À vrai dire, ils pointent en réalité vers le début des structures list_head ; pour récupérer la task_struct correspondante, il faut soustraire son offset à la valeur du pointeur.

    2.2. Mémoire virtuelle

    Le champ mm de task_struct pointe vers une structure de type mm_struct, qui décrit les propriétés de l'espace mémoire du processus. Elle est définie dans mm_types.h et comporte deux champs particulièrement intéressants :

    Le champ pgd contient la valeur du registre CPU correspondant à l'adresse physique de la table de traduction d'adresses de premier niveau. Il s'agit typiquement du registre CR3 pour les architectures x86, et TTBR0 ou TTBR1 pour les processeurs ARM.

    Le tout premier champ de cette structure, mmap, pointe vers une liste simplement chaînée de structures vm_area_struct. Chacune d'entre elles correspond à une zone de mémoire contiguë (un ensemble de pages). La définition de cette structure se trouve également dans mm_types.h :

    Son premier champ désigne l'espace mémoire auquel la zone correspond, les autres recensent diverses propriétés de la zone mémoire. On y retrouve ses adresses de début et de fin (vm_start et vm_end), les droits d'accès (vm_flags), le fichier correspondant à la zone (vm_file) s'il s'agit d'un fichier mappé, ainsi que l'offset de cette zone au sein du fichier (vm_pgoff). Le champ vm_next pointe vers la zone suivante.

    Notons que la cartographie de la mémoire virtuelle d'un processus se limite à l'espace utilisateur, c'est-à-dire aux adresses virtuelles en dessous de la constante PAGE_OFFSET (qui vaut en général 0xC0000000). L'espace noyau situé virtuellement au-dessus est le même pour tous les processus et est mappé physiquement du début de la RAM.

    2.3. Fichiers

    La structure file est quant à elle définie dans fs.h. Son seul champ qui nous intéresse est un pointeur vers une structure de type dentry. Notons que pour les versions du noyau supérieures à 2.6.20, ce pointeur se retrouve au sein d'une structure path, elle-même intégrée dans file. Une macro définie au sein de cette structure permet d'accéder à ce membre en gardant la compatibilité avec les anciennes versions :

    Enfin, la structure dentry recense le nom du fichier en utilisant une structure intermédiaire, qstr, qui contient un tableau de caractères correspondant au nom du fichier :

    L'ensemble des structures ainsi que leurs relations sont illustrées sur la figure 1.

    Fig. 1 : Relations entre les structures noyau

    3. Détection automatique des offsets

    En parcourant toutes ces structures, il devient possible d'extraire la liste des processus du système et la cartographie mémoire de chacun d'entre eux, comprenant leurs fichiers ouverts. Ce point est détaillé plus loin. En attendant, nous faisons face à une difficulté principale : les adresses de ces structures ne sont pas connues a priori, ni les offsets des champs qu'elles contiennent.

    Vous souhaitez commenter cet article ?
    Brèves Flux RSS
    Édito : Linux Pratique N°77
    Édito : GNU/Linux Magazine N°160
    Édito : GNU/Linux Magazine Hors-Série N°66
    Édito : MISC Hors-Série N°7
    Édito : Linux Essentiel N°31
    Communication RSS Com. RSS Presse
    Misc, Partenaire de l’événement Hack In Paris.
    Linux Pratique, Partenaire de l’Ubuntu Party à la Cité des Sciences et...
    Linux Essentiel N°31 – Communiqué de presse
    GNU/Linux Magazine N°159 – Communiqué de presse
    Linux Magazine, Partenaire de Symfony Live Paris
    Rechercher un article dans notre base documentaire :
    En kiosque Flux RSS

    Le tout nouveau Misc est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Pratique est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau GNU/Linux Magazine est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau GNU/Linux Magazine HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Essentiel est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Open Silicium est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...