La sécurité des Systèmes d’Informations Industriels (SII) est aujourd’hui au centre des préoccupations dans les entreprises concernées. Ces systèmes permettent une action directe dans le monde « physique » à l’aide d’instructions provenant du monde « logique » et pilotent les outils de production de nombreuses entreprises.
Du fait du manque de sécurité de ces systèmes, de nombreuses attaques ont été recensées dans le monde ces dernières années. La dernière en date ayant eu le plus gros impact est l’attaque du réseau électrique de l’Ukraine en décembre dernier [1]. De nombreuses personnes se sont retrouvées sans électricité suite à une attaque du réseau industriel.
Le plus bas niveau des SI industriels est le réseau de production. Les capteurs et les actionneurs sont reliés aux entrées/sorties des automates industriels. Les protocoles utilisés pour communiquer avec ces automates sont généralement des protocoles propriétaires. Parmi les plus utilisés, on retrouve : Modbus, S7comm, DNP3, Profibus, Hart… Ces protocoles manquent souvent des principales fonctions de sécurité à savoir l’authentification et le chiffrement des flux. Il est donc possible de rejouer des requêtes et de réaliser des actions malveillantes directement sur les automates.
Modbus, protocole de Schneider Electric publiquement documenté et libre de droits, est une norme de référence pour les communications industrielles. De nombreux outils utilisant ce protocole existent pour communiquer avec les automates Schneider :
- Le module Metasploit modbusclient [2], permettant de lire et d’écrire sur les coils / registres de l’automate
- Le module Metasploit modicon_command [3], permettant d’arrêter / démarrer l’automate à distance
- Le module Metasploit modicon_stux_transfer [4], permettant de récupérer / télécharger le code de l’automate
- Le script perl mbtget [5], permettant de lire et d’écrire sur les coils / registres de l’automate
- La librairie python Pymodbus [6], permettant de communiquer avec des automates Schneider
En revanche, le protocole S7 Communication (S7comm) est quant à lui nettement moins fourni en outils, bien qu’utilisé par tous les automates Siemens.
Il existe cependant la bibliothèque Snap7 [7] ainsi qu’un wrapper Python utilisant ce protocole.
Nous nous sommes ainsi lancés dans le développement d’un nouveau script baptisé « s7comm », permettant facilement de dialoguer avec les automates Siemens.
Présentation de s7comm s7comm [8] est un script python utilisant la librairie Snap7 permettant de lire et écrire sur les sorties des automates Siemens.
Les différents arguments sont directement spécifiés en ligne de commande, exactement comme pour le script mbtget pour le protocole Modbus :
$ python
s7comm.py -a address -m mode -n number -d data ip_address
-a Adresse à partir de laquelle les
données vont être lues / écrites
-m [r|w] Choix du mode de
fonctionnement : lecture ou écriture sur l’automate
-n Nombre de données à lire /
écrire
-d Données en bit à écrire (exemple
0110)
Les deux principales fonctions utilisées de la bibliothèque Snap 7 sont les suivantes :
s7.read_area(snap7.types.areas[‘PA’], 0, start, size)
Cette fonction permet de lire des données sur les sorties de l’automate en utilisant le protocole S7comm.
Elle admet quatre arguments :
1. Le type de données : dans ce cas, il s’agit des sorties numériques (« tout ou rien », tor) de l’automate.
2. Le numéro de la base de données : dans le cas des sorties numériques, cette option n’est pas utilisée et a donc toujours la valeur 0.
3. Le byte d’offset : il s’agit du premier byte lu.
4. Le nombre de bytes à lire.
s7.write_area(snap7.types.areas[‘PA’], 0, start, data)
Cette fonction permet d’écrire des données sur les sorties de l’automate.
Elle a quatre arguments :
1. Le type de données : dans ce cas, il s’agit des sorties numériques de l’automate.
2. Le numéro de la base de données : dans le cas des sorties numériques, cette option n’est pas utilisée et a donc toujours la valeur 0.
3. Le byte d’offset : il s’agit du premier byte sur lequel on va écrire.
4. Les données à écrire sous forme de bytearray.
Chaque sortie de l’automate a une valeur sur un bit. Huit sorties peuvent donc être écrites sur un byte. Plusieurs opérations doivent donc être réalisées avant d’envoyer la commande puisque les arguments “address” et “number” donnés en ligne de commande font référence à des bits. Notamment, si le premier bit à lire n’est pas le premier bit du byte, il y a un offset à prendre en compte.
Pour finir, voici deux exemples d’utilisation :
1. Lecture de 8 bits à partir de l’adresse 0 :
2. Écriture de la valeur 1 sur 8 bits à partir de l’adresse 0
Conclusion
À travers la publication de l’outil s7comm comme de cet article, nous souhaitons rappeler la relative facilité à communiquer avec des automates industriels.
Un attaquant, une fois arrivé sur le SI industriel, peut directement perturber le procédé industriel. Vos commentaires et contributions sont les bienvenus afin de fiabiliser et d’améliorer cet outil.
Sources :