Les systèmes embarqués et les objets connectés (IoT) sont aujourd’hui omniprésents. On les retrouve dans les équipements domestiques intelligents, capteurs industriels, dispositifs médicaux, systèmes automobiles ou encore infrastructures urbaines connectées. Derrière ces appareils se trouvent des microcontrôleurs et des composants électroniques dont le fonctionnement doit être rigoureusement testé, observé et diagnostiqué tout au long de leur cycle de développement.
Pour les ingénieurs et les développeurs, il est essentiel de pouvoir analyser le comportement interne du matériel, vérifier l’exécution du firmware ou identifier l’origine d’un dysfonctionnement. C’est précisément le rôle des interfaces de debugging matériel qui permettent d’interagir directement avec l’électronique d’un appareil pendant les phases de conception et de validation.
Cependant, ces mécanismes conçus pour faciliter le développement peuvent devenir problématiques lorsqu’ils restent accessibles sur un produit final. Dans le contexte de la sécurité des objets connectés, un port de debug exposé peut constituer une surface d’attaque importante, notamment pour un attaquant disposant d’un accès physique au matériel.
Pour cette raison, ces interfaces sont aujourd’hui un point d’attention majeur dans les démarches de pentest IoT et d’analyse de sécurité des systèmes embarqués.
Les ports de debug sont des interfaces matérielles utilisées en électronique et dans l’IoT pour faciliter le développement, la configuration et le diagnostic des systèmes embarqués.
Ils permettent aux développeurs d’interagir directement avec un microcontrôleur ou un circuit intégré afin d’observer son fonctionnement interne, d’analyser l’exécution du firmware ou encore de modifier l’état du système pendant les phases de test.
Selon leur implémentation, ces interfaces de hardware debugging peuvent offrir de nombreuses capacités de diagnostic ou de contrôle sur le système :
Ces fonctionnalités, indispensables lors du développement, font également des ports de debug des éléments particulièrement sensibles dans la sécurité des objets connectés. Lorsqu’ils restent accessibles sur un appareil en production, ils peuvent offrir à un attaquant un niveau de contrôle très élevé sur le système ciblé.
Pour comprendre les risques associés à ces interfaces, il est nécessaire d’examiner les principaux types de ports de debug que l’on rencontre dans les environnements IoT et les systèmes embarqués grand public.
Le JTAG (Joint Test Action Group) est un standard de test et de debug matériel défini dans les années 1980 et aujourd’hui largement utilisé dans les systèmes embarqués et les microcontrôleurs modernes.
Initialement conçu pour effectuer des tests de continuité sur des circuits imprimés, il a progressivement évolué vers une interface complète de debug permettant d’interagir directement avec un processeur ou un microcontrôleur.
Les architectures courantes (ARM, x86, MIPS, PowerPC) proposent ainsi des outils permettant d’effectuer du tracing, de définir des breakpoints, d’accéder aux registres ou encore de réaliser des dumps mémoire. Cela rend le JTAG un outil complet et très puissant pour accompagner le développement et le debugging d’un circuit imprimé.
D’un point de vue technique, le JTAG est un bus série synchrone qui peut comporter entre 2, 4 ou 5 pins :
Une configuration JTAG standard ressemble à ceci :

Cette configuration est généralement utilisée en chaînage (daisy-chain). Le bus JTAG étant un bus série, plusieurs composants peuvent être reliés les uns aux autres, le signal TMS permettant de sélectionner le composant ciblé.
Le cJTAG (compact JTAG) est une variante du protocole JTAG conçue pour réduire le nombre de pins nécessaires.
Contrairement au JTAG classique, il n’utilise que deux lignes :
Étant donné qu’il n’y a qu’un seul canal de communication (sans TMS), dans le cas de plusieurs composants, il est nécessaire que tous les composants soient allumés et parsent les instructions envoyées par le canal TMSC, cela étant le seul moyen de savoir à quel composant en particulier les instructions sont adressées.

Cette simplification permet de réduire l’empreinte matérielle sur les circuits intégrés, ce qui est particulièrement utile dans les systèmes embarqués compacts.
L’UART (Universal Asynchronous Receiver-Transmitter) est une interface de communication série asynchrone largement utilisée dans les systèmes embarqués et les objets connectés.
Contrairement au JTAG ou au SWD, l’UART n’est pas une interface de debug dédiée mais un simple canal de communication entre deux composants. Il est historiquement utilisé depuis les années 1980 pour permettre la communication entre un ordinateur et un périphérique.
Étant asynchrone, il n’y a pas de pin pour synchroniser la fréquence des communications. Le système ne requiert que 2 pins :

Chaque pin est connecté à son équivalent sur le périphérique distant.
Puisque dépourvu de pin pour la synchronisation des fréquences, celle-ci doit être manuellement mise en place pour que les deux composants puissent communiquer correctement. La synchronisation entre les deux systèmes est donc définie via un taux de transmission (baud rate), souvent configuré à 115200 bauds dans les systèmes embarqués.
L’UART est un simple système de communication. Il n’a pas de fonctions préétablies telles que pourrait l’avoir, par exemple, le JTAG avec EXTEST. Toute fonctionnalité va donc être définie soit par le fabricant du composant visé ou par le software que celui-ci fait tourner. Il existe évidemment de nombreux standards d’implémentation, trop pour être énumérés, et cela sans compter toute la possible surcouche de fonctionnalités qui peut être rajoutée ensuite.
Dans de nombreux appareils IoT, un port UART exposé sur la carte électronique permet d’accéder à une serial console. Celle-ci peut afficher les logs du firmware, permettre d’interagir avec un bootloader ou, dans certains cas, offrir un accès direct à un shell système. Il peut être compliqué pour un acteur malicieux (et sans accès à la documentation) de savoir quels privilèges ou opportunités un port UART actif peut lui donner.
Le SWD (Serial Wire Debug) est une interface de debug développée par ARM pour les microcontrôleurs Cortex-M.
Le SWD utilise deux lignes principales :
Il reprend les principales capacités de debugging du JTAG tout en réduisant le nombre de pins nécessaires, ce qui la rend particulièrement adaptée aux microcontrôleurs modernes utilisés dans les objets connectés. Cependant, il ne permet pas de faire de tests de continuité. Il est également limité aux architectures ARM, il n’y a, à ma connaissance, pas d’autres constructeurs qui ont décidé d’implémenter ce protocole.
Cette interface permet d’effectuer de nombreuses opérations d’ARM debugging, comme l’accès aux registres du processeur, l’inspection de la mémoire ou l’analyse du firmware en cours d’exécution.
Le JTAG, l’UART et le SWD représentent les principaux types de ports de debug mais il existe d’autres standards par différentes entreprises ou consortiums. Techniquement, n’importe quel fabricant peut implémenter ses propres outils de debugging, ce qui peut conduire à une prolifération de ceux-ci, chacun avec une documentation plus ou moins complète et plus ou moins publique.
Parmi les standards relativement répandus :
Les ports de debug offrent un ensemble d’outils extrêmement puissants pour interagir avec un système embarqué. Lorsqu’ils restent accessibles sur un appareil en production, ils peuvent offrir à un attaquant disposant d’un accès physique un avantage significatif.
Lors d’un pentest IoT, ces interfaces figurent souvent parmi les premiers éléments analysés. Un port actif peut permettre :
Un port JTAG entièrement fonctionnel, par exemple, peut conduire à une compromission totale du composant ciblé, ce qui peut ensuite être exploité pour compromettre d’autres éléments du système ou de l’écosystème auquel il appartient.
Pour faire un parallèle avec le monde du web, un port de debug doit être considéré comme l’équivalent d’un mode développement activé sur une application ou un framework (comme le profiler Symfony). Il s’agit d’un outil extrêmement utile durant le développement mais qui doit impérativement être désactivé ou protégé avant une mise en production.
Il est donc essentiel de mettre en place des processus de sécurisation lors du déploiement afin de s’assurer que les interfaces de debug ne restent pas accessibles dans les produits commercialisés. Une mauvaise gestion de ces ports peut conduire à la fuite de données sensibles, à la compromission du firmware ou encore à l’utilisation du composant comme point d’entrée pour des attaques plus larges.
Les ports de debug constituent des outils indispensables pour le développement et l’analyse des systèmes embarqués. Ils permettent aux ingénieurs d’observer le fonctionnement interne d’un microcontrôleur, d’accéder au firmware et de diagnostiquer des problèmes matériels ou logiciels.
Cependant, lorsqu’ils restent accessibles dans un produit final, ils peuvent offrir à un attaquant un accès privilégié au matériel et au firmware. Dans le domaine de la sécurité des objets connectés, leur désactivation, leur restriction ou leur protection constitue donc une étape essentielle pour limiter les risques liés à l’accès physique au dispositif.
Auteur : Renaud CAYOL – Pentester @Vaadata