Realtime Process Simulation of Plant Water Supply Unit
Virtual hardware-in-the-loop process, generates logically correct Modbus signals of typical Water Supply facility using Python and ModbusTCP library
Simulation uses https://github.com/riptideio/pymodbus library
Python script could run on any Linux system with python 3.6 and above (Kali Linux, Ubuntu, Debian) should also run on Raspberry Pi like boards
This simulation can be used for HMI/SCADA and PLC's ModbusTCP interface card testing with realtime values and for ICS security research/trainings
The project is a migration of https://github.com/akiUp/ICSUnitSim from Arduino like platform.
- V1 Project migrated from arduino/ESP32 platform
- V2 introduces pressure sensor and pipe explosion scenario as well as owerflow scenarion which will stop the simulation
- V3 is the reaction on Oldsmar attack, adding simple clorine level dial. changing it would not affect process, but raise warning message on backend.
!!!The Modbus server implementation requires super user rights!!!
copy the process.py script into user area like /home/kali/
to run the server use below command from script directory
sudo python3 process.py
by default server will start on current machine's ip and port 502
Lightweight VM image with autorun of process.py script is planned
For simple Modbus values reading/writing/monitoring you could use python scripts from my Modbus_Bruteforce repo https://github.com/akiUp/modbus_bruteforce
Current HMI Example is designed on Ignition SCADA by Inductive Automation
HMI_Project folder contains latest backup of Ignition HMI Project, restore it into you Ignition setup for below result.
Free trial versions of HMI software like RapidSCADA, Ignition and Advantech are available on internet.
!Important!: Modbus library uses 0 based adressing
- Modbus Coils Offsets (read\write)
mot_start, address: 100, boolean, Start button, 1 to activate, returns to 0 after activation
mot_stop, address: 110, boolean, Stop button, 1 to activate, returns to 0 after activation
valve_state, address: 120, boolean 0-Closed 1-Open (Controlled by start/stop logic)
mat_auto, address:130, boolean, 1-Pump automatic mode(by setpoints), 0 - manual mode
- Modbus input status (Discrete Inputs) Offsets(read only)
mot_run, address: 100, boolean, 1 running, 0 stop
mot_trip, address: 110, boolean, Motor trip state, cause: Tank full, Valve closed, Random trip (1 of 10000)
- Modbus Input Register Offsets (read only)
mot_load, address: 100; Uint16, range:0-100, random motor load simulation
flowm_flow, address: 110, Uint16, range:0-10, flow value depending on mot_load
tank_level, address: 120, Uint16, range:0-65000, 65000 value trips the motor, has constant (random of 4) drainage flow
tank_drain, address: 130; Uint16, Random drain by process
- Modbus Holding Register Offsets (read\write)
tank_Hi, address: 100; Uint16, adjustable Hi level setpoint, for turning motor OFF in AUTO mode
tank_Lo, address: 110; Uint16, adjustable Lo level setpoint, for turning motor ON in AUTO mode
- Based on Pymodbus's "Updating server" example script
- Inductive Automation's Ignition SCADA used for HMI Design https://inductiveautomation.com/ignition/