By RUGERO Tesla (@404Saint).

Why I Started with the Foundations

When I finished my industrial protocol research series, I wanted to move closer to the systems using those protocols. I turned my attention to software PLCs and started investigating OpenPLC Runtime v4.

My first investigation quickly took me into runtime internals and the Linux environment supporting them. There was a lot to learn, but I eventually realised that I was spending more time understanding implementation details than answering the security questions I had originally set out to explore.

I stepped back and reorganised the project. Before investigating how software PLCs could be attacked, I wanted to understand what they actually are, how they operate, and how their different components fit together. That became Part I: Software PLC Foundations.

Understanding the Software PLC

A Programmable Logic Controller (PLC) is an industrial computing system responsible for monitoring inputs, executing control logic, and controlling outputs connected to a physical process. It receives information from devices such as sensors, evaluates that information against its programmed instructions, and sends commands to equipment such as motors, pumps, and valves.

Traditionally, PLC functionality has been delivered through dedicated industrial controller hardware. A typical controller brings together a CPU, memory, system software, communication interfaces, and connections to industrial I/O. Depending on the platform, these components may be integrated into a compact unit or arranged as a modular system.

A Software PLC (SoftPLC) implements the same fundamental control functionality through a software runtime operating on a compatible computing platform. That platform might be an industrial PC, an embedded computer, or another supported computing environment.

This contrast became the starting point for my first investigation. A software PLC still relies on physical hardware. What changes is how the controller functionality is implemented and how it relates to the underlying computing environment.

In a traditional PLC, the manufacturer generally delivers the controller as an integrated platform with its own firmware, execution environment, and supported hardware interfaces. In a SoftPLC, the runtime depends more directly on the host platform. The operating environment supplies computing resources and system services, while the runtime provides the environment for loading and executing the control application.

Traditional PLC vs. Software PLC Architecture

Figure 1. Architectural comparison of traditional hardware PLCs and software PLCs.

That separation introduces some interesting possibilities. Software PLCs can offer more flexibility in hardware selection and integration with other software systems. It also means that the host operating environment becomes part of the controller's architecture and something we need to understand when examining its security.

The deployment model adds another layer to this picture.

A software PLC can run directly on a host operating system, use a real-time operating environment, or operate inside a virtual machine or container. These arrangements are quite different. A virtual machine provides a guest operating system over virtualised hardware managed by a hypervisor. A container packages and isolates application processes while sharing the host operating system's kernel.

Software PLC Deployment Models

Figure 2. Common deployment environments for software PLC runtimes.

That difference is important. The isolation provided by a container is not the same as the separation between a virtual machine and its host. Access to devices, network interfaces, filesystems, and host resources also depends on how the environment is configured.

I also wanted to understand the assumptions around execution timing. There is a tendency to associate deterministic control exclusively with dedicated PLC hardware, as though running control software on a general-purpose platform automatically makes predictable execution impossible. The reality is more dependent on the complete configuration. Processor resources, scheduling, operating system behaviour, runtime implementation, I/O handling, and competing workloads all influence execution timing.

Virtualisation does not automatically rule out predictable execution either. Research examining virtual PLC implementations has demonstrated that comparable timing behaviour is achievable under particular tested configurations. That does not mean every virtualised deployment will meet every industrial timing requirement. The intended application and the complete system still have to be considered.

There is also the physical environment to account for. An ordinary computer running PLC software should not automatically be treated as equivalent to industrial-rated controller equipment. Environmental conditions, supported interfaces, power requirements, and equipment qualification remain relevant.

By this point, the contrast between a hardware PLC and a SoftPLC was becoming much clearer. I could also see why identifying the deployment environment was important before making assumptions about the security of a particular implementation.

From Control Logic to a Running System

The computing platform provides somewhere for the PLC runtime to operate, but the runtime needs a control application to execute.

Industrial control applications are commonly developed using the programming languages defined by IEC 61131-3. These include Structured Text (ST), Ladder Diagram (LD), and Function Block Diagram (FBD), alongside Sequential Function Chart (SFC) elements used to organise sequential operations.

The languages provide different ways of expressing control behaviour. Structured Text uses a textual syntax, Ladder Diagram represents logic through graphical electrical-style elements, and Function Block Diagram connects functional blocks to describe operations. SFC provides a way to organise sequences through steps and transitions.

The standard also defines how control applications can be organised through Program Organization Units (POUs). Programs, functions, and function blocks provide different building blocks for structuring application logic. A function block, for example, can retain internal state between executions, which makes it useful for representing operations that need to remember previous conditions.

Understanding these structures helped me move beyond thinking of a PLC program as one large block of instructions. A control application can contain several interconnected pieces of logic, each contributing to the behaviour of the overall system.

There is also a process between writing that logic and having it run on a controller. This is where the engineering lifecycle becomes important.

An engineering workstation is used to develop and configure the application. Depending on the platform, the project may then pass through compilation or code generation before being transferred to the target PLC runtime. The runtime loads the resulting application and makes it available for execution.

The engineering environment often remains involved after deployment. Engineers may use it to monitor variables, inspect controller status, modify application logic, or perform online changes where the platform supports them. Projects also need to be backed up, maintained, and recovered when something goes wrong.

PLC Engineering and Program Lifecycle

Figure 3. Simplified lifecycle of a PLC control application.

I found this part particularly important because the engineering project, generated application, and program currently loaded on the controller are related, but they are not necessarily identical artefacts. Platform-specific compilation, project formats, libraries, and deployment procedures all affect how an application moves through its lifecycle.

Interchange standards such as IEC 61131-10 also address the exchange of PLC project information using XML. That provides a basis for exchanging engineering data, although it does not guarantee that projects will behave identically across different runtimes and vendor environments.

Once the application reaches the runtime, another important contrast appears: how the program is executed.

A familiar PLC execution pattern is the scan cycle. The controller reads input states, evaluates the control logic, and updates outputs before repeating the cycle. This provides a useful way to understand basic PLC operation, although actual execution models vary. Some platforms support multiple tasks with different priorities, intervals, or triggering conditions.

PLC Program Execution Cycle

Figure 4. Simplified PLC scan cycle and interaction with the industrial process.

The runtime is responsible for coordinating this execution according to its implementation and configuration. Timing requirements become especially important here. A control application that produces the correct logical result may still be unsuitable for its intended process if it cannot execute within the required time.

This also explains why runtime scheduling, resource availability, and watchdog mechanisms matter. They contribute to how the controller behaves during normal operation and how it responds when execution does not proceed as expected.

Taken together, the programming model, engineering workflow, and execution environment describe how control logic travels from an engineering project into a running industrial controller. They also reveal several points where the integrity and availability of that application matter.

Looking at the System Through a Security Lens

By the time I reached the final investigation, the different pieces of the architecture were starting to connect.

A software PLC depends on its host platform. The host supports the runtime, the runtime executes the control application, and the application interacts with the industrial process through supported I/O and communication interfaces. The engineering environment provides another route through which the application is created, configured, and maintained.

Each relationship establishes a boundary worth examining.

Software PLC Security Boundaries

Figure 5. Architectural components and security boundaries in a software PLC environment.

At the platform level, operating system privileges, user accounts, filesystem permissions, and process isolation influence what the runtime and its supporting services can access. Where containers or virtual machines are involved, their configuration introduces additional isolation boundaries and dependencies.

At the application level, the integrity of the control program matters because its instructions determine how the controller responds to the process. The engineering workstation and program deployment workflow therefore deserve attention alongside the runtime itself. An assessment that only looks at the PLC host can miss important parts of how control logic is developed and delivered.

The communication side introduces another set of considerations. Management interfaces may support configuration, monitoring, and program deployment, while industrial communication interfaces allow the controller to exchange data with other systems. These interfaces have different purposes and may have different security requirements.

Availability also deserves attention. A software PLC may share processor time, memory, storage, and other resources with services running on the same host. Depending on the deployment, resource pressure or failure of a supporting component could affect runtime operation.

This is where the six investigations came together for me. The security boundaries of a software PLC cannot be understood by looking at the runtime in isolation. They emerge from the relationship between the deployment environment, the control application, the engineering process, and the interfaces connecting the system to its surroundings.

I used standards, manufacturer documentation, academic publications, and implementation documentation throughout Part I. OpenPLC Runtime v4 served as a useful practical reference when I needed to examine how some of these architectural ideas appear in an actual implementation. I kept its specific design separate from general SoftPLC concepts, since one implementation cannot represent every platform.

I also tried to keep documented behaviour, observations from the lab, and my own technical interpretations distinct. That contrast is important when drawing security conclusions. An exposed interface or a process running with elevated privileges can be relevant to an investigation, but its presence alone does not establish a vulnerability or demonstrate what an attacker can achieve.

The goal of this first part was to establish the system context needed to ask better security questions.

What's Next?

With Part I complete, the research moves into Part II: Attack Techniques.

The next stage will examine established techniques involving PLC program and configuration tampering, runtime manipulation, and execution disruption. The focus will be on understanding what these techniques can achieve against software PLC environments and gathering evidence of their actual impact.

The work from Part I gives me a much better starting point for those investigations. I also intend to retain and use the earlier OpenPLC implementation work wherever it helps answer a relevant security question.

Explore the Research

This article brings together the main ideas from Part I, but there's more behind it. I've documented the individual investigations, technical details, diagrams, and supporting material in the project repository.

You can explore the research on GitHub: 404saint/softplc-security-research.