“L’histoire de l’industrie est le livre ouvert des facultés humaines.”
Igor Sikorsky
Hum… Et bien nous allons voir aujourd’hui que ce n’est pas forcément une bonne nouvelle !
Bonjour à tous et bienvenue sur ce nouveau tuto, aujourd’hui nous allons attaquer cette nouvelle série dédiée aux protocoles avec Modbus.
Je ne vous demande même pas si vous êtes prêts car je sens que vous bouillonnez d’impatience !
“Ouuuuuuuuuuuuuais”
C’est parti !
I) Un peu de contexte
Avant de rentrer dans les détails du protocole Modbus, il va falloir que je vous parle un peu des technologies opérationnelles. Cette introduction va peut être vous paraitre un peu longue mais ne vous inquiétez pas , restez avec moi, ça va bien se passer.
La technologie opérationnelle (Operational Technology ou plus simplement OT) est du matériel et des logiciels qui détectent ou provoquent un changement, par le biais de la surveillance et / ou du contrôle direct des équipements industriels, des actifs , des processus et des événements .
https://fr.qaz.wiki/wiki/Operational_Technology
Pour la suite de ce tuto, j’utiliserai le terme ‘OT’ plutôt que ‘technologie opérationnelle’ pour faciliter la lecture et ne pas surcharger. De plus c’est le terme le plus couramment utilisé en entreprise.
Vous l’aurez compris l’OT peut prendre donc plusieurs formes, comme par exemple :
- Le contrôle du trafic aérien
- La gestion des niveaux des ingrédients dans des cuves
- Le système de gestion des pipelines
- Le système de gestion des réacteurs de centrales nucléaires
- etc…
Pour gérer les OT il existe plusieurs système de contrôles (Industrial Control Systems ou ICS) dont les plus connus sont :
- SCADA (Supervisory Control And Data Acquisition)
- RTA (Remote Terminal Unit)
- HMI (Human Machine Interface)
- DCS (Distributed Control System)
- RTU (Remote Terminal Unit)
- etc..
Ces systèmes sont en général utilisés ensemble car ils sont complémentaires et/ou utiles à différents endroits de l’OT, voici un petit schéma pour l’exemple :

- Les senseurs (sensors) sur le schéma, dans les faits peuvent être des thermostats, des capteurs qui comptent le passage de produits sur une chaine opérationnelle, une cafetière connectée…
- Un système de supervision SCADA n’a pas forcément d’HMI (Human Machine Interface) directement liée à lui
- Un PLC est un automate programmable industriel (Programmable Logic Controler), c’est un dispositif électronique numérique programmable destiné à la commande de processus industriels par un traitement séquentiel. Il envoie des ordres vers les préactionneurs (partie opérative ou PO côté actionneur) à partir de données d’entrées (capteurs,senseurs…) (partie commande ou PC côté capteur), de consignes et d’un programme informatique.
- Un RTU (Remote Terminal Unit) est un dispositif électronique contrôlé par un microprocesseur qui sert d’interface entre des objets physiques et un système distribué ou un système de supervision tel que SCADA, et ce en transmettant des données de télémétrie à un système maître et en utilisant des messages provenant de le système de supervision maître pour contrôler les objets connectés.
Pour ceux qui sont curieux voici une image d’un PLC :

Petit Disclaimer : Je suis conscient qu’en si peu de temps il est difficile de vous expliquer à quels points les système OT sont complexes, et les technologies qui leurs sont associées le sont aussi. Je suis aussi conscient que les définitions données peuvent être un peu floues pour l’instant et que vous ne voyez pas encore ou l’on va aller dans ce tuto, mais n’ayez pas peur, nous avons fini la partie la plus difficile à appréhender. Toutefois gardez à l’idée que dans la réalité ce genre de réseaux peuvent contenir plusieurs centaines de capteurs, senseurs et PLC en tout genre. Je m’excuse par avance pour ceux qui on l’habitude de côtoyer ce genre de système, mais j’ai volontairement fait le tri des informations données pour essayer de faire une synthèse, et pouvoir par la suite se concentrer sur le protocole Modbus sans devoir aborder toutes les subtilités du monde de l’OT.
II) On peut parler de Modbus ? (oui)
“Ouais d’accord t’es bien sympa mais ça fait déjà un moment que le tuto a commencé et tu nous a toujours pas parlé du sujet qu’on est censé aborder ! On sait même pas à quoi ça sert !”
Je sais bien je sais bien calmez vous ! Mais pour comprendre ce qu’est Modbus il faut bien que j’introduise correctement le sujet !
A) Un protocole pour les gouverner tous
Bien donc regardons de plus près le protocole Modbus maintenant :
MODBUS est un protocole de communication non-propriétaire, créé en 1979 par Modicon (absorbée en 1996 par Schneider Electric), utilisé pour des réseaux d’automates programmables, relevant du niveau applicatif, c’est-à-dire du niveau 7 du Modèle OSI. Ce protocole basé sur une structure hiérarchisée entre un client unique et plusieurs serveurs est dans le domaine public et sa spécification est publique.
https://fr.wikipedia.org/wiki/Modbus
Modbus est un protocole qui fonctionne avec deux modes :
- Mode RTU
- Mode TCP
Nous allons nous intéresser aujourd’hui uniquement au mode TCP de Modbus.
Voici donc quelques caractéristique du protocole Modbus en mode TCP :
- Il fonctionne sur le mode client-serveur. Seuls les clients sont actifs, le serveur est complètement passif.
- Ce sont les clients qui doivent lire et écrire dans le serveur Modbus.
- Chaque client doit se connecter au serveur en protocole TCP via l’adresse du serveur et en utilisant un port (par défaut Modbus est mappé sur le port 502)
- Modbus est constitué de trames contenant la fonction à traiter (écriture, lecture) et la donnée.
En plus de ça le protocole peut être implémenté via TCP/IP sur Ethernet , on parle alors de Modbus over TCP/IP (le port par défaut étant le 502) . Dans sa version over TCP/IP le protocole offre un débit de 10 à 100 Mbits par seconde.
B) Ou Modbus est-il utilisé ?
Très bonne question, reprenons dans un premier temps le schéma vu précédemment et laissez moi y ajouter quelques informations :

Comme vous pouvez le voir sur le schéma, Modbus va être utile entre les PLC/RTU et SCADA. SCADA est le maître (le client) et les PLC/RTU sont les esclaves (les serveurs), souvenez vous que des opérations d’écriture et de lecture vont se faire entres les clients et le serveur sur le port 502.
C) Et la sécurité dans tout ça ? La sécu… quoi ?
Bon, maintenant que nous avons vu un peu comment tout cela fonctionne, parlons sécurité.
Le protocole Modbus n’étant pas sécurisé du tout car il n’a pas été prévu pour au départ, il facilement possible pour un attaquant :
- D’intercepter le trafic
- De rejouer des transactions
- D’écrire ou lire des données en tant que maitre (client)
- Altérer les transactions
“Ouais d’accord c’est bien beau ça aussi, mais ça fait beaucoup de théorie tu trouves pas la ? elle est ou la pratique ?!”
Vous me coupez l’herbe sous le pied ! Vous êtes prêts ?!

III) À l’abordage, mes petits pirates
A) Mais avant l’abordage, le configurage…
“Ah ouais, maintenant tes titres sont même plus français, c’est du propre.”
Hum…
Dans un premier temps, il va nous falloir un ennemi à attaquer, heureusement pour nous il existe un logiciel capable de nous aider à constituer rapidement et simplement un environnement OT avec des PLC/RTU simulés. Ainsi tout sera comme si nous avions branché des PLC/RTU sur notre réseau ! Et le tout sans devoir en acheter ou de passer du temps à les configurer…
Pour cette démonstration j’utiliserai Kali Linux (5.9.0-kali5-amd64) et je travaillerai en local mais sachez que vous pouvez tout à fait lancer le logiciel qui va suivre sur une seconde machine sur le même réseau ou sur une machine virtuelle pour rendre cela plus “réaliste”.
Le logiciel en question se nomme ModbusPal et vous pourrez le trouver ici : http://modbuspal.sourceforge.net/
Une fois téléchargé, il suffit de lancer le ‘.jar’ avec la commande suivante :
java -jar ModbusPal.jar
Le programme suivant devrait s’ouvrir :

Nous allons donc maintenant créer un esclave (slave), pour ce faire, cliquez sur le bouton ‘Add’ de la section ‘Modbus slaves’. La fenêtre suivante s’ouvre alors :

Dans la première zone de texte il va falloir renseigné l’identifiant de l’esclave ou plus communément appelé ‘id’. L’id peut prendre des valeurs allant de 1 à 255, ce qui par conséquent veut dire qu’un maître ne peut avoir “que” 255 esclaves à sont service.
Pour l’exemple je vais renseigner tout simplement l’id de notre esclave comme étant le 42.
Et nous pouvons également à l’aide de la seconde zone de texte nommer notre esclave, c’est quand même plus pratique ! Dans la réalité on donnerait un nom clair et précis comme par exemple “Mélangeur d’ingrédient 1” ou encore “Escalator numéro 342”. Je vais pour ma part jouer le jeu et donner un nom précis.
Chez moi cela donnera donc :

Il semblerait que Snk a oublié d’éteindre sa machine à café connectée… dommage pour lui.
Une fois ajouté vous devriez voir l’esclave apparaitre sur la fenêtre principale du programme :

Maintenant nous allons configurer notre équipement, pour ce faire cliquez sur l’œil :

Une fois fait, la fenêtre suivante devrait s’ouvrir :

Deux onglets sont particulièrement intéressant ici, ‘Coils’ et ‘Holding registers’.
Coils veut dire bobine en anglais, les bobines peuvent prendre les valeurs 0 ou 1, et servent donc de fonction ‘marche-arrêt’.
L’onglet ‘Holding registers’ fait références aux registres (mémoires) de l’équipement, en effet la machine à café d’Snk dispose de sa propre mémoire, elle y stocke et lit des valeurs. Ces valeurs peuvent servir à tout et à rien et sont propres à chaque équipement, dans le cas de cette machine à café , nous allons ajouter 5 registres (nous verrons après à quoi ils correspondent). Pour ce faire cliquez sur le bouton ‘Add’, la fenêtre suivante va s’ouvrir :

Comme vous pouvez le voir, il est possible d’ajouter jusqu’à 65535 registres (de 1 à 65536), mais comme dit précédemment nous allons nous servir que de 5 registres seulement. Dans mon cas je vais donc remplir comme suit :

Une fois ajouté les registres vont apparaitre comme suit :

Nous allons donc maintenant donner des valeurs à ces registres, dans le but de simuler un appareil en cours d’utilisation (pour que ce soit plus clair pour vous j’ai donné des noms aux registres, mais vous n’êtes absolument pas obligé de les renseigner). Chez moi cela donnera donc par exemple :

Une fois fait, nous n’allons pas perdre de temps et nous allons lancer la simulation, nous n’avons pas besoin de spécifier de bobine (coils) pour notre exemple.
Pour lancer la simulation, revenez sur la fenêtre principale, et cliquez sur le bouton ‘Run’ en haut, une fois le bouton cliqué, le programme ne vous laissera plus changer le port en grisant la fenêtre comme ceci :

Notre simulation est donc lancée, nous venons donc ce générer un petit équipement (une machine à café dans notre cas) et il communique via Modbus TCP/IP sur le port 502.
Pour vérifier que le logiciel s’est bien lancé et pour nous mettre dans la peau d’un attaquant, nous allons donc scanner le réseau à la recherche d’un port 502 visible.
Pour ce faire procédons comme suit à l’aide du célèbre scanner de port nmap :
nmap "IP de l'équipement ou du sous-réseaux" -p 502
Dans mon cas comme j’ai lancé la simulation sur la même machine qui va me servir de machine d’attaque cela donnera :

Si tout s’est bien passé vous devriez avoir comme moi le port 502 de visible (que ce soit en local ou sur une autre machine sur votre réseau).
B) Maintenant… c’est la bonne !
Sortez vos plus beau drapeaux et vos sabres moussaillons !

“Ah enfin c’est pas trop tôt !”
Donc maintenant que nous avons un réseau avec un équipement à attaquer, lançons dans un premier temps metasploit, pour ce faire utilisez cette commande :
msfconsole
Une fois lancé, regardons ce que nous avons comme possibilités avec msf, pour se faire je vous propose d’effectuer une simple recherche grâce à la commande :
search modbus

En tant qu’attaquant essayons de jouer le jeu, nous savons déjà qu’il y a un ou plusieurs équipements qui utilisent le port 502 sur notre réseau, mais nous ne connaissons pas l’id de l’appareil que l’on va attaquer, et vous allez voir que l’on va en avoir besoin.
Heureusement pour nous il existe un script qui va nous permettre de trouver l’id de l’équipement, il s’agit de ‘modbus_findunitid’.
Sélectionnez donc le module comme suit :
use auxiliary/scanner/scada/modbus_findunitid
Regardons les options du module avec la commande comme suit :
options
Les options sont les suivantes :

Les paramètres semblent bons, il ne reste qu’a renseigner le champ RHOSTS avec l’adresse IP de votre machine ou se trouve la simulation, dans mon cas cela donne ça :

Il ne reste plus qu’a lancer le module en tapant :
run
Remarque : Le script va juste tenter de se connecter aux différents identifiants, si comme moi vous avez renseigné l’id 42 pour votre équipement cela risque de prendre environ 1 minute car par défaut le script attend 1 seconde entre chaque essai, si vous voulez accélérer le scan vous pouvez changer la valeur de l’option ‘BENICE’.
Dans mon cas, une fois le script arrivé sur l’id numéro 42 il découvre bien l’équipement :

Nous savons donc maintenant que l’équipement ciblé a pour identifiant le numéro 42 !
Grâce à cela nous allons pouvoir maintenant lancer notre attaque !
Pour ce faire nous allons utiliser le module ‘modbusclient’ :
use auxiliary/scanner/scada/modbusclient
Regardons les options :

Regardons la liste des actions possibles comme ceci :
show actions

Comme vous le voyez il est possible donc de lire et d’écrire dans les registres et les bobines comme on le souhaite, nous allons donc pour l’exemple lire la valeur des registres et ensuite écrire des valeurs dedans.
Pour lire les données dans mon cas je vais procéder comme suit :
set action READ_HOLDING_REGISTERS
set DATA_ADDRESS 0
set RHOSTS 127.0.0.1
set unit_number 42
Remarque : Le champ DATA_ADDRESS est l’adresse de la donnée que l’on souhaite lire, précédemment j’ai définis à l’adresse 1 le nombre de gobelets restants dans la machine à café, on s’attend dans mon cas à lire donc la valeur 50. Seulement le programme de simulation étiquette à partir de 1 alors que le module msf étiquette à partir de 0, ainsi pour lire la valeur de l’adresse 1 on doit spécifier l’adresse 0 dans msf.
Remarque 2 : la valeur unit_number correspond à l’id de l’équipement, en théorie dans un cas aussi simple que le nôtre il ne serait pas nécessaire de le spécifier, mais pour faire les choses proprement il vaut mieux prendre l’habitude de le faire.
De mon côté la configuration finale donne donc ceci :

Il ne nous reste plus qu’à lancer :
run

Et donc c’est bien la valeur 50 qui est lue !
Maintenant essayons de changer la valeur à cette adresse , afin que Snk pense que sa machine à café n’a plus de gobelets mouhahahahaha !
Pour ce faire procédons de la manière suivante :
set action WRITE_REGISTER
set DATA 0
Le champ DATA est la valeur que l’on va écrire dans le registre, ici donc j’ai choisis la valeur 0.
Dans mon cas la configuration finale sera donc :

Il ne nous reste plus qu’à lancer comme ceci :
run

Il semblerait que notre attaque soit une réussite, vérifions immédiatement sur le simulateur :

Et bravo ! Nous avons changé la valeur du registre ! Notre pauvre Snk aura donc un message d’alerte de sa machine à café alors qu’il reste réellement 50 gobelets ! Je suis un génie du mal mouhahahahahahahaha !

IV) Conclusion(s)
Bien , nous sommes ENFIN à la fin de ce tuto, il est vrai qu’il était dense mais j’espère qu’il était néanmoins intéressant !
Nous avons simulé ici une simple machine à café et nous avons changé les valeurs de ses registres pour faire croire au propriétaire que sa machine n’avait plus de gobelets… Mais en réalité il y a très peu de chance qu’une cafetière utilise Modbus comme vous devez vous en douter puisqu’il faudrait qu’un PLC/RTU soit intégré à celle-ci.
Maintenant je vous laisse imaginer dans un système SCADA d’une centrale nucléaire, si nous changeons la valeur d’un registre du PLC qui contrôle la vitesse des ventilateurs pour refroidir le cœur du réacteur….
Modbus n’a pas été conçut pour être sécurisé mais fiable, c’est pourquoi il est vivement conseillé de ne pas utiliser Modbus tel quel mais de l’encapsuler et/ou de chiffrer.
Vous pouvez bien sur vous amuser avec le logiciel et créer des réseaux bien plus vastes.
Si vous voulez des informations sur des attaques réelles sur des systèmes SCADA je vous invite à lire de la documentation sur Stuxnet.
Pour ceux qui voudront plus d’informations et des détails techniques directement lié à Modbus, je vous recommande la lecture de cette RFC :
https://tools.ietf.org/html/draft-dube-modbus-applproto-00
Encore une fois merci à tous pour avoir suivit ce tuto, j’espère sincèrement qu’il aura été instructif !
Je vous dis à bientôt pour un nouveau tuto !
ZeR0-@bSoLu
4 thoughts on “Protocoles : Modbus”
PLC est certes traduit dans l’article.
Néanmoins, l’usage veut que l’on utilise API en Français dans ce contexte (à ne pas confondre avec API = Active Pharmaceutical Ingredient en Anglais, c-à-d. principe actif pharmaceutique 😉 ).
Concernant les aspects de “non-sécurisation” mentionnés dans l’article, il est crucial que les personnes en charge de la “modernisation” des systèmes d’automatisation réalisent que les prérequis des deux mondes – OT / IT – sont très différents : temps de réponse, sécurisation des systèmes, durée de rétention des données, …
PLC est plus “wordwild” comme on dit 😛
Mais merci pour la précision encore une fois 🙂
Mon premier merci était global pour tout ce que tu as écris, et ma remarque ne tenait donc que sur les termes 😉
Donc encore Merci pour avoir pris le temps de détailler pour ceux qui liront l’article 🙂
Bonjour,
merci pour cet article intéressant.
Quelques remarques :
– Sensor = capteur
– PLC = API, c-à-d. automate programmable industriel
– à propos de l’OT :
J’ai bien conscience que cette abréviation est devenue très à la mode depuis 2 ou 3 ans. Néanmoins, il s’agit tout simplement de systèmes temps réel d’automatisation (y compris les infrastructures dédiées associées). Je sais que depuis au moins 25 ans, l’informatique – IT – était plus à la mode que l’automation, cependant il s’agit de système parfois – pas toujours – complexes et la plupart du temps critiques pour les processus contrôlés, pour la sécurité de personnels et des biens, pour la qualité du produit. De nombreuses technologies évoluées et efficaces (efficientes) ont été élaborées pour des systèmes automatisés et de contrôle des procédés. Pendant très longtemps, ces systèmes n’ont pas été mis en contact avec “le monde extérieur” (c-à-d. les réseaux de l’entreprise). C’est la raison pour laquelle ces systèmes étaient jusqu’à présent faiblement sécurisés. La vague “4.0” qui tend à tout interconnecter – malheureusement sans suffisamment réfléchir aux risques associés – rend ces systèmes vulnérables car très sensibles aux problèmes de cybersécurité.
Cordialement,
Erwann
Merci pour tes précisions même si la traduction des termes est déjà dans l’article ^^’