Relevé de configuration matérielle sur plateforme x86

Magazine
Marque
MISC
Numéro
109
Mois de parution
mai 2020
Spécialité(s)


Résumé

Sur une plateforme de type PC, la configuration des éléments matériels se trouve répartie dans de nombreux registres accessibles par différents moyens. Cet article présente les différents modes de collecte de ces informations, exploitables par la suite pour des vérifications de sécurité.


Body

1. Introduction

Sur une plateforme x86 moderne, la configuration matérielle se trouve dispersée dans de nombreux composants. Cette configuration comprend à la fois des aspects fonctionnels (configuration de l’adresse MAC d’une carte réseau, fréquence d’horloge ou voltage d’un processeur) et des aspects liés à la sécurité (configuration du contrôleur mémoire, verrouillage de la mémoire flash…).

L’écosystème x86 a eu tendance à se complexifier ces dernières années, entraînant parfois des vulnérabilités liées à un manque de communication entre les fabricants de composants, les concepteurs de BIOS et les intégrateurs. La vérification qu’une plateforme est correctement configurée nécessite l’accès à de nombreux espaces de configuration répartis dans différents composants, pas forcément identiques d’une machine à une autre. L’ANSSI s’est intéressée ces dernières années à la façon de valider des configurations matérielles pour vérifier qu’elles sont à l’état de l’art vis-à-vis des attaques publiées.

Dans cet article, nous allons nous intéresser aux méthodes d’accès aux différents registres de configuration présents sur une machine de type x86 récente. Un autre article (Chipsec, un outil pour les tests de conformité des firmwares) présent dans le dossier de ce numéro de MISC, de plus haut niveau, s’intéresse à la mise en cohérence des informations collectées afin de vérifier la bonne configuration de la machine et l’absence de vulnérabilités connues.

BIOS , UEFI, firmware : dans cet article, nous utiliserons indifféremment ces termes pour désigner le code exécuté par le processeur au démarrage de la plateforme pour initialiser celle-ci. Toutes les machines considérées supportent le standard UEFI.

2. Notions de registre

Un registre de configuration est un espace physique bien délimité (mémoire d’un contrôleur de périphérique, mémoire du CPU, etc.) stockant des données de configuration spécifiques.

Un registre définit généralement, à travers des valeurs précises, le comportement d’un périphérique ou les droits associés à celui-ci. Certaines valeurs n’ont pas d’importance sur le niveau de sécurité, mais d’autres sont cruciales. À titre d’exemple, il existe une valeur de registre responsable du verrouillage de la mémoire flash SPI stockant le BIOS et empêchant ainsi son altération depuis un système d’exploitation. L’absence de verrouillage de cette mémoire rend par exemple possible l’installation d’une porte dérobée non détectable par les antivirus, car non présente sur le disque dur, mais uniquement dans le BIOS.

Le parcours de la documentation des chipsets Intel montre qu’il existe un nombre très important de registres et valeurs possibles sur une plateforme x86, et qu’ils ont souvent des dépendances entre eux qui ne sont pas forcément simples à identifier : le bit a1 d’un registre Ra peut être nativement positionné correctement, mais si le bit b1 du registre Rb, responsable du verrouillage de Ra, n’est pas correctement verrouillé alors le bit a1 peut finalement être modifié.

Un élément important à préciser est que ces valeurs de registre sont définies généralement via le BIOS au démarrage de la plateforme. Des paramètres de sécurité non conformes nécessitent ainsi généralement une mise à jour du BIOS.

3. Les composants à interroger

Lors du relevé des valeurs des registres, par Chipsec ou manuellement, les composants de la plateforme suivants seront sollicités :

  • le CPU : composant exécutant les instructions machine et donc le code provenant du système d’exploitation ou encore du BIOS ;
  • le PCH : Platform Controller Hub, aussi appelé chipset, combinant les anciennes puces North Bridge et South Bridge, son rôle est d’interfacer avec le CPU et d’autres périphériques ou contrôleurs avec des protocoles différents (PCI, SPI…) ;
  • la mémoire flash SPI : divisée en plusieurs régions, comme des partitions d’un disque, et contenant notamment le firmware BIOS ;
  • le contrôleur de la flash SPI : composant, intégré généralement dans le PCH, pour s’interfacer avec la mémoire flash SPI et le PCH ;
  • le contrôleur de la RAM : composant, intégré généralement dans le CPU, pour s’interfacer avec la mémoire RAM et d’autres périphériques ou contrôleurs.

configuration figure 01

Figure 1 : Représentation d’une plateforme Intel munie d’un PCH [1].

4. Moyens d’accès aux registres

4.1 Registres du CPU

Le processeur expose un certain nombre de registres de configuration internes, qui sont accessibles par plusieurs moyens :

  • via la réponse à l’instruction cpuid (qui énumère les diverses fonctionnalités exposées par le CPU, comme AES-NI ou encore le bit NX) à travers notamment les registres EAX, EBX, ECX et EDX ;
  • via des Model Specific Register (MSR), qui sont des registres spécifiques aux processeurs Intel.

Ces deux moyens sont détaillés dans le Intel 64 and IA-32 Architectures Software Developer’s Manual [2] (volume 1, chapitre 20 pour cpuid et volume 4 pour les MSR).

4.2 Accès via PCI

Pour les composants situés sur le bus PCI Express, les registres de configuration peuvent être situés dans l’espace de configuration PCI (PCI Configuration Space, présent sur tous les périphériques PCI) ou bien dans des espaces spécifiques exposés par le périphérique et découverts automatiquement lors de l’énumération du composant au démarrage de la machine.

configuration figure 02

Figure 2 : PCI Configuration Space [1].

L’accès au PCI Configuration Space sur une machine x86 peut se faire de deux façons. La première, plutôt obsolète, est spécifique à cette architecture et utilise la notion de Port Mapped I/O (PMIO), c’est-à-dire l’espace des ports x86. Sans entrer dans les détails, il s’agit d’un espace similaire à un espace mémoire, mais nettement plus limité (64Ko répartis en unités de 1 à 64 bits) et accessible au travers d’instructions x86 spécifiques (in et out typiquement).

Les périphériques PCI sont identifiés par un triplet Bus:Device.Function dans la hiérarchie PCI. Pour accéder à l’espace de configuration d’un périphérique en utilisant PMIO, le processeur utilise les deux ports 0xcf8 (Configuration space address) et 0xcfc (Configuration space data) de la façon suivante :

  1. le CPU écrit l’adresse (combinant Bus, Device, Function et l’offset du registre) dans 0xcf8 ;
  2. le CPU lit ou écrit le contenu du registre dans 0xcfc.

En pseudo-code, cela donne :

address = 0x80000000;
address |= bus << 16 | device << 11 | function << 8;
address |= offset;
outl(address, 0xcf8);
result = inl(0xcfc);

Ce mode d’accès a été progressivement remplacé avec l’avènement du PCI Express par un mode d’accès nommé Memory Mapped I/O (MMIO), où l’espace de configuration PCI Express (qui fait 4Ko et dont les 256 premiers octets sont communs avec l’espace de configuration PCI) est projeté dans l’espace mémoire du processeur : une zone mémoire est réservée pour les périphériques PCI et tous les accès mémoire à des adresses situées dans cette zone sont dirigés vers le bus PCI. L’adresse de base de cette zone est déterminée au démarrage par le BIOS et configurée dans un registre du chipset nommé PCI Express Register Range Base Address Register (PCIEXBAR). Les accès à l’espace de configuration PCI Express se font ensuite par des accès mémoires standards, là encore en incluant dans l’adresse l’identifiant du périphérique, selon le pseudo-code suivant :

address = *PCIEXBAR;
address |= bus << 20 | device << 15 | function << 12;
address |= offset
result = *address;

L’adresse mémoire est décodée par le chipset afin de générer une transaction PCI Express dirigée vers le bon périphérique.

Les périphériques PCI Express peuvent aussi exposer de la mémoire interne à destination du processeur, que ce soit pour des données (par exemple une carte réseau) ou de la configuration. Lors de l’énumération du périphérique (au démarrage ou lors de l’insertion à chaud), le BIOS ou le système d’exploitation vérifie au sein du PCI Configuration Space la présence de Base Address Registers (BAR) qui indiquent la présence de mémoire exposée par le périphérique.

Cette mémoire est là encore projetée dans l’espace mémoire du processeur et les accès à ces adresses sont dirigés vers le périphérique en question au lieu de la mémoire centrale.

4.3 Autres accès MMIO

Les accès MMIO ne sont pas spécifiques aux périphériques PCI, mais peuvent se rencontrer sur d’autres types de contrôleurs. Sur des architectures telles que ARM, chaque périphérique exposant de la mémoire (configuration ou espaces d’échange) est habituellement projeté dans l’espace mémoire du processeur, et tous les accès se font en MMIO. La répartition de l’espace d’adressage fait souvent partie des spécifications de la plateforme et est par exemple transmise au système d’exploitation via un mécanisme spécifique comme les device tree.

Sur une plateforme Intel, on peut par exemple accéder à la configuration du contrôleur flash SPI, dans une zone mémoire dont l’adresse est contrôlée par le registre SPIBAR, lui-même situé dans la configuration du chipset, accessible lui en PCI.

v-configuration figure 03

Figure 3 : Datasheet Intel : registres accessibles depuis SPIBAR en MMIO.

5. Extraction manuelle des informations sous Linux

Depuis un système Linux, il est tout à fait possible d’accéder aux différents registres de configuration des périphériques embarqués. Pour chaque type d’accès vus précédemment, il peut exister plusieurs méthodes, nécessitant plus ou moins de privilèges, qui seront détaillés.

5.1 Registres du CPU

5.1.1 CPUID

Comme évoqué précédemment, les informations propres au CPU peuvent être lues via l’instruction assembleur cpuid détaillée dans la documentation Intel de l’architecture x86 [2].

Sous Linux, il existe un module cpuid(4) (la notation (n) indique la section où se trouve la page de manuel correspondante) qui collecte les informations sur les CPU présents sur le système et les expose au travers d’une hiérarchie sous /dev/cpu/*/cpuid. Il existe aussi un utilitaire cpuid(1) pouvant utiliser au choix l’interface noyau ou bien, par défaut, l’instruction cpuid. Cet outil permet notamment une visualisation pratique des informations collectées.

configuration figure 04

Figure 4 : Configuration brute du CPU via cpuid.

La sémantique de l’instruction cpuid est assez simple : elle prend en entrée une valeur dans le registre EAX et renvoie les informations dans les registres EAX à EDX. Il existe une quinzaine de combinaisons renvoyant chacune une configuration spécifique du CPU. Par exemple, dans la capture précédente, la première ligne correspond à l’appel de cpuid avec EAX positionné à 0. Dans ce cas, le CPU renvoie dans EBX, EDX et ECX la chaîne ASCII correspondant au nom du fabricant du CPU, soit ici : GenuineIntel.

L’outil cpuid(1) interprète automatiquement les valeurs renvoyées pour qu’elles soient clairement compréhensibles (Figure 5).

configuration figure 05

Figure 5 : Configuration interprétée du CPU via cpuid.

5.1.2 MSR

Les Model Specific Registers sont, comme leur nom l’indique, des registres spécifiques à différents modèles de processeur Intel. Leur présence est habituellement signalée par une information dans cpuid. Ces registres sont accessibles en lecture et en écriture, à l’aide des instructions privilégiées rdmsr et wrmsr.

Sous Linux, il existe là encore un module noyau msr(4) qui expose une interface vers ces MSR dans la hiérarchie /dev/cpu/*/msr (accessible au super-utilisateur uniquement). De façon similaire à cpuid, il existe un projet nommé msr-tools qui fournit les utilitaires rdmsr(1) et wrmsr(1) qui permettent d’offrir une interface plus simple vers les fichiers exposés par le noyau.

5.2 Listing des périphériques PCI

Au démarrage du système, le noyau Linux identifie tous les périphériques PCI attachés aux bus PCI et stocke diverses informations dans un pseudo système de fichiers sous l’arborescence /sys/bus/pci/devices.

ls -la /sys/bus/pci/devices
total 0
drwxr-xr-x 2 root root 0 mars   9 09:29 .
drwxr-xr-x 5 root root 0 mars   9 09:29 ..
lrwxrwxrwx 1 root root 0 mars   9 09:29 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
lrwxrwxrwx 1 root root 0 mars   9 09:29 0000:00:02.0 -> ../../../devices/pci0000:00/0000:00:02.0
lrwxrwxrwx 1 root root 0 mars   9 09:29 0000:00:04.0 -> ../../../devices/pci0000:00/0000:00:04.0
Arborescence Linux de gestion du matériel PCI.

On y trouve diverses métadonnées (vendor et product id, classe du matériel, révision, etc.).

cat /sys/bus/pci/devices/0000:00:1f.0/{device,vendor,revision}
0x8c4c
0x8086
0x04
Stockage des DID, VID et RID du matériel PCI.

La suite d’outils pciutils se base sur ces informations. Le plus connu est sans doute lspci qui permet de lister les périphériques connus du système :

# lspci -n
00:00.0 0600: 8086:0c00 (rev 06)
00:02.0 0300: 8086:0412 (rev 06)
00:03.0 0403: 8086:0c0c (rev 06)
00:14.0 0c03: 8086:8c31 (rev 04)
00:19.0 0200: 8086:153a (rev 04)
00:1a.0 0c03: 8086:8c2d (rev 04)
00:1b.0 0403: 8086:8c20 (rev 04)
00:1c.0 0604: 8086:8c10 (rev d4)
00:1c.3 0604: 8086:8c16 (rev d4)
00:1d.0 0c03: 8086:8c26 (rev 04)
00:1f.0 0601: 8086:8c4c (rev 04)
00:1f.2 0106: 8086:8c02 (rev 04)
00:1f.3 0c05: 8086:8c22 (rev 04)
VID/DID des périphériques PCI précédés de leur adresse PCI.

lspci affiche les informations fournies par les périphériques eux-mêmes, mais aussi les informations topologiques, en particulier les identifiants du périphérique, sous la forme Bus:Device.Function.

# lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Controller (rev 06)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 Audio device: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (rev 06)
00:14.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB xHCI (rev 04)
00:19.0 Ethernet controller: Intel Corporation Ethernet Connection I217-LM (rev 04)
00:1a.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)
00:1b.0 Audio device: Intel Corporation 8 Series/C220 Series Chipset High Definition Audio Controller (rev 04)
00:1c.0 PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #1 (rev d4)
00:1c.3 PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #4 (rev d4)
00:1d.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q85 Express LPC Controller (rev 04)
00:1f.2 SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (rev 04)
00:1f.3 SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller (rev 04)
Noms des périphériques PCI (VID/DID convertis) précédés de leur adresse PCI.

À noter que la conversion automatique par la commande lspci du couple VID:DID se base sur le fichier /usr/share/hwdata/pci.ids (ou /usr/share/misc/pci.ids) fourni avec pciutils.

Ainsi, le PCH (dans ce cas 8086/Intel et 8c4c/Q85 Express LPC Controller) est identifié avec l’adresse PCI 00:1f.0 alors que le contrôleur DRAM est identifié avec l’adresse 00:00.0.

5.3 Extraction de registres de périphériques PCI

Extraire les valeurs de registre de configuration d’un périphérique PCI (par exemple, le chipset) nécessite d’identifier préalablement les adresses de ces derniers et donc de consulter la datasheet Intel de celui-ci.

configuration figure 07

Figure 6 : Datasheet Intel : données d’accès au registre BIOS_CNTL.

Ainsi, pour accéder au registre BIOS_CNTL (Bios Control Register) il est nécessaire de sélectionner le périphérique PCI correspondant au chipset et de se déplacer à l’offset 0xdc de l’espace de configuration PCI. La commande lspci avec les options -xxx permet d’afficher en hexadécimal l’espace de configuration PCI et donc d’en extraire les registres, tels que BIOS_CNTL qui a en l’occurrence la valeur 0xA2.

# lspci -xxx -s 00:1f.0
00:1f.0 ISA bridge: Intel Corporation Q85 Express LPC Controller (rev 04)
00: 86 80 4c 8c 07 01 10 02 04 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 3c 10 e7 18
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00
40: 01 04 00 00 80 00 00 00 01 05 00 00 11 00 00 00
50: f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 8b 80 85 8a 90 00 00 00 83 80 8b 8a f8 f0 00 00
70: 78 f0 78 f0 78 f0 78 f0 78 f0 78 f0 78 f0 78 f0
80: 10 00 09 14 01 0a fc 00 01 08 fc 00 00 00 00 00
90: 00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 00
a0: 38 5e a0 18 09 38 06 00 00 46 00 00 00 00 01 80
b0: 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 33 22 11 00 67 45 00 00 cf ff 00 00 2a 00 00 00
e0: 09 00 0c 10 00 00 00 00 01 00 c0 91 00 00 00 00
f0: 01 c0 d1 fe 00 00 00 00 b1 0f 06 08 00 00 00 00
Extraction des registres du PCH via « lspci ».
 
d0: 33 22 11 00 67 45 00 00 cf ff 00 00 2a 00 00 00
BIOS_CNTL, un des registres de PCH.

Il est aussi possible d’utiliser la commande setpci pour lire directement la valeur du registre correspondant :

# setpci -s 00:1f.0 0xdc.b
2a

Les deux outils (lspci et setpci) reposent sur la bibliothèque pcilib et peuvent utiliser plusieurs méthodes pour récupérer les informations, suivant le système sous-jacent :

  • linux-sysfs utilise les informations fournies par le noyau Linux (soit /sys/bus/pci/devices comme évoqué précédemment), qui est dans ce cas-là chargé de la collecte des informations auprès des périphériques eux-mêmes ;
  • intel-conf1 utilise les instructions assembleur in et out (accès PMIO).

Les deux méthodes nécessitent des privilèges root pour obtenir des informations complètes, mais sur des systèmes Linux récents (intégrant la fonctionnalité Lockdown) l’accès à l’espace des ports x86 est restreint pour des raisons de sécurité, ce qui empêche l’utilisation de la deuxième méthode.

La valeur du registre connue permet alors, depuis la datasheet, de connaître la valeur de chaque bit et donc des paramètres à vérifier (0x2A vaut 0b00101010) :

  • bit 0 : BIOS_WE = 0 ;
  • bit 1 : BLE = 1 ;
  • bit 5 : SMM_BWP = 1.

v-configuration figure 08 0

Figure 7 : Contenu du registre BIOS_CNTL.

Une lecture fine de la documentation et la compréhension de la sémantique des différents paramètres est enfin nécessaire pour vérifier si la configuration est correcte ou non.

5.4 Extraction des registres via des redirections multiples

Comme expliqué précédemment, les registres ne sont pas nécessairement dans l’espace de configuration PCI et peuvent être dans une zone mémoire exposée par le périphérique et projetée dans l’espace mémoire CPU. L’adresse de cette zone mémoire accessible alors en MMIO, est inscrite dans un registre PCI.

Ainsi, un accès PCI seul n’est pas suffisant pour lire les valeurs des registres et il est nécessaire de procéder à plusieurs redirections :

  • identifier, au sein du registre PCI, la zone mémoire (l’adresse en mémoire physique) BAR ;
  • accéder à la mémoire physique et extraire spécifiquement la zone mémoire BAR ;
  • identifier les registres au sein de la zone mémoire extraite et relever les valeurs souhaitées.

Un exemple de ce type d’accès, utilisant notamment l’espace mémoire SPIBAR, spécifique au contrôleur de la flash SPI, est fourni ci-dessous.

5.4.1 Identifier l’adresse mémoire SPIBAR

Si nous souhaitons relever la configuration des registres propres au contrôleur de la flash SPI, il est tout d’abord nécessaire de relever l’adresse mémoire physique RCRB (Root Complex Register Block) stockée au sein de l’espace de configuration PCI du chipset (dans le périphérique PCI 00:1f.0) et précisément dans le registre de 4 octets RCBA (Root Complex Base Address Register) situé à l’offset 0xF0. Les registres de configuration du PCH sont tous projetés à partir de cette adresse, d’où la nécessité de la relever. Le résultat de la commande lspci pour extraire l’espace de configuration PCI indique ainsi la valeur de RCRB (à lire en Little Indian) : FED1 C001.

f0: 01 c0 d1 fe 00 00 00 00 b1 0f 06 08 00 00 00 00
RCRB enregistrée dans le PCH.

Tel que cela est spécifié dans la datasheet du chipset, l’espace mémoire dédié aux registres du contrôleur SPI (nommé SPIBAR) débute à l’offset 0x3800 à partir de RCRB, à un offset fixe précisé dans la datasheet (0x3800).

v-configuration figure 09

Figure 8 : Datasheet Intel : identification de l’offset propre à SPIBAR et de sa taille.

Ainsi, l’adresse finale en mémoire de SPIBAR est : 0x3800+0xFED1C001-1 = 0xFED1F800. La taille de SPIBAR est également indiquée : 0x39FF-0x3800 = 0x1FF.

À noter qu’une alternative consiste à parcourir les plages d’adresses mémoire recensées par le noyau Linux via /proc/iomem et d’identifier celles attribuées au contrôleur SPI :

fed19000-fed19fff : pnp 00:0a
fed1c000-fed1ffff : Reserved
  fed1c000-fed1ffff : pnp 00:0a
    fed1f410-fed1f414 : iTCO_wdt.0.auto
    fed1f800-fed1f9ff : intel-spi
fed20000-fed3ffff : pnp 00:0a
Espace mémoire SPIBAR (noté « intel-spi »).

5.4.2 Extraire les valeurs des registres de SPIBAR via MMIO

Les espaces mémoire projetés en mémoire physique (dont celles de SPIBAR) sont accessibles sous Linux au travers du device /dev/mem. Une copie bit-à-bit permet de copier le contenu de l’espace SPIBAR.

# dd if=/dev/mem of=spibar skip=$((0xfed1f800)) count=$((0x1FF)) bs=1
511+0 records in
511+0 records out
511 bytes copied, 0.00850042 s, 60.1 kB/s
Copie de l’espace mémoire SPIBAR à travers /dev/mem.

Ainsi, à l’offset 0x04 se trouve le registre de 2 octets HSFS qui a dans le cas présent une valeur de 0xF008 (soit 1111 0000 0000 1000 en binaire).

# cat /proc/iomem
[…]
fed1c000-fed1ffff : Reserved
  fed1c000-fed1ffff : pnp 00:0a
    fed1f410-fed1f414 : iTCO_wdt.0.auto
    fed1f800-fed1f9ff : intel-spi
[…]
Espace mémoire SPIBAR et son registre HSFS

Il est alors nécessaire d’identifier, depuis la datasheet, les paramètres de configuration associés à chacun des bits du registre (8 variables sur 1 ou 2 bits), de les comprendre et de vérifier leur conformité.

# xxd spibar
00000000: 8005 ff0f 08f0 0000 6caf 5800 0000 0000 ........l.X.....
00000010: 2200 2200 0000 0000 0000 0000 0000 0000 ".".............
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................

Par exemple, FDOPSS étant le bit 13, sa valeur est donc 1 (1111 0000 0000 1000).

v-configuration figure 10

Figure 9 : Datasheet Intel : FDOPSS du registre HSFS.

À noter que sur des systèmes actuels l’accès à /dev/mem est en général filtré et il n’est pas possible d’accéder à la totalité de la mémoire physique ainsi.

5.5 Extraire le firmware BIOS

Les paramètres stockés dans les registres sont pour la plupart définis par le BIOS au démarrage de la machine. Il est donc important de s’assurer de la conformité de son code via son extraction depuis la flash SPI. Cette opération permettra à un analyste/auditeur de le comparer à une base de codes sains ou éventuellement de l’analyser pour identifier une malveillance, même si cette opération reste délicate.

Pour extraire le code du BIOS, une première méthode serait d’exploiter la mémoire physique. En effet, au démarrage de la plateforme, le code va être décompressé en mémoire pour être exécuté par le CPU et sera donc accessible. Les moyens existants pour effectuer un dump de la mémoire physique ne manquent pas (localement via /dev/mem ou un driver tel que fmem, ou avec des transferts DMA à l’aide d’outils tels que PCIe Screamer), mais au lancement du noyau Linux (et suite à l’exécution de la fonction UEFI ExitBootService()), une partie de l’espace occupé en mémoire par le firmware peut être libéré.

Une deuxième méthode plus fiable est d’utiliser le contrôleur SPI en programmant ses registres de contrôle pour accéder au contenu de la mémoire flash. Les registres FDATA0 et FDADDR (accès via SPIBAR + 0x08 et 0x10) permettent de lire bloc par bloc la flash SPI via les 15 registres FDATAN (accès via SPIBAR + 0x14 à 0x4C).

Ces méthodes logicielles ont toutefois des limites. En dehors de la nécessité d’avoir des privilèges élevés sur le système (super-utilisateur, voire accès noyau), certaines régions de la flash SPI ne sont de toute façon pas lisibles par le CPU (en particulier la région ME dédiée au Management Engine). Dans ce cas, la seule solution pour récupérer l’intégralité de la flash est de procéder à une extraction physique, par exemple avec un clip de type SOP8 couplé à un Raspberry Pi et un logiciel tel que flashrom pour piloter la flash.

Conclusion

Si nous établissons un bilan global de cette étude, il semble possible, et il est tentant de scripter l’extraction des registres de configuration. Si nous regardons plus en détail, plusieurs difficultés apparaissent :

  • le niveau de droits requis dépend de la plateforme ciblée et de son niveau de sécurité, des mécanismes de sécurité système pouvant bloquer l’utilisation de certains outils ou bloquer l’accès à certains périphériques ;
  • la présence des registres et leur moyen d’accès peuvent différer selon la plateforme ciblée et il est nécessaire de consulter les spécifications matérielles, qui évoluent dans le temps et sont globalement très complexes ;
  • chacune des valeurs des registres relevée doit faire l’objet d’une interprétation en consultant les spécifications ;
  • certaines opérations (comme l’extraction de flash SPI) nécessitent d’écrire du bas niveau pour interagir avec des registres MMIO avec plusieurs niveaux d’indirections, opération potentiellement délicate.

La réelle difficulté est donc de développer un outil compatible avec toutes les plateformes. Les analyses sont généralement menées sur des plateformes non maîtrisées et adapter l’outil à chaque vérification devient vite fastidieux. Chipsec, abordé dans l’article du dossier, apporte justement une solution à ces problématiques en mettant à disposition un outil multiplateforme, automatisé, fiable et très simple d’utilisation.

Références

[1] D. Salihun, « Architecture CPU/PCH » : https://resources.infosecinstitute.com/system-address-map-initialization-x86x64-architecture-part-2-pci-express-based-systems/

[2] Intel, « Intel® 64 and IA-32 Architectures Software Developer’s Manuals » : https://software.intel.com/en-us/articles/intel-sdm#combined



Article rédigé par

Par le(s) même(s) auteur(s)

Recherche d'indices de compromission sur iOS

Magazine
Marque
MISC
HS n°
Numéro
10
Mois de parution
octobre 2014
Spécialité(s)
Résumé

Cet article est une introduction à l’investigation numérique de terminaux Apple iOS. L'objectif est d’infirmer ou confirmer la compromission du terminal par un programme malveillant. Dans les différents exemples, nous partons du principe que le terminal à analyser est fourni volontairement par la victime et donc que l'éventuel mot de passe protégeant le terminal est connu. D’autre part, les thèmes relatifs à l’analyse des éléments de la chaîne de démarrage du terminal (BootRom, LLB, iBoot, etc.) ainsi que le code exécuté sur la puce radio (Baseband) ne seront pas abordés, leur complexité d’analyse nécessitant un article à eux seuls.

Fuite d’informations sous Mac OS X

Magazine
Marque
MISC
Numéro
65
Mois de parution
janvier 2013
Spécialité(s)
Résumé

À partir d'une analyse passive distante sans compte ou à partir d'un accès physique avec ou sans compte utilisateur, quelles informations critiques peuvent être extraites d'un système Mac OS X dans le cadre d'une attaque réelle ou d'une investigation numérique ?Cet article illustre, de manière crescendo, les différentes fuites d'informations accessibles pouvant être exploitées sur votre système.

Les derniers articles Premiums

Les derniers articles Premium

Cryptographie : débuter par la pratique grâce à picoCTF

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

L’apprentissage de la cryptographie n’est pas toujours évident lorsqu’on souhaite le faire par la pratique. Lorsque l’on débute, il existe cependant des challenges accessibles qui permettent de découvrir ce monde passionnant sans avoir de connaissances mathématiques approfondies en la matière. C’est le cas de picoCTF, qui propose une série d’épreuves en cryptographie avec une difficulté progressive et à destination des débutants !

Game & Watch : utilisons judicieusement la mémoire

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Au terme de l'article précédent [1] concernant la transformation de la console Nintendo Game & Watch en plateforme de développement, nous nous sommes heurtés à un problème : les 128 Ko de flash intégrés au microcontrôleur STM32 sont une ressource précieuse, car en quantité réduite. Mais heureusement pour nous, le STM32H7B0 dispose d'une mémoire vive de taille conséquente (~ 1,2 Mo) et se trouve être connecté à une flash externe QSPI offrant autant d'espace. Pour pouvoir développer des codes plus étoffés, nous devons apprendre à utiliser ces deux ressources.

Raspberry Pi Pico : PIO, DMA et mémoire flash

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Le microcontrôleur RP2040 équipant la Pico est une petite merveille et malgré l'absence de connectivité wifi ou Bluetooth, l'étendue des fonctionnalités intégrées reste très impressionnante. Nous avons abordé le sujet du sous-système PIO dans un précédent article [1], mais celui-ci n'était qu'une découverte de la fonctionnalité. Il est temps à présent de pousser plus loin nos expérimentations en mêlant plusieurs ressources à notre disposition : PIO, DMA et accès à la flash QSPI.

Les listes de lecture

11 article(s) - ajoutée le 01/07/2020
Clé de voûte d'une infrastructure Windows, Active Directory est l'une des cibles les plus appréciées des attaquants. Les articles regroupés dans cette liste vous permettront de découvrir l'état de la menace, les attaques et, bien sûr, les contre-mesures.
8 article(s) - ajoutée le 13/10/2020
Découvrez les méthodologies d'analyse de la sécurité des terminaux mobiles au travers d'exemples concrets sur Android et iOS.
10 article(s) - ajoutée le 13/10/2020
Vous retrouverez ici un ensemble d'articles sur les usages contemporains de la cryptographie (whitebox, courbes elliptiques, embarqué, post-quantique), qu'il s'agisse de rechercher des vulnérabilités ou simplement comprendre les fondamentaux du domaine.
Voir les 55 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous