Piratage d'ESP32 en contournant le démarrage sécurisé et le chiffrement Flash (CVE-2020-13629)

Nous avons mené une étude du microcontrÎleur Espressif ESP32 pour la résistance aux attaques réalisées par la méthode d'introduction de pannes dans le fonctionnement des puces (Fault Injection). Nous avons progressivement cherché à trouver des vulnérabilités qui nous permettront de contourner les mécanismes de démarrage sécurisé et de cryptage Flash avec une seule défaillance causée par un champ électromagnétique. De plus, aprÚs avoir mené à bien l'attaque, nous avons non seulement pu exécuter du code arbitraire, mais également reçu les données de la mémoire flash déchiffrées. Espressif a signalé cette vulnérabilité dans la base de données CVE sous le code CVE-2020-13629







... Lorsque vous examinez l'attaque décrite dans cet article, gardez à l'esprit qu'elle s'applique aux révisions 0 et 1 des puces ESP32. Les nouveaux ESP32 V3 prennent en charge la fonctionnalité de désactivation du chargeur de démarrage UART utilisée dans cette attaque.



Chargeur de démarrage UART



Dans ESP32, le chargeur de démarrage UART est implémenté dans le code ROM. Cela permet, entre autres, d'écrire des programmes sur une mémoire flash externe. L'implémentation du chargeur de démarrage UART en tant que code stocké dans la ROM est une solution courante. Il est assez fiable car un tel code n'est pas facilement endommagé. Si cette fonctionnalité était basée sur le code stocké dans la mémoire flash externe, alors tout dommage à une telle mémoire conduirait à une inopérabilité totale du microcontrÎleur.



Habituellement, l'accÚs à une telle fonctionnalité est organisé lorsque la puce est chargée dans un mode spécial, en mode démarrage. Le choix de ce mode s'effectue à l'aide de cavaliers de contact (ou cavaliers), définis avant le redémarrage de l'appareil. L'ESP32 utilise une broche pour cela G0.



Le chargeur de dĂ©marrage UART prend en charge de nombreuxinstructions qui peuvent ĂȘtre utilisĂ©es pour lire / Ă©crire de la mĂ©moire et des registres, et mĂȘme pour exĂ©cuter des programmes Ă  partir de SRAM.



▍ExĂ©cution de code arbitraire



Le chargeur UART prend en charge le chargement et l'exĂ©cution de code arbitraire Ă  l'aide de la commande load_ram. Le SDK ESP32 comprend tous les outils nĂ©cessaires pour compiler du code qui peut ĂȘtre exĂ©cutĂ© Ă  partir de SRAM. Par exemple, l'extrait de code suivant gĂ©nĂšre une chaĂźne SRAM CODE\nvers l'interface sĂ©rie.



void __attribute__((noreturn)) call_start_cpu0()
{
    ets_printf("SRAM CODE\n");
    while (1);
}


L'outil esptool.py, qui fait partie du SDK ESP32, peut ĂȘtre utilisĂ© pour charger des binaires compilĂ©s dans SRAM. Ensuite, ces fichiers peuvent ĂȘtre exĂ©cutĂ©s.



esptool.py --chip esp32 --no-stub --port COM3 load_ram code.bin


Fait intĂ©ressant, le chargeur de dĂ©marrage UART ne peut pas ĂȘtre dĂ©sactivĂ©. Par consĂ©quent, il y a toujours accĂšs, mĂȘme si le dĂ©marrage sĂ©curisĂ© et le cryptage flash sont activĂ©s.



▍ Mesures de sĂ©curitĂ© supplĂ©mentaires



Évidemment, Ă  moins que des mesures de sĂ©curitĂ© supplĂ©mentaires ne soient prises, la disponibilitĂ© constante du chargeur de dĂ©marrage UART rendra les mĂ©canismes de dĂ©marrage sĂ©curisĂ© et de cryptage de la mĂ©moire flash pratiquement inutiles. Par consĂ©quent, Espressif a mis en place des mĂ©canismes de sĂ©curitĂ© supplĂ©mentaires basĂ©s sur la technologie eFuse.



Ce sont les bits utilisés pour configurer les paramÚtres de sécurité, qui sont stockés dans une mémoire spéciale souvent appelée mémoire OTP (One-Time-Programmable Memory). Les bits d'une telle mémoire ne peuvent changer que de 0 à 1, mais pas dans la direction opposée. Cela garantit que si un bit d'activation d'une fonction a été défini, il ne sera plus jamais effacé. Lorsque l'ESP32 fonctionne en mode de chargeur de démarrage UART, les bits suivants de la mémoire OTP sont utilisés pour désactiver certaines fonctionnalités:



  • DISABLE_DL_ENCRYPT: -.
  • DISABLE_DL_DECRYPT: -.
  • DISABLE_DL_CACHE: MMU- -.


Nous sommes plus intéressés par le bit de mémoire OTP DISABLE_DL_DECRYPTcar il désactive le décryptage transparent des données stockées dans la mémoire flash.



Si ce bit n'est pas défini, lors du chargement du microcontrÎleur à l'aide du chargeur de démarrage UART, vous pouvez organiser un accÚs simple aux données stockées dans la mémoire flash, en les utilisant comme avec du texte ordinaire.



Si ce bit est dĂ©fini, alors, en mode de dĂ©marrage Ă  l'aide du chargeur de dĂ©marrage UART, seules les donnĂ©es chiffrĂ©es peuvent ĂȘtre lues Ă  partir de la mĂ©moire. La fonctionnalitĂ© de cryptage Flash, entiĂšrement implĂ©mentĂ©e dans le matĂ©riel et transparente pour le processeur, n'est activĂ©e que lorsque l'ESP32 dĂ©marre en mode normal.



Lors de l'attaque dont nous parlons ici, tous ces bits sont mis Ă  1.



Données SRAM persistantes aprÚs le redémarrage à chaud de l'appareil



La SRAM utilisĂ©e par le microcontrĂŽleur ESP32 est assez courante. La mĂȘme chose est utilisĂ©e par de nombreuses puces. Il est gĂ©nĂ©ralement utilisĂ© en conjonction avec la ROM et est responsable du dĂ©marrage du premier chargeur de dĂ©marrage Ă  partir de la mĂ©moire flash. Une telle mĂ©moire est pratique Ă  utiliser dans les premiĂšres Ă©tapes du chargement, car rien n'a besoin d'ĂȘtre configurĂ© avant de l'utiliser.



L'expérience des recherches précédentes nous indique que les données stockées dans la SRAM ne changent pas tant qu'elles ne sont pas écrasées, ou jusqu'à ce que plus d'électricité ne soit fournie aux cellules de mémoire. AprÚs un redémarrage à froid (c'est-à-dire un cycle de mise sous / hors tension) de la puce, le contenu de la SRAM sera réinitialisé à son état par défaut. Chaque puce d'une telle mémoire se distingue par un état unique (on pourrait dire semi-aléatoire) des bits mis aux valeurs 0 et 1.



Mais aprĂšs un redĂ©marrage Ă  chaud, lorsque la puce est redĂ©marrĂ©e sans couper l'alimentation, il peut arriver que les donnĂ©es stockĂ©es dans la SRAM restent les mĂȘmes. Ceci est illustrĂ© dans la figure suivante.





Impact des redémarrages à froid (ci-dessus) et à chaud (ci-dessous) sur le contenu SRAM



Nous avons dĂ©cidĂ© de savoir si ce qui prĂ©cĂšde est vrai pour l'ESP32. Nous avons constatĂ© que vous pouvez utiliser une minuterie de surveillance matĂ©rielle pour effectuer un dĂ©marrage Ă  chaud logiciel. Vous pouvez forcer ce minuteur Ă  se dĂ©clencher mĂȘme lorsque la puce est en mode de dĂ©marrage Ă  l'aide du chargeur de dĂ©marrage UART. En consĂ©quence, vous pouvez utiliser ce mĂ©canisme pour mettre l'ESP32 en mode de dĂ©marrage normal.



En utilisant le code de test, qui a été chargé dans la SRAM et exécuté à l'aide du chargeur de démarrage UART, nous avons déterminé que les données de la SRAM, en effet, persistent aprÚs une réinitialisation à chaud initiée par le minuteur de surveillance. Et cela signifie que nous, aprÚs avoir enregistré ce dont nous avons besoin dans SRAM, pouvons démarrer l'ESP32 comme d'habitude.



Ensuite, la question s'est posée de savoir comment nous pouvons utiliser cela.



La route de l'Ă©chec



Nous avons supposĂ© que nous pourrions ĂȘtre en mesure de tirer parti du fait que les donnĂ©es sont enregistrĂ©es dans la SRAM aprĂšs un redĂ©marrage Ă  chaud pour une attaque. Notre premiĂšre attaque a consistĂ© Ă  Ă©crire du code dans SRAM Ă  l'aide du chargeur de dĂ©marrage UART, puis, Ă  l'aide du minuteur de surveillance, nous avons effectuĂ© un redĂ©marrage Ă  chaud de l'appareil. Nous avons ensuite fait un plantage en l'exĂ©cutant car le code ROM Ă©crase ce code avec le code du chargeur de dĂ©marrage flash pendant le dĂ©marrage normal.



Nous avons eu cette idée aprÚs avoir transformé le processus de transfert de données en processus d'exécution de code au cours d' expériences précédentes . Ensuite, nous avons remarqué que la puce commence à exécuter le code à partir de l'adresse de démarrage avant que le chargeur de démarrage ne termine la copie.



Parfois, pour réaliser quelque chose, il suffit de l'essayer ...



▍Code chargĂ© dans SRAM et utilisĂ© pour mener l'attaque



Voici le code que nous avons écrit à SRAM à l'aide du chargeur de démarrage UART.



#define a "addi a6, a6, 1;"
#define t a a a a a a a a a a
#define h t t t t t t t t t t
#define d h h h h h h h h h h

void __attribute__((noreturn)) call_start_cpu0() {
    uint8_t cmd;

    ets_printf("SRAM CODE\n");

    while (1) {

        cmd = 0;
        uart_rx_one_char(&cmd);

        if(cmd == 'A') {                                    // 1
            *(unsigned int *)(0x3ff4808c) = 0x4001f880;
            *(unsigned int *)(0x3ff48090) = 0x00003a98;
            *(unsigned int *)(0x3ff4808c) = 0xc001f880;
        }
    }

    asm volatile ( d );                                     // 2

    "movi a6, 0x40; slli a6, a6, 24;"                       // 3
    "movi a7, 0x00; slli a7, a7, 16;"
    "xor a6, a6, a7;"
    "movi a7, 0x7c; slli a7, a7, 8;"
    "xor a6, a6, a7;"
    "movi a7, 0xf8;"
    "xor a6, a6, a7;"

    "movi a10, 0x52; callx8  a6;" // R
    "movi a10, 0x61; callx8  a6;" // a            
    "movi a10, 0x65; callx8  a6;" // e               
    "movi a10, 0x6C; callx8  a6;" // l               
    "movi a10, 0x69; callx8  a6;" // i               
    "movi a10, 0x7A; callx8  a6;" // z               
    "movi a10, 0x65; callx8  a6;" // e               
    "movi a10, 0x21; callx8  a6;" // !               
    "movi a10, 0x0a; callx8  a6;" // \n               

    while(1);
}


Ce code implémente ce qui suit (les numéros d'élément de liste correspondent aux numéros spécifiés dans les commentaires):



  1. Un gestionnaire de commande de commande unique qui réinitialise le minuteur de surveillance.
  2. Un analogue NOPbasé sur des instructions addi.
  3. Code d'assembly qui génÚre une chaßne vers l'interface série Raelize!.


▍Choisir le moment de l'attaque



Nous avions une fenĂȘtre d'attaque relativement petite Ă  notre disposition, en commençant par Fcomme indiquĂ© dans la figure suivante. Nous savions d'aprĂšs des expĂ©riences prĂ©cĂ©dentes que le code du chargeur de dĂ©marrage Ă©tait copiĂ© Ă  partir de la mĂ©moire flash Ă  ce stade.





La fenĂȘtre d'attaque est reprĂ©sentĂ©e par F Un



Ă©chec doit ĂȘtre effectuĂ© avant que le contenu de la SRAM ne soit complĂštement Ă©crasĂ© par le code du chargeur de dĂ©marrage correct de la mĂ©moire flash.



▍ Cycle d'attaque



Dans chacune de nos expériences, nous avons suivi les étapes suivantes pour vérifier que l'idée d'attaque fonctionnait. L'organisation réussie de l'échec aurait dû aboutir à la sortie vers l'interface de ligne série Raelize!.



  • DĂ©finissez la broche G0basse et effectuez un dĂ©marrage Ă  froid pour entrer en mode de chargeur de dĂ©marrage UART.
  • Utilisation d'une commande load_rampour exĂ©cuter un code d'attaque depuis SRAM.
  • Envoie le programme Aau redĂ©marrage Ă  chaud et au retour au mode de dĂ©marrage normal.
  • Organisation d'un Ă©chec dans le processus de copie du bootloader Ă  partir de la mĂ©moire flash Ă  l'aide du code de la ROM.


▍RĂ©sultats



AprÚs avoir effectué cette expérience pendant plus d'une journée, aprÚs l'avoir effectuée plus d'un million de fois, nous n'avons toujours pas réussi.



▍RĂ©sultat inattendu



Mais, malgré le fait que nous n'ayons pas réussi à réaliser ce que nous voulions, nous, en analysant les résultats des expériences, avons trouvé quelque chose d'inattendu.



Dans une expérience, l'interface série a rapporté des données indiquant qu'un échec a entraßné une exception IllegalInstruction(instruction invalide). Voici à quoi cela ressemblait:



ets Jun  8 2016 00:22:57
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0008,len:4
load:0x3fff000c,len:3220
load:0x40078000,len:4816
load:0x40080400,len:18640
entry 0x40080740
Fatal exception (0): IllegalInstruction
epc1=0x661b661b, epc2=0x00000000, epc3=0x00000000, 
excvaddr=0x00000000, depc=0x00000000


Lorsque vous essayez de provoquer une panne de puce, ces exceptions se produisent assez souvent. Il en va de mĂȘme pour l'ESP32. Pour la plupart de ces exceptions, le registre est PCdĂ©fini sur la valeur attendue (c'est-Ă -dire que l'adresse correcte s'y trouve). Il arrive rarement qu'une PCsignification aussi intĂ©ressante apparaisse.



L'exception est IllegalInstructionlevĂ©e car 0x661b661bil n'y a pas d'instruction correcte Ă  l'adresse . Nous avons dĂ©cidĂ© que cette valeur PCdevait provenir de quelque part dans le registre , et que d'elle-mĂȘme elle ne pouvait pas y figurer.



À la recherche d'une explication, nous avons analysĂ© le code que nous avons chargĂ© dans la SRAM. La visualisation du code binaire, dont un extrait est prĂ©sentĂ© ci-dessous, nous a permis de trouver rapidement la rĂ©ponse Ă  notre question. À savoir, il est facile de trouver le sens ici0x661b661b... Il est reprĂ©sentĂ© par deux instructions addi a6, a6, 1, Ă  l'aide desquelles l'analogue est implĂ©mentĂ© dans le code NOP.



00000000  e9 02 02 10 28 04 08 40  ee 00 00 00 00 00 00 00  |....(..@........|
00000010  00 00 00 00 00 00 00 01  00 00 ff 3f 0c 00 00 00  |...........?....|
00000020  53 52 41 4d 20 43 4f 44  45 0a 00 00 00 04 08 40  |SRAM CODE......@|
00000030  50 09 00 00 00 00 ff 3f  04 04 fe 3f 4d 04 08 40  |P......?...?M..@|
00000040  00 04 fe 3f 8c 80 f4 3f  90 80 f4 3f 98 3a 00 00  |...?...?...?.:..|
00000050  80 f8 01 c0 54 7d 00 40  d0 92 00 40 36 61 00 a1  |....T}.@...@6a..|
00000060  f5 ff 81 fc ff e0 08 00  0c 08 82 41 00 ad 01 81  |...........A....|
00000070  fa ff e0 08 00 82 01 00  4c 19 97 98 1f 81 ef ff  |........L.......|
00000080  91 ee ff 89 09 91 ee ff  89 09 91 f0 ff 81 ee ff  |................|
00000090  99 08 91 ef ff 81 eb ff  99 08 86 f2 ff 5c a9 97  |.............\..|
000000a0  98 c5 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 3e 0c  |...f.f.f.f.f.f>.|
000000b0  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
000000c0  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
000000d0  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
...
00000330  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
00000340  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
00000350  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|


Nous avons prĂ©parĂ© une «marge de manƓuvre» avec ces instructions, en les utilisant de la mĂȘme maniĂšre que les sĂ©quences de commandes NOPsont souvent utilisĂ©es dans les exploits pour retarder l'exĂ©cution du code jusqu'Ă  ce qu'elle soit nĂ©cessaire. Nous ne nous attendions pas Ă  ce que ces instructions se retrouvent dans le registre PC.



Mais, bien sĂ»r, nous n’étions pas contre l’utilisation de cela. Nous avons dĂ©cidĂ© que nous pourrions charger des donnĂ©es de la SRAM dans un registre PClors d'un crash causĂ© par la copie des donnĂ©es de la mĂ©moire flash au moyen du code ROM.



Nous nous sommes rapidement rendu compte que nous disposions désormais de tous les ingrédients pour préparer une attaque qui contournerait les systÚmes de démarrage sécurisé et de cryptage flash en un seul problÚme. Ici, nous avons utilisé l'expérience acquise lors de l'exécution de l' attaque précédemment décritequand nous avons réussi à prendre le contrÎle du registre PC.



Chemin vers le succĂšs



Dans cette attaque, nous avons utilisé la plupart du code précédemment chargé dans SRAM à l'aide du chargeur de démarrage UART. Seules les commandes de sortie de caractÚres vers l'interface série ont été supprimées de ce code, puisque maintenant notre objectif était de définir le registre PCsur la valeur dont nous avions besoin, c'est-à-dire d'avoir la possibilité de contrÎler le systÚme.



#define a "addi a6, a6, 1;"
#define t a a a a a a a a a a
#define h t t t t t t t t t t
#define d h h h h h h h h h h

void __attribute__((noreturn)) call_start_cpu0() {
    uint8_t cmd;
   
    ets_printf("SRAM CODE\n");

    while (1) {

        cmd = 0;
        uart_rx_one_char(&cmd);

        if(cmd == 'A') {
            *(unsigned int *)(0x3ff4808c) = 0x4001f880;
            *(unsigned int *)(0x3ff48090) = 0x00003a98;
            *(unsigned int *)(0x3ff4808c) = 0xc001f880;
        }
    }

    asm volatile ( d );

    while(1);
}


AprĂšs avoir compilĂ© ce code, nous avons, directement dans sa version binaire, remplacĂ© les instructions addipar une adresse 0x4005a980. À cette adresse se trouve une fonction de la ROM qui envoie des donnĂ©es Ă  l'interface sĂ©rie. Un appel rĂ©ussi Ă  cette fonction nous avertirait d'une attaque rĂ©ussie.



Nous nous sommes préparés à gérer des échecs cohérents avec ce qui a provoqué l'exception lors d'une expérience précédente IllegalInstruction. AprÚs un certain temps, nous avons découvert la réussite de plusieurs expériences pour charger l' PCadresse donnée dans le registre . Le contrÎle de cas PCsignifie trÚs probablement que nous pouvons exécuter du code arbitraire.



▍ Pourquoi est-ce possible?



Le titre de cette section contient une bonne question à laquelle il n'est pas facile de répondre.



Malheureusement, nous n'avons pas de réponse claire. Nous ne nous attendions certainement pas à ce que la manipulation des données permette le contrÎle des registres PC. Nous avons plusieurs explications à cela, mais nous ne pouvons pas affirmer avec une certitude absolue que l'une d'entre elles est vraie.



Une explication est que lors d'un Ă©chec, les deux opĂ©randes de l'instruction ldrutilisĂ©s pour charger la valeur dans a0. Ceci est similaire Ă  ce que nous avons vu dans cette attaque, oĂč nous avons obtenu un contrĂŽle indirect sur le registre PCen modifiant les donnĂ©es.



De plus, il est possible que le code stocké dans la ROM implémente des fonctionnalités qui contribuent au succÚs de cette attaque. En d'autres termes, en raison d'un échec, nous pouvons exécuter le code correct à partir de la ROM, ce qui conduit au fait que les données de la SRAM sont chargées dans le registre PC.



Afin de savoir ce qui nous a permis de réaliser cette attaque, nous devons faire plus de recherches. Mais si vous regardez la question à travers les yeux de quelqu'un qui a décidé de pirater la puce, nous avons suffisamment de connaissances pour créer un exploit basé sur la possibilité d'influencer le registre PC.



Extraire le contenu de la mémoire flash sous forme de texte brut



Nous pouvons écrire dans le registre PCce que nous voulons, mais nous ne pouvons pas encore récupérer le contenu de la mémoire flash sous forme de texte brut. Par conséquent, il a été décidé de tirer parti des capacités du chargeur de démarrage UART.



À savoir, nous avons dĂ©cidĂ© d'aller directement au chargeur de dĂ©marrage UART pendant que la puce est en mode de dĂ©marrage normal. Pour mener Ă  bien cette attaque, nous avons rĂ©Ă©crit les instructions addidans le code chargĂ© dans la RAM, en utilisant Ă  la place l'adresse de dĂ©marrage du code du chargeur de dĂ©marrage UART ( 0x40007a19).



Le chargeur de démarrage UART envoie la ligne indiquée ci-dessous à l'interface série. Nous pouvons utiliser ce fait pour déterminer le succÚs d'une attaque.



waiting for download\n"


Une fois qu'une telle expérience est réussie, nous pouvons simplement l'utiliser esptool.pypour exécuter la commande read_memet accéder aux données en texte brut dans la mémoire flash. Par exemple, la commande suivante lit 4 octets à partir de l'espace d'adressage flash externe ( 0x3f400000).



esptool.py --no-stub --before no_reset --after no_reset read_mem 0x3f400000


Malheureusement, une telle commande n'a pas fonctionné. Pour une raison quelconque, la réponse du processeur ressemblait à celle-ci 0xbad00bad, indiquant que nous essayons de lire des données à partir de la mémoire non allouée.



esptool.py v2.8
Serial port COM8
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Crystal is 40MHz
MAC: 24:6f:28:24:75:08
Enabling default SPI flash mode...
0x3f400000 = 0xbad00bad
Staying in bootloader.


Nous avons remarqué que de nombreux paramÚtres sont définis au début du chargeur de démarrage UART. Nous avons supposé que ces paramÚtres pouvaient également affecter la MMU.



Juste pour essayer autre chose, nous avons dĂ©cidĂ© d'aller directement au gestionnaire de commandes du chargeur de dĂ©marrage UART ( 0x40007a4e) lui-mĂȘme . Une fois que nous nous trouvons dans le gestionnaire, nous pouvons indĂ©pendamment envoyer la commande read_memdirectement Ă  l'interface sĂ©rie:



target.write(b'\xc0\x00\x0a\x04\x00\x00\x00\x00\x00\x00\x00\x40\x3f\xc0')


Malheureusement, si vous accĂ©dez directement au gestionnaire, la ligne qui s'affiche aprĂšs ĂȘtre entrĂ© dans le chargeur de dĂ©marrage UART (c'est-Ă -dire - waiting for download\n) ne sera pas affichĂ©e. Pour cette raison, nous perdons un moyen simple et pratique d'identifier les expĂ©riences rĂ©ussies. En consĂ©quence, nous avons dĂ©cidĂ© d'envoyer la commande ci-dessus dans toutes les expĂ©riences, qu'elles aient rĂ©ussi ou non. Nous avons utilisĂ© un timeout sĂ©rie trĂšs court afin de minimiser le timeout supplĂ©mentaire associĂ© Ă  ce timeout, ce qui est presque toujours le cas.



Au bout d'un moment, nous avons vu les résultats des premiÚres expériences réussies!



RĂ©sultat



Dans cet article, nous avons décrit une attaque sur ESP32, dans laquelle nous contournons les systÚmes de démarrage sécurisé et de cryptage de la mémoire flash, en organisant une seule panne dans le microcontrÎleur. De plus, nous avons utilisé une vulnérabilité exploitée lors de l'attaque pour extraire le contenu de la mémoire flash chiffrée en texte brut.



Nous pouvons utiliser FIRM pour traverser cette attaque .





Progression de l'attaque



Voici une brÚve description de ce qui se passe dans les différentes étapes de l'attaque ci-dessus:



  1. Activer (le choix des outils pour mener une attaque) - ici le complexe Riscure Inspector FI est utilisé .
  2. Injecter (attaque) - un effet électromagnétique est effectué sur le microcontrÎleur étudié.
  3. Glitch ( ) — , (, , ).
  4. Fault ( ) — , , , . , - .
  5. Exploit ( ) — UART , SRAM, . UART PC read_mem.
  6. Goal ( ) — - .


Fait intĂ©ressant, le succĂšs de cette attaque dĂ©pend de deux faiblesses de l'ESP32. La premiĂšre faiblesse est que le chargeur de dĂ©marrage UART ne peut pas ĂȘtre dĂ©sactivĂ©. En consĂ©quence, il est toujours disponible. La deuxiĂšme faiblesse est la persistance des donnĂ©es dans la SRAM aprĂšs une rĂ©initialisation Ă  chaud de l'appareil. Cela permet d'utiliser le chargeur de dĂ©marrage UART pour remplir la SRAM avec des donnĂ©es arbitraires.



Dans un rapport d' information , qui fait référence à l'attaque, la société Espressif rapporte que les versions plus récentes ESP32 existent des mécanismes qui rendent une telle attaque impossible.



Tous les systÚmes intégrés standard sont vulnérables aux attaques par interruption de service. Par conséquent, il n'est pas surprenant que le microcontrÎleur ESP32 soit également vulnérable aux attaques de canaux secondaires. Les puces comme celles-ci ne sont tout simplement pas conçues pour résister à de telles attaques. Mais surtout, cela ne signifie pas que de telles attaques ne comportent aucun risque.



Nos recherches ont montrĂ© que l'exploitation des faiblesses de la puce permet des attaques et des perturbations rĂ©ussies. La plupart des attaques qui peuvent ĂȘtre apprises Ă  partir de sources ouvertes utilisent des approches traditionnelles, oĂč l'objectif principal est de contourner les contrĂŽles. Nous n'avons pas vu beaucoup de rapports d'attaques comme celle que nous avons dĂ©crite.



Nous sommes convaincus que le plein potentiel de ces attaques n’est pas encore pleinement explorĂ©. Jusqu'Ă  rĂ©cemment, la plupart des chercheurs Ă©tudiaient uniquement des mĂ©thodes pour perturber le fonctionnement des puces (Ă©tapes Activer, Injecter, Glitch), mais nous sommes allĂ©s plus loin, en envisageant la possibilitĂ© de travailler avec une puce vulnĂ©rable aprĂšs une panne (Ă©tapes Fault, Exploit, Goal).





Recherche jusqu'en 2020 et au-delĂ  de 2020



Nous sommes convaincus que l'utilisation créative de nouveaux modÚles de panne de puce conduira à une augmentation des méthodes d'attaque qui utilisent des stratégies d'exploitation de vulnérabilité intéressantes pour atteindre une grande variété d'objectifs.



Si vous ĂȘtes intĂ©ressĂ© par le sujet soulevĂ© dans ce matĂ©riel, alors ici , ici et ici - d'autres matĂ©riaux consacrĂ©s Ă  l'Ă©tude d'ESP32.



Avez-vous rencontré en pratique le piratage d'appareils en utilisant des méthodes similaires à celles décrites dans cet article?










All Articles