The attack targets Modbus TCP — an industrial protocol with no built-in authentication or encryption.
Data injection attacks in industrial control systems.
This project demonstrates how insecure OT protocols can be exploited to directly manipulate PLC behaviour, the physical impact that follows, and how detection, prevention, and AI-powered reporting can protect real industrial environments.
Python scripts using PyModbus establish a direct connection to the PLC and send malicious write commands.
Snort detects suspicious Modbus traffic patterns. Suricata blocks the attack before it reaches the PLC.
Ollama processes Suricata logs and generates human-readable incident reports automatically.
What this project demonstrates
Modbus TCP is one of the most widely used industrial protocols — and one of the least secure. It has no built-in authentication, meaning any device on the network can connect to a PLC and issue commands. This project exploits that weakness in a controlled lab environment to show what a real attack looks like and how it can be stopped.
The vulnerability
Modbus TCP was designed for reliability in closed networks, not security. Any host that can reach port 502 on the PLC can read or write registers and coils without any credentials.
The attack
A Python script running on Kali Linux connects directly to the PLC over TCP, acts as a rogue Modbus master, and issues write commands — forcing unsafe register values or overriding output coils.
The physical impact
Factory I/O reflects the manipulated values in real time — pumps forced on, tanks overflowing, valves driven to unsafe states — exactly what would happen in a real OT environment.
The defence layer
Snort and Suricata monitor the same network. Snort raises alerts; Suricata actively blocks the connection. Logs flow into ELK and an Ollama AI model turns them into incident reports.
End-to-end system walkthrough
From normal PLC operation through to AI-generated incident reports — here is exactly how the project runs from start to finish.
Normal Operation
Under normal conditions, OpenPLC runs a Structured Text control program that monitors and controls a water tank process simulated in Factory I/O. The PLC reads sensor inputs — water level, flow rate — and issues output commands to pumps and valves to maintain a safe operating state.
A custom HMI built with Python, Flask, and PyModbus polls the PLC over Modbus TCP and displays live process values in a browser dashboard. The operator can see tank level, pump status, and valve positions in real time. Everything is behaving exactly as designed.
Attack Phase — Unauthorised Modbus Command Injection
The attacker VM (Kali Linux) runs a Python script that uses PyModbus to establish a direct TCP connection to the PLC on port 502. There is no interception of existing traffic — the script connects as a rogue Modbus master and issues its own write commands directly to the PLC.
The script can write arbitrary values to holding registers (e.g. forcing a tank level reading to 9999) or write coil states directly (e.g. forcing a pump output to TRUE). The PLC has no way to distinguish these commands from legitimate ones — Modbus TCP has no authentication. Factory I/O responds to the changed output states immediately, showing the physical consequence of the attack.
client.write_register(1, 9999) # overflow tank
client.write_coil(5, True) # force pump ON
Detection Phase — Snort IDS
Snort is running on the defensive VM and monitoring the same network segment. It applies custom rules that flag unexpected Modbus write commands — particularly write requests from hosts that are not the authorised HMI, or write values that fall outside safe operating ranges.
When the attack script connects and starts issuing commands, Snort raises alerts and logs the event with full packet detail: source IP, destination port, Modbus function code, and payload. At this stage Snort is detection only — it raises the alarm but does not interrupt the connection.
Prevention Phase — Suricata IPS
Suricata operates in IPS mode inline on the defensive VM. Unlike Snort which only observes, Suricata can actively drop packets that match its ruleset. When it detects the unauthorised Modbus write pattern from the attacker, it drops the connection entirely — the PLC never receives the malicious command.
This is the key difference between detection and prevention in this project: Snort tells you the attack happened; Suricata stops it from completing. Running both together lets the project compare outcomes — with and without active blocking — and demonstrates the importance of inline IPS in OT environments.
Monitoring & Analysis — ELK Stack
All Suricata and Snort logs are shipped to the ELK Stack (Elasticsearch, Logstash, Kibana) running on the defensive VM. Logstash ingests and parses the raw log data, Elasticsearch indexes it, and Kibana provides a real-time dashboard showing traffic volume, alert categories, attacker IPs, and Modbus function code distribution.
This gives a full visual picture of the attack as it happens — when the connection was made, what commands were sent, and whether Suricata blocked them. The Kibana dashboard is a key deliverable of the project, showing that OT security monitoring does not have to be limited to specialist industrial tools.
AI Reporting Layer — Ollama
A Python script on the host machine reads Suricata's eve.json log file, extracts alert entries, and passes them to Ollama — a locally running large language model. The model processes the structured log data and generates a plain-English incident report: what happened, when, what was targeted, and what the recommended response is.
This layer matters because raw SIEM logs are not accessible to most plant engineers. Automating the translation from technical alerts into readable reports bridges the gap between security tooling and operational awareness — which is one of the key goals of this project.
Awareness Impact
One of the primary goals of this project is to act as an awareness tool for engineers working in OT and ICS environments. A written report or lecture explaining that Modbus has no authentication is easy to dismiss. Watching a Python script connect to a PLC in seconds and physically change a simulated process in real time is not.
By combining a live Factory I/O simulation, a working attack, visible detection and blocking, and an AI report — the project creates a complete, demonstrable picture of the risk. Engineers who see it understand immediately why network segmentation, protocol hardening, and continuous monitoring matter in their environments.
OT/ICS security monitoring and AI reporting
This diagram shows the full end-to-end architecture: the ICS environment on the host machine, the attacker VM, the defensive VM running Suricata/Snort/ELK, and the AI reporting layer — all connected and interacting as a complete system.
Tools used across the project
Each component of the stack has a specific role — from simulating the industrial process, to executing the attack, to detecting, blocking, logging, and reporting it.
ICS Environment
- Factory I/O (process sim)
- OpenPLC (control logic)
- Docker (PLC runtime)
- Structured Text
Custom HMI
- Python
- Flask
- PyModbus
- Browser dashboard
Attack VM
- Kali Linux
- Python attack scripts
- PyModbus
- Modbus TCP (port 502)
Detection & Prevention
- Snort (IDS)
- Suricata (IPS)
- Custom Modbus rules
SIEM / Monitoring
- Elasticsearch
- Logstash
- Kibana
- eve.json log pipeline
AI Reporting
- Ollama (local LLM)
- Python log parser
- Auto incident reports
Video walkthrough
A full walkthrough of the project — showing the lab environment, the attack script connecting to the PLC, Factory I/O responding in real time, and the detection, blocking, and AI reporting stages.
Key deliverables and supporting material
The main written outputs of the project. PDF files are included in the uploaded submission package.
Project specification
Initial project scope, objectives, deliverables, success criteria, and proposed ICS security focus including the Modbus TCP attack model.
Research document
Literature review covering ICS security, Modbus TCP vulnerabilities, OT attack history, and the case for combining IDS/IPS with AI-assisted reporting.
Project report
Full dissertation covering implementation, attack execution, detection and prevention testing, ELK pipeline setup, AI layer, results, and conclusions.
What the project shows
Zero-barrier exploitation
Modbus TCP requires no credentials. Any host that can reach port 502 on the PLC can issue write commands — the attack script connects and begins injecting in seconds.
Real physical impact
Factory I/O responds to the injected register and coil values immediately — pumps forced on, tanks driven beyond safe levels. The physical consequence is visible, not theoretical.
Detection vs. prevention
Snort proves the attack happened. Suricata stops it from completing. Running both together shows why inline IPS — not just alerting — is necessary in OT environments.
AI closes the reporting gap
Raw Suricata logs mean little to a plant engineer. Ollama translates them into plain-English reports that communicate the attack clearly without requiring security expertise to interpret.
Why this matters for OT engineers
Millions of Modbus TCP devices are deployed in industrial environments worldwide, many of them directly reachable on flat or poorly segmented networks. This project makes the risk tangible: a few lines of Python and an open port is all it takes. The defence tools exist — Suricata, Snort, ELK — and they work on standard hardware. The barrier is awareness, and that is exactly what this project is designed to address.
Get in touch
For academic reviewers, industry visitors, or anyone who wants to discuss the project, the tooling, or OT security in more detail.
Use email for project questions, documentation requests, or follow-up discussion on the research.
philipdudas@gmail.com ↗Connect on LinkedIn to discuss the project, OT security, or industrial cybersecurity more broadly.
Philip Dudas on LinkedIn ↗