David Madore's WebLog: Le problème des gadgets électroniques qu'on peut bricker (briquer ? pétrifier ?)

Index of all entries / Index de toutes les entréesXML (RSS 1.0) • Recent comments / Commentaires récents

Entry #2396 [older|newer] / Entrée #2396 [précédente|suivante]:

(jeudi)

Le problème des gadgets électroniques qu'on peut bricker (briquer ? pétrifier ?)

Il faut d'abord que je commente le mot bricker dans le titre de cette entrée. C'est un anglicisme (l'anglais est to brick, c'est-à-dire que le nom commun brick a été sauvagement verbé), mais je ne crois pas qu'il existe de mot français : on peut écrire bricker en important le mot anglais, ou bien briquer en reproduisant la même construction qu'en anglais (ce verbe existe déjà en français avec un sens différent — frotter pour faire briller — mais je ne trouve pas que la confusion soit problématique, et à la limite ça peut marcher de façon humoristique). Quelqu'un m'a proposé pétrifier, ce qui est effectivement astucieux pour rendre le sens de ce dont je veux parler ici, et du coup je vais l'utiliser dans la suite.

De quoi s'agit-il ? Je définirais ce mot de la manière suivante : rentre, généralement par accident, un appareil électronique inutilisable (aussi utile qu'une brique, donc), en abîmant non pas le matériel lui-même, mais le logiciel qui sert à démarrer.

Expliquons un peu, pour ceux qui ont besoin de plus de précisions. De nos jours, énormément de gadgets électroniques (en gros, tout ce qui est plus complexe qu'une télécommande) sont, en fait, de petits ordinateurs dédiés, dits aussi « embarqué ». Autrefois, un téléviseur (par exemple), c'était de l'électronique spécialisée, maintenant c'est un ordinateur embarqué qui sait décoder la TNT et parle à l'écran LCD ; il en va de même, par exemple, des voitures (et d'ailleurs ça me fait très peur vu le niveau général catastrophique de la sécurité informatique et vu que les constructeurs n'auront aucune obligation à maintenir ad vitam æternam le logiciel). Énormément d'entre ces gadgets, soit dit en passant, tournent sous Linux (tous les téléphones ou tablettes Android, bien sûr, mais aussi les MachinBox qui servent de modem-routeur ADSL ou fibre, et je soupçonne, beaucoup de télévisions, de magnétoscopes, etc.), vu que Linux est très commode pour avoir rapidement un système standardisé sur un matériel à peu près quelconque. Je pense que Madame Michu serait très étonnée de savoir combien de systèmes Linux elle a chez elle.

Certains appareils (montres, frigos, fours, machines à laver) sont encore dans une phase où coexistent plusieurs versions sur le marché : purement électroniques, les véritables ordinateurs embarqués, et quelque chose d'intermédiaire comme un microcontrôleur. Mais avec l'Internet of Things (également appelé, la catastrophe de sécurité informatique qui va nous fondre dessus), les frigos, fours et machines à laver seront aussi de plus en plus souvent de véritables ordinateurs, capables de parler au réseau (et de se faire attaquer par lui). Ironiquement, maintenant, même les périphérique des ordinateurs sont souvent des ordinateurs eux-mêmes : les disques durs modernes, par exemple, ont un véritable ordinateur à l'intérieur (typiquement un processeur ARM), pour pouvoir mener toutes les choses complexes qu'un disque dur est censé faire (positionner les tête, contrôler les sommes de contrôle sur les données lues, analyser sa propre santé et la rapporter à l'ordinateur hôte, etc.).

L'avantage des ordinateurs par rapport à l'électronique pure (par électronique, je veux dire qu'il n'y a pas de puce généraliste, microprocesseur ou microcontrôleur, même si évidemment les frontières ne sont pas parfaitement bien définies), c'est qu'ils permettent de faire des choses beaucoup plus complexes de façon plus simple, et globalement ils sont plus flexibles. L'inconvénient, le pendant du généralisme, c'est qu'un microprocesseur seul ne sait rien faire : il lui faut un logiciel, un programme, également appelé du « code », pour faire quoi que ce soit, et notamment quoi que ce soit d'utile. Dans le cadre d'un ordinateur embarqué ou de périphériques d'un ordinateur, ce logiciel s'appelle souvent firmware (intermédiaire entre hardware, le matériel, et software, le logiciel sous-entendu de plus haut niveau).

On peut imaginer que ce firmware soit fixé une fois pour toutes : stocké en ROM (mémoire en lecture seule), gravé dans le marbre pour toute la vie de l'appareil. On se rapproche de l'électronique (une fois que l'électronique est câblée, plus moyen de changer). Mais cela signifie qu'en cas de problème, il sera impossible de corriger le bug ou le trou de sécurité. Du coup, ces appareils prévoient souvent un moyen de mettre à jour leur firmware : on utilise souvent le terme de flasher le firmware, parce qu'il est typiquement contenu dans une mémoire persistante appelée mémoire flash. Et c'est là que les ennuis commencent : parce que la mise à jour du firmware est à la fois une réponse à toutes sortes de problèmes (comme des trous de sécurité) et la cause de toutes sortes de problèmes (comme des trous de sécurité ! car si un attaquant modifie le firmware, il prend durablement contrôle de l'appareil, c'est plus grave que si le firmware n'était pas modifiable).

La modification du firmware est elle-même une opération qui nécessite l'éxcution de code, ce faisant partie du firmware, et c'est là qu'on comprend que les ennuis commencent vraiment. Parce que si l'opération échoue pour une raison ou une autre (bug, fausse manip', coupure de courant au mauvais moment) et qu'on se retrouve avec du firmware qui ne marche plus, on n'a plus de moyen de remettre en état le firmware : on se retrouve avec une brique : l'appareil ne marche plus, faute de firmware, et il n'y a pas de moyen, ou en tout cas pas de moyen simple, de remettre le firmware en état.

On peut bien sûr imaginer toutes sortes de façons de régler quand même le problème, et de rendre une machine impossible à pétrifier. Discutons un peu ces différentes approches.

La façon la plus évidente, comme je l'ai dit, c'est que le firmware ne soit pas du tout modifiable. Sur certains appareils (mais ce n'est pas courant), il faut actionner un interrupteur mécanique, ou décaler un jumper, ou quelque chose comme ça, avant de pouvoir flasher le firmware (si on ne le fait pas, la mémoire n'est pas modifiable) : ceci évite au moins les modifications malencontreuses dues à un bug ou une attaque, mais ça n'empêche pas qu'on puisse pétrifier la machine en cas de problème lors d'une mise à jour légitime (l'interrupteur étant donc actionné). Une autre solution consiste à avoir deux versions du firmware sur l'appareil, l'une dans une mémoire flash qu'on peut mettre à jour, l'autre dans une ROM inaltérable (en fait, probablement, une mémoire flash dont les pattes servant à réécrire le contenu n'ont pas été câblées) : un petit interrupteur permet de choisir — au niveau purement électronique — la version utilisée, on choisira normalement la première, mais en cas de problème on pourra démarrer sur la seconde, qui est capable de reflasher la première. Ceci permet bien d'avoir un appareil « impétrifiable » dont le firmware peut cependant être mis à jour. Astucieux. Je crois que ma carte mère a quelque chose du genre (un firmware/BIOS alternatif, non modifiable, du moins j'espère, accessible en appuyant sur un bouton, et qui est simplement capable d'aller lire un fichier sur une clé USB qui doit être branchée sur un port précis, et de reflasher le firmware/BIOS principal avec son contenu), mais les explications du manuel ne sont pas un modèle de clarté donc je ne suis pas sûr.

On peut imaginer d'autres moyens de rendre un appareil impétrifiable. Par exemple, si le firmware est flashable depuis un autre ordinateur, on pourra ranimer la brique tant qu'on dispose d'un ordinateur fonctionnel. Une idée serait d'avoir un firmware contenu dans une simple clé USB : pour le flasher, il suffirait de mettre un fichier différent sur cette clé USB. Malheureusement, la simple opération de lire une clé USB nécessite elle-même du code, donc un firmware, et on a un problème de bootstrap si on veut mettre le firmware sur clé USB (bootstrap fait référence à un épisode où le baron de Münchhausen se sort de l'eau en tirant sur les languettes de ses bottes). Mais on peut contourner ce problème de différentes façons. Par exemple, avoir un firmware zéro qui sait simplement lire un firmware sur clé USB, puis l'exécuter et décider que ce firmware zéro sera gravé en ROM donc impossible à modifier (c'est une solution raisonnable, et elle se rapproche de ce que je raconte ci-dessus à propos de ma carte mère). À défaut de clé USB, le firmware peut être contenu dans une puce détachable et on peut vendre un gadget (USB par exemple) permettant d'en modifier le contenu depuis un autre ordinateur. Ou encore, il peut y avoir un tel gadget intégré dans l'appareil lui-même : si on branche une connexion USB et qu'on allume l'appareil d'une certaine manière (peut-être en appuyant sur un bouton), on pourra flasher le firmware depuis un autre ordinateur, par pure électronique.

Les petits systèmes embarqués que j'utilise comme routeurs chez moi et chez mes parents, des DreamPlugs (ce sont des ordinateurs ARM), ont une petite mémoire flash (NOR) de 2Mo qui suffit à stocker un code de démarrage (bootloader, en l'occurrence U-Boot) capable de charger autre chose par Ethernet, USB ou eSATA, en ce qui me concerne un noyau Linux. On peut reflasher la mémoire NOR en passant par Linux ou depuis le bootloader U-Boot lui-même ; mais si l'opération échoue pour une raison ou une autre et que le DreamPlug est pétrifié ? Alors il faut utiliser une autre approche, qui consiste à prendre le contrôle du processeur et de la mémoire du DreamPlug depuis un autre ordinateur, en passant par une interface JTAG côté DreamPlug (et reliée de l'autre côté à un petit boîtier lui-même relié par USB à l'ordinateur qui contrôle) : de cette manière, on peut utiliser le programme OpenOCD pour mettre un U-Boot frais quelque part dans la mémoire du DreamPlug, démarrer dessus, et s'en servir pour reflasher la mémoire NOR. En théorie, c'est très bien. En pratique, il y a quantité de problèmes : la connexion JTAG n'est pas très stable, parfois elle ne marche pas du tout, parfois il faut réessayer plusieurs fois avant qu'elle marche ; en plus, OpenOCD version ≥0.8.0 ne fonctionne plus avec mon boîtier de contrôle JTAG, bref, ce n'est pas la joie. Mais au moins sur le principe, mes DreamPlugs sont « impétrifiables ». On ne peut pas en dire autant de la plupart des téléphones mobiles.

Beaucoup de fabricants de gadgets électroniques ont essayé l'approche suivante, qui ne sert pas seulement à éviter que le gadget soit pétrifié, mais aussi à ce que le le fabricant garde un contrôle sur le code qui tourne dessus : avant que le firmware accepte de flasher un nouveau firmware, il vérifie que celui-ci est acceptable, généralement au sens où il a été signé (par une signature électronique) par le fabricant. Malheureusement, cette approche est condamnée à l'échec pour toutes sortes de raisons, elle n'empêche pas la pétrification et elle pose toutes sortes de problèmes, ce qui n'empêche pas les fabricants de l'aimer. Une raison pour laquelle cette approche n'empêche pas la pétrification, c'est qu'il n'y a rien de magique dans le firmware de démarrage : s'il est capable de flasher la mémoire persistante, un autre bout de code en est aussi capable, donc dès que l'appareil présente un trou de sécurité quelque part (i.e., toujours), l'attaquant risque de pouvoir s'en servir pour reflasher le firmware, et l'approche choisie rend alors quasiment impossible de remettre les choses en état. (The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at or repair. — Douglas Adams, Mostly Harmless) Une autre raison qui fait que l'approche ne marche pas, c'est que la crypto est souvent mauvaise, par exemple au lieu d'utiliser une signature à clé publique, ce qui est possiblement lourd sur un appareil embarqué, on va parfois utiliser un MAC, dont la clé (symétrique) est alors forcément contenue dans le firmware, et qui va donc forcément fuiter. Encore une autre raison est qu'il y a un intervalle de temps entre le moment où le firmware vérifie la signature et le moment où il se reflashe, et il est parfois possible d'exploiter astucieusement cet intervalle pour changer le contenu sous ses pieds (on lui fait croire que la signature est bonne en vérifiant un « bon » nouveau firmware, mais au moment où il flashe la mémoire, c'est autre chose qui se présente). Toutes ces attaques sont menées soit par des attaquants malicieux qui veulent prendre le contrôle de l'appareil à l'insu de son propriétaire, soit par les propriétaires eux-mêmes qui veulent prendre le contrôle de leur propre gadget dont le fabricant essaie de limiter l'usage. Dans les deux cas, la pétrification est un résultat accidentel, mais qui se produit néanmoins dans une certaine proportion des cas.

Pourquoi les fabricants ont-ils si souvent recours à la méthode « vérification du firmware avant de le flasher » (dont je viens de parler) si elle ne marche pas vraiment ? Parce que cette méthode leur garantit — dans la mesure où elle marche, tant qu'elle marche — un certain contrôle sur l'appareil, à l'encontre de son propriétaire/utilisateur. On pourra l'empêcher d'utiliser cet appareil pour autre chose que ce pour quoi il a été prévu, et ce peut être le départ d'une chaîne de sécurité qui interdit certaines choses à l'utilisateur (qui, même s'il est censé être propriétaire de l'appareil, ne l'est alors jamais vraiment), par exemple de copier certaines données dans un sens ou dans l'autre. A contrario, certains des dispositifs qui empêchent la pétrification empêchent le fabricant de se réserver ce contrôle sur l'appareil.

Toujours est-il qu'il existe bien des moyens pour rendre un appareil impétrifiable. Je trouve que cela devrait être une obligation du fabricant de s'assurer qu'un de ces moyens existe (par exemple : si l'appareil est pétrifié, le fabricant aurait l'obligation légale de le rembourser au prix du neuf — une telle mesure augmenterait énormément la motivation à mettre en place des moyens pour éviter cet écueil). Un autre problème est qu'il n'est pas toujours évident de savoir ce qu'il en est, avant d'acheter l'appareil, ou même une fois qu'on l'a. Est-ce que mon téléphone Nexus 5 est pétrifiable, par exemple ? Je ne sais pas vraiment, je pense que oui, mais je n'ai pas franchement envie d'essayer pour vérifier ma sécurité de ce point de vue-là.

Je raconte tout ça parce que j'ai récemment mis à jour le noyau sur mes routeurs DreamPlugs (j'étais coincé depuis une éternité sur la branche 3.2.x du noyau Linux, avec toute une série de patchs, et pour la quitter j'ai dû mettre à jour U-Boot pour pouvoir passer au noyau un device tree, et avant de faire tout ça j'ai dû réapprendre la manière de réparer les choses en cas de pétrification accidentelle — dont je ne pouvais pas négliger les risques, même si au final tout s'est bien passé ; ceux qui veulent en savoir plus peuvent consulter cette page, récemment mise à jour, où je raconte les détails). J'envisage d'acheter d'autres gadgets pour remplacer ces DreamPlugs, par exemple ce truc-là, et une des choses que je cherche systématiquement à savoir c'est qu'elle garantie d'impétrificabilité(?) j'aurai (sur le produit précis que je viens de mentionner, il semble que ce soit bon, mais c'est rarement parfaitement clair).

↑Entry #2396 [older|newer] / ↑Entrée #2396 [précédente|suivante]

Recent entries / Entrées récentesIndex of all entries / Index de toutes les entrées