Les systèmes embarqués et IoT sont définis comme étant des systèmes électroniques et informatiques autonomes, qui sont dédiés à effectuer des tâches fonctionnelles précises. Ils sont complexes car ils regroupent des briques logicielles pointues, des ressources matérielles intégrées très hétérogènes et de plus en plus souvent des capacités de communication et connectivité. Cependant, ces différents éléments augmentent inévitablement la surface d’attaque et amènent de nouvelles vulnérabilités en termes de sécurité.
La sécurité des systèmes embarqués couvre de nombreuses problématiques liées à la protection de ces circuits électroniques et des données qu’ils manipulent. La connectivité à Internet, de plus en plus présente, nous incite à revoir les techniques de sécurité pour éviter la prise de contrôle à distance par un acteur malveillant. Il est donc important de définir et mettre en œuvre une politique de performance et de sécurité dans les systèmes embarqués, afin de pouvoir profiter pleinement des opportunités offertes par l’IoT.
Le problème majeur observé en termes de sécurité lors du développement d’un objet connecté est la non-évaluation de la menace, surtout lorsque ce produit est communicant et qu’il est développé sans tenir compte de l’aspect sécurité.
Les différentes voies d’attaques possibles sur les objets connectés sont les suivantes :
Ces différents types attaques remettent en cause les principes clés de la cybersécurité (Confidentialité, Intégrité, Disponibilité) des applications exécutées et des données manipulées par le système embarqué.
L’amélioration de la sécurité d’un système embarqué et des systèmes distribués critiques commence par une bonne identification de la surface d’attaque potentielle.
Lors de nos missions d’audit avec une approche par boite blanche (tests qui consistent à examiner le fonctionnement d’une application et sa structure interne), des outils d’analyse de code sont utilisés pour détecter les erreurs courantes de débordement de buffer (buffer overflow) ou débordement d’entier (integer overflow).
Nous mettons en œuvre deux techniques différentes pour réaliser cette analyse :
Dans le cas d’une fonction implantée de manière logicielle et exécutée sur un microprocesseur, le risque de disfonctionnement en cas de perturbation est fortement corrélé à l’utilisation des registres internes par l’application considérée. La compilation d’un programme C peut par exemple être optimisée avec des objectifs variés (performance, taille mémoire, consommation…). Les options de compilations nous permettent de se protéger contre l’exploitation des vulnérabilités.
Par exemple, la plus connue est fstack-protector qui permet de minimiser les dommages qui peuvent être dus à des attaques de type dépassement de tampon (plusieurs astuces sont disponibles sur le Wiki Debian Hardening).
De plus, toute section sensible du code doit faire l’objet de tests unitaires exhaustifs. Cela inclut notamment :
Voici un résumé des bonnes pratiques à intégrer dans vos processus de développement de produits et systèmes :
Modèle « Security Development Lifecycle » – Microsoft
Pour conclure ce retour d’expérience, il apparaît que la majorité des objets connectés représente une surface d’attaque considérable et cette dernière couvre aussi bien les attaques physiques que logicielles. De plus, les systèmes embarqués modernes hébergent de multiples applications qui représentent également un vecteur d’attaque possible. Il est donc important de mener une évaluation des menaces de bout-en-bout afin de minimiser les risques et les niveaux d’exposition aux menaces de sécurité qui affectent les produits embarqués à forte connectivité. Pour ce faire, la revue et l’analyse détaillée du code est bonne manière d’identifier les vulnérabilités liées aux erreurs d’implémentation et ainsi protéger la propriété intellectuelle.
Trois conseils pour établir une relation de confiance entre les concepteurs d’IoT et utilisateurs/clients finaux :
Réda, Consultant Sécurité chez Akerva