Linux Embedded

Le blog des technologies libres et embarquées

Quelques questions à se poser pour sécuriser un système embarqué

Les systèmes embarqués se retrouvent aujourd’hui dans des domaines d’application de plus en plus critiques : ferroviaire, automobile, médical, militaire, aéronautique... autant de secteurs d’activités qui nécessitent de répondre à de fortes contraintes normatives et sécuritaires.

Typiquement, on ne peut se permettre de laisser libre accès à un contrôle commande de freins de train ou au pilotage automatique d’un avion.

Concevoir la politique de sécurité d’un système embarqué nécessite de se poser quelques questions préalables. Ce sont rarement les développeurs qui ont les réponses à ces questions, mais il est généralement indispensable de les poser et les développeurs étant en première ligne, ce sont eux qui doivent les poser.

Il y a de nombreux articles sur la sécurité informatique en général mais peu d’entre eux abordent la phase de réflexion qui est nécessaire avant de sécuriser un système. Ces questions sont particulièrement importantes dans le cas des systèmes embarqués car leur utilisation est fortement décentralisée. Les mises à jour des systèmes embarqués sont beaucoup plus compliqués que pour des serveurs et les conséquences d'un système compromis sont souvent très différentes. Déployer une mise à jour est déjà une opération complexe pour un logiciel utilisé sur un serveur, mais un déploiement sur des objets connectés dispersés aux quatre coins du monde est une opération autrement plus coûteuse.

Que protégeons-nous ?

Il est impossible de « sécuriser un système » dans l’absolu. Pour aborder sereinement la question de la sécurité, il est nécessaire d’organiser une réflexion sur les menaces et les enjeux. La question de la nature de la cible à protéger est fondamentale mais souvent ignorée.

Quelles informations précieuses contient mon système ?

La première catégorie de cibles qui peuvent être visées est l’information contenue dans notre système. Quelle information sauvegarde-t-on, qui utilise cette information, qui sera la victime si cette information est diffusée ?

Il faut faire preuve d’un peu d’imagination. Notre système contient-il des informations sur son utilisateur ? Nos logs sont-ils anonymisés ? Garde-t-on des informations de debug qui pourraient être exploitées ? Avons-nous des caches qui survivent à un redémarrage ? Les systèmes embarqués ont souvent accès à beaucoup plus d’informations que ce qu’on pourrait croire à priori, un audit peut être souhaitable.

Une question importante est de décider si il vaut mieux compromettre les données ou les perdre. Selon les cas, il peut être intéressant de détruire les données au premier signe d'intrusion, même si celles-ci ne sont pas sauvegardées.

A quelles ressources notre système a-t-il accès ?

Il est assez courant pour un système embarqué de ne pas avoir de données à protéger. Les systèmes purement read-only sont assez fréquents et la plupart des objets connectés sont de simples capteurs qui poussent des informations vers des serveurs distants.
De tels systèmes restent pourtant des cibles valables. Ils ont généralement accès à du matériel dont l’accès même est une cible précieuse : actionneurs, caméras, accès à un réseau interne. Attaquer une serrure connectée peut être très intéressant, même si il n'y a pas de log à l'intérieur.

Même si le matériel lui-même n’a pas d’accès particulier, la ressource informatique elle-même est devenue une cible : un objet peut être utilisé pour mettre en place une attaque de déni de service (DDOS).

A quels autres systèmes notre système a-t-il accès ?

Les permissions données à un système sur lequel nous avons un accès limité et qui sera déployé dans un environnement hostile sont des ressources précieuses. Il est important de les inventorier pour se poser correctement la question des conséquences d’une faille de sécurité.

Dans le monde de l’IoT, cette question devient particulièrement importante : Les objets connectés ont généralement accès à des serveurs centraux et peuvent contaminer des bases de données en y injectant des fausses données.

Un objet compromis peut donc compromettre tout le système. Chiffrer les données n’aide pas car c’est la source du chiffrement qui est compromise. Avoir un système d’authentification peut aider mais la principale façon de se protéger consiste à être capable de révoquer sélectivement les accès de chaque périphérique embarqué lorsqu’une compromission est détectée.

Par quels chemins peut-on accéder à notre système ?

Après l’inventaire des cibles, il faut se poser la question des moyens d’accès à notre système. Il ne s’agit pas de faire l’inventaire des ports ouverts, cela se fait plus tard, mais de réfléchir aux connexions matériels dont dispose notre système.

L’accès physique à la machine

Les systèmes embarqués ne sont que rarement déployés dans des environnements contrôlés. Ce sont des objets du commerce que n’importe qui peut obtenir assez facilement. Toute cible sur notre objet peut donc être attaqué par une personne ayant obtenu l’objet.

Se protéger d’une personne ayant un accès physique à la machine est très difficile. Si nous supposons que notre adversaire est un expert, il est nécessaire de mettre en place un boot sécurisé.

Si notre adversaire est peu qualifié, il suffit de ne pas laisser d’accès simples (protection du BIOS par mot de passe, pas de shell, pas de port série accessible, pas de JTAG ou autre port de debug matériel) mais les limites de notre sécurité doivent être connues et assumées.

Les connexions réseau

L’accès physique est un vecteur d’attaque qui a une limitation forte : il ne permet pas d’attaquer l’ensemble du parc mais uniquement au cas par cas. Il est également difficile d’avoir un accès physique lorsque l’adversaire n’est pas le dépositaire de l’objet.

La plupart des attaques constatées sont des attaques de masse qui visent à infecter le plus grand nombre de machines possible et qui ne font que peu d’effort pour attaquer une machine spécifique. De bonnes pratiques de développement peuvent donc fortement contribuer à la sécurité du parc de produits. Notre adversaire préférera s’attaquer à des cibles plus faciles.

Il existe un grand nombre de bonnes pratiques pour sécuriser le réseau que nous détaillerons dans un autre article, mais lors de la réflexion préalable, il est important de se poser la question de l’utilité de l’accès réseau : pour quoi faire, quels accès, pour qui ? Notre réseau est-il sécurisé en amont (y a t-il un firewall) ?

Les systèmes de mise à jour et de mise au point à distance sont une source de failles très courante et il est nécessaire de les analyser de près. Est-il souhaitable de pouvoir avoir un shell à distance sur toutes les machines déployées ? Pour quoi faire ? Si oui, qui y a accès et comment est-ce surveillé ? Le risque de sécurité vaut-il le coup par rapport au service rendu ? Ces questions sont plus liées à la maintenance du produit qu'à son développement mais c'est pendant les phases de développement qu'il faut se les poser.

La réponse à ces questions dépend fortement du produit, du coût d’un rappel du produit et des conséquences d’une compromission du système.

Les autres accès

Si l'accès physique et le réseau sont les deux chemins d'attaque les plus fréquents, il est important de réfléchir à d'autres connexions dont peut disposer votre système. Chaque système est particulier mais un peu de réflexion sur l'ensemble des entrées du système (Bus CAN, port USB, Bluetooth etc.) peut aider à trouver des vecteurs d'attaque particulier à votre système que l'on n'aurait pas pensé à protéger à priori.

Que sait faire notre adversaire ?

Les moyens de sécurité à déployer ne sont pas les mêmes selon le niveau supposé des adversaires. Il est très facile de faire exploser les coûts de développement en se protégeant d’adversaires beaucoup plus compétents que la menace réelle. La question du niveau de l’adversaire doit être posée en amont.

L’adversaire occasionnel

L’adversaire occasionnel n’est que peu compétent et n’a pas de gros moyens à sa disposition. Il suffit de mettre des barrières standards dans son chemin pour le bloquer. Se limiter à ce genre d’adversaire est un choix qui doit être fait en connaissance de cause. Ce choix revient à accepter qu’un certain nombre de produits seront compromis mais que la plupart ne le seront pas.

Votre système de sécurité revient alors à laisser les utilisateurs compétents faire ce qu’ils veulent avec le produit mais garantir un niveau technique minimum avant de pouvoir prendre en main le système. Ce niveau de sécurité peut être acceptable pour un adversaire ayant un accès physique mais pas pour un adversaire ayant un accès réseau, par exemple.

L’adversaire expert

Nous imaginons ici un expert disposant de gros moyens et un accès au produit (analyse du hard, machines capables de casser des clés de codage de taille raisonnable etc.) Il est extrêmement difficile de se protéger de ce genre d’adversaires, on ne peut que les ralentir.

Ici les défenses seront des défenses en profondeur et des défenses réactives. Il faut mettre en place de nombreux systèmes redondants, chacun se protégeant contre la compromission des autres.

Des pièges de type honeypot peuvent également aider : il s’agit de cibles potentiels que l’on inclut dans le système mais qui ne sont pas utilisées par le système. Tout accès à ces ressources est donc un indice de compromission. Il peut s’agir de ports réseaux spécifiques, d’entrées dans une base de données ou de comptes utilisateurs aux noms tentant (admin, en particulier) mais qui n'ont aucun droit.

Il est également nécessaire de mettre en place des systèmes de détection et d’alerte pour détecter la compromission et être capable de remonter ces alertes pour pouvoir réagir.

Enfin, il est important d’avoir un plan de réponse particulièrement soigné.

Que se passerait-il si notre sécurité est compromise ?

Imaginer qu’un système sera éternellement sûr est une illusion. Anticiper les conséquences d’une attaque est une étape fondamentale de la conception d’un système sécurisé.

Qui doit être informé et comment doit-on les informer ?

Le constructeur d'un système embarqué n'est généralement pas la première victime lorsqu'un système embarqué est compromis mais c'est généralement le premier informé. Il est donc nécessaire de mettre en place un plan d'action pour permettre aux victimes de l'attaque de réagir rapidement. La vitesse de réaction peut être fondamentale si la compromission du système risque de se propager à d'autres systèmes (votre utilisateur réutilise probablement ses mots de passes sur plusieurs systèmes...).

La mise en place d'un plan de communication et de mesures de confinement est indispensable. Réfléchir aux conséquences du vol d'information à priori permet également de se préparer.

Comment re-sécuriser un système compromis ?

Une fois l'attaque détectée et que l'on a déterminé comment corriger la faille de sécurité, il est nécessaire de déployer le correctif vers l'ensemble des systèmes déployés. Ici aussi la prise en compte de cet aspect pendant les phases de conception est indispensable.

Un rappel usine de l'ensemble des produits n'est jamais souhaitable. Un mécanisme de mise à jour à distance est souvent le seul moyen de récupérer un produit corrompu. Le système de mise à jour lui-même étant une cible intéressante pour les attaquants, il est important que celui-ci ne puisse être compromis. Idéalement, ce système doit être totalement séparé du produit et dans une partition read-only inaccessible depuis le système opérationnel. Si une intervention de l'utilisateur n'est pas possible, il faut avoir un moyen fiable de forcer le système à prendre en compte une mise à jour.

Il est important de comprendre qu'une mise à jour sur un système compromis n'est pas une mise à jour comme les autres. Il est important (et difficile) de garantir que le système de mise à jour n'est pas compromis. Si le système de mise à jour n'est plus un système de confiance, un rappel usine sera la seule solution.

 

Conclusion

Ces différentes questions ne doivent pas être prises séparément mais étudiées ensemble. On arrive assez rapidement à devoir catégoriser les adversaires et cibles :

  • L'adversaire n'a pas d'accès physique :
    • Il est intéressé par les ressources mais pas par une instance du produit en particulier ? il s'agit typiquement d'un pirate qui tente de construire un botnet. Des bonnes pratiques et un peu d'audit sur le produit fini suffiront à le contrer mais, si les cibles sont compromises, il faudra être capable de déployer une mise à jour sur l'ensemble du parc, ce qui peut être très coûteux. Il est également recommandé d'introduire de la variation dans vos produits : les mots de passe par défaut devraient être différents pour chaque produit (écrit sur une étiquette du produit par exemple), les clés de sécurité doivent pouvoir être révoquées individuellement.
    • Il vise une cible particulière : notre produit est utilisé pour attaquer la personne qui en est le dépositaire. Contrer ces attaquants est très compliqué car ils sont compétents et motivés. En plus de déployer plusieurs systèmes de sécurité redondants, il faut mettre en place des systèmes d'alerte pour prévenir notre utilisateur.
  • L'adversaire a un accès physique à la machine :
    • Il n'est pas intéressé par une machine particulière : il s'agit sans doute d'un concurrent qui a acheté un exemplaire dans le commerce pour en comprendre le fonctionnement ou pour voler des ressources graphiques ou du code source (en particulier si vous utilisez des langages scriptés).
    • Il est intéressé par une machine particulière, il peut s'agir du propriétaire de la machine ou bien d'une personne ayant illégalement accès à celle-ci (pour les systèmes déployés dans l'espace publique par exemple)

Différencier ces deux cas est quasiment impossible et il est très difficile de s'en protéger.

Chaque produit est un cas particulier qui doit être considéré dans son contexte.

La sécurité informatique n’est pas qu'une question de code, c’est un processus. Cela est souvent répété mais rarement détaillé. Le manque de point de départ pour la réflexion rend les problèmes de sécurité informatique difficile à aborder et généralement laissé aux bons soins des développeurs sans effort d’architecture ni réflexion sur ce que veut dire « sécuriser un produit ».

Maintenant, à vous de vous poser et de poser les bonnes questions sur cet aspect de l'informatique qui ne peut plus être ignoré dans le monde de l'informatique embarqué.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.