In Part 1 of this series, we set up a Koyo CLICK C0-10DRE-D PLC, configured our lab network, and wrote a basic ladder logic program mapping inputs X001 through X004 to outputs Y001 through Y004. The PLC was running, the lights were responding to physical inputs, and the attack surface was already visible: open ports, no authentication, plaintext communication.
In Part 2, we move from observation to active interaction. We are going to override PLC data remotely using the CLICK software's DataView, then interact directly with the PLC over Modbus TCP using mbtget, and finally enumerate and write values over EtherNet/IP using the cpppo Python library. None of these operations require credentials. That is the point.
If you are approaching this series from a defensive perspective and want to understand how to build security controls around industrial environments, the team at Redfox Cybersecurity delivers ICS-specific penetration testing and advisory engagements that map exactly this kind of exposure in production systems.
Before running any commands, it is worth framing what we are simulating. In a real-world ICS intrusion, an attacker who has pivoted from the IT network into the OT network through a misconfigured firewall or a compromised engineering workstation now has Layer 3 access to the PLC subnet. From that position, everything we demonstrate below is executable with no additional privilege escalation.
The PLC does not distinguish between a command from a legitimate SCADA server and a command from an attacker's laptop. It processes whatever arrives on its listening ports. This is the foundational problem with legacy OT protocols: they were designed for trusted, isolated environments that no longer exist in most organizations.
Security boundaries have to be enforced externally through network segmentation, protocol-aware firewalls, and unidirectional gateways. The PLC itself will not protect you. If your organization operates ICS environments without those controls in place, a professional assessment from Redfox Cybersecurity can help you understand your exposure before an adversary does.
The first technique we cover does not require any external tooling. It uses the built-in DataView feature of the CLICK programming software, which is available to anyone who can reach the PLC on the network with the software installed.
Open DataView1 from the Navigation pane on the left side of the CLICK interface. Click the Address button and select input addresses X001 through X004, adding each one to the DataView table.
Once all four addresses are visible in the table, click the Edit button and enable the View Override checkbox. Then double-click the OVR toggle buttons on the rows for X001 through X004 until they turn yellow, indicating override mode is active.
Now double-click the ON button in the New Value column for X001. You will hear the output coil energize on the PLC and see the Y001 indicator LED illuminate on the faceplate.
What just happened is significant. The physical input terminal X001 has no voltage applied to it. The 24V DC source is not connected. But the output coil fired anyway, because the PLC's input data table was written directly from the network. The ladder logic executed based on that overridden value, not on the physical reality of the field device.
This is how an attacker would simulate a sensor reading, suppress an alarm, or force an actuator into a state it should not be in, without touching the physical equipment at all.
Modbus was developed in 1979 by Modicon as a serial communication protocol for connecting industrial equipment. Modbus TCP is a variant that carries Modbus frames over standard TCP/IP networks, listening on port 502. It has no authentication mechanism and no encryption. Every command is sent in cleartext. Every device on the network that can reach port 502 is a potential Modbus master.
In the Modbus model, the PLC acts as a slave. The master polls the slave for data or sends write commands. The slave executes those commands without questioning the source.
mbtget is a lightweight Modbus TCP client written in Perl. It is clean, scriptable, and does exactly what you need for protocol-level interaction without the overhead of a full framework.
To read the state of coil bits starting at address 0, pulling four consecutive values:
mbtget -r1 -a 0 -n 4 10.0.1.10
[cta]
The -r1 flag specifies Function Code 01 (Read Coils). The -a flag sets the starting address and -n sets the count of consecutive registers to read. The output will show four bit values corresponding to the current state of the PLC's coil addresses.
Writing a bit value to the PLC is equally straightforward. To force coil address 0 to a value of 1 using Function Code 05 (Write Single Coil):
mbtget -w5 -a 0 -v 1 10.0.1.10
[cta]
After executing this command, read the coil states again to confirm the write succeeded:
mbtget -r1 -a 0 -n 4 10.0.1.10
[cta]
The bit at address 0 will now return 1, reflecting the value we wrote. The PLC accepted that write without any credential check, any session token, or any source validation.
For more complex interaction, such as writing multiple coils in a single transaction or scripting a sequence of register writes, pymodbus gives you full programmatic control. This is far more representative of what a sophisticated attacker would use for sustained or automated interaction with a PLC.
Install the library on Kali Linux:
pip3 install pymodbus
[cta]
Then write a script to read current coil state, force all four outputs on, and verify the result:
from pymodbus.client.sync import ModbusTcpClient
client = ModbusTcpClient('10.0.1.10', port=502)
client.connect()
# Read current coil states at addresses 0-3
read_result = client.read_coils(0, 4, unit=1)
print("Current coil states:", read_result.bits[:4])
# Force all four output coils ON
write_result = client.write_coils(0, [True, True, True, True], unit=1)
print("Write result:", write_result)
# Verify
verify_result = client.read_coils(0, 4, unit=1)
print("Updated coil states:", verify_result.bits[:4])
client.close()
[cta]
Running this script will activate outputs Y001 through Y004 on the PLC without touching a single physical input terminal. From a defender's perspective, the SCADA historian would log those outputs as ON. The operator display would show normal operation. Nothing in the PLC's own event log would distinguish this from a legitimate command from the SCADA server.
This is the mechanism behind a class of ICS attacks where physical processes are manipulated while reporting systems continue to show nominal values. If you want to understand how to detect and contain this type of activity in your environment, Redfox Cybersecurity's ICS security assessment services include protocol-level traffic analysis and anomaly detection strategy.
For practitioners who want to build deep expertise in Modbus exploitation, coil manipulation, and ICS protocol analysis through structured labs, the Redfox Cybersecurity Academy offers hands-on OT security courses that go well beyond the basics.
EtherNet/IP is a more modern industrial protocol developed in the late 1990s and maintained by ODVA. It carries Common Industrial Protocol (CIP) messages over standard TCP/IP, using port 44818 for explicit messaging and port 2222 for implicit (real-time) messaging. Like Modbus TCP, EtherNet/IP in most deployed configurations has no authentication.
CIP organizes data into objects, each identified by a Class ID, an Instance ID, and an Attribute ID. When you interact with a PLC over EtherNet/IP, you are reading or writing specific attributes of specific object instances.
The EtherNet/IP adapter on the Koyo CLICK is disabled by default. Enable it through the CLICK programming software:
cpppo is a Python library for EtherNet/IP and CIP communication. It is well-maintained, scriptable, and capable of both read and write operations on CIP objects.
pip3 install cpppo
[cta]
Before writing anything to the PLC, enumerate its identity to confirm you are targeting the correct device and gather version information:
python3 -m cpppo.server.enip.list_services -vv -a 10.0.1.10 --list-identity
[cta]
The verbose output will include the device's product name, vendor ID, device type, product code, revision, and serial number. In our lab, this returns the identity string for the CLICK C0-10DRE-D. In a real engagement, this information helps you identify the specific firmware version and cross-reference known vulnerabilities or behavioral characteristics.
With the Class, Instance, and Attribute IDs recorded during the EtherNet/IP adapter configuration, read both the input and output data blocks simultaneously:
python3 -m cpppo.server.enip.get_attribute '@4/101/3' '@4/102/3' -S -a 10.0.1.10
[cta]
The -S flag enables simple mode. The output will show the current values of the XD input registers and the YD output registers. With all physical inputs off and no overrides applied, both blocks should return zero values.
To activate all four output lights by writing a value directly to the YD output register block, use the following command. The integer value 15 in binary is 00001111, which sets the four least significant bits to 1, corresponding to outputs Y1 through Y4:
python3 -m cpppo.server.enip.get_attribute '@4/102/3=(INT)15' -S -a 10.0.1.10
[cta]
After running this command, outputs Y1 through Y4 on the PLC should illuminate. Verify the write by reading the output register back:
python3 -m cpppo.server.enip.get_attribute '@4/102/3' -S -a 10.0.1.10
[cta]
The register will now return 15, confirming the write was accepted. Check the DataView screen in the CLICK software simultaneously and you will see all YD output addresses reflecting the ON state.
This entire interaction happened with no session authentication, no token exchange, and no encryption. A packet capture of this traffic in Wireshark would show every command and every response in fully readable plaintext.
The two protocols we demonstrated in this post, Modbus TCP and EtherNet/IP, account for a significant portion of all deployed industrial field device communication globally. Both were designed with the assumption that the network carrying them was physically isolated and trusted. That assumption is increasingly difficult to maintain as organizations connect OT systems to enterprise networks, cloud platforms, and remote access infrastructure.
The controls that actually protect these environments are external to the protocol. They include network segmentation that prevents IT-to-OT lateral movement, protocol-aware deep packet inspection firewalls that can detect anomalous Modbus or CIP transactions, unidirectional security gateways on critical process networks, and continuous OT network monitoring that baselines normal communication patterns and alerts on deviations.
None of those controls are implemented by default in most industrial environments. They require deliberate design, engineering effort, and regular validation.
The Redfox Cybersecurity Academy provides courses in ICS protocol analysis, OT network monitoring, and industrial penetration testing that give practitioners the skills to design and validate these controls. If your team is building an OT security program from the ground up, structured training combined with lab practice is the fastest path to competence.
In two posts, we have gone from physically wiring a PLC to remotely forcing its outputs through two different industrial protocols, neither of which asked us to authenticate. The Koyo CLICK C0-10DRE-D is not unusual in this regard. The same unauthenticated access patterns exist on Siemens S7 devices, Allen-Bradley MicroLogix controllers, Schneider Electric Modicon systems, and dozens of other platforms deployed across critical infrastructure worldwide.
The goal of this series is not to provide a recipe for attacks. It is to give defenders, architects, and security practitioners a concrete, technical understanding of what they are actually defending against. Abstract risk statements do not drive security investment the way a live demonstration does.
If you operate industrial systems and want to know exactly how exposed your environment is to the techniques described in this series, Redfox Cybersecurity offers ICS penetration testing engagements that use the same protocol-level tooling covered here, delivered by practitioners with real OT environment experience. The outcome is a clear, prioritized picture of your attack surface and a practical remediation roadmap.