0% found this document useful (0 votes)
9 views

2024 StructuredFuzzer= Fuzzing Structured Text-Based Control Logic Applications

Uploaded by

Yanshi Dong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

2024 StructuredFuzzer= Fuzzing Structured Text-Based Control Logic Applications

Uploaded by

Yanshi Dong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

electronics

Article
StructuredFuzzer: Fuzzing Structured Text-Based Control
Logic Applications
Koffi Anderson Koffi 1 , Vyron Kampourakis 2 , Jia Song 1 , Constantinos Kolias 1, * and Robert C. Ivans 3

1 Department of Computer Science, University of Idaho, 1776 Science Center Dr suite 304,
Idaho Falls, ID 83402, USA; [email protected] (K.A.K.); [email protected] (J.S.)
2 Department of Information Security and Communication Technology, Norwegian University of Science and
Technology, 2802 Gjøvik, Norway; [email protected]
3 Idaho National Laboratory, Idaho Falls, ID 83415, USA; [email protected]
* Correspondence: [email protected]

Abstract: Rigorous testing methods are essential for ensuring the security and reliability of industrial
controller software. Fuzzing, a technique that automatically discovers software bugs, has also proven
effective in finding software vulnerabilities. Unsurprisingly, fuzzing has been applied to a wide
range of platforms, including programmable logic controllers (PLCs). However, current approaches,
such as coverage-guided evolutionary fuzzing implemented in the popular fuzzer American Fuzzy
Lop Plus Plus (AFL++), are often inadequate for finding logical errors and bugs in PLC control logic
applications. They primarily target generic programming languages like C/C++, Java, and Python,
and do not consider the unique characteristics and behaviors of PLCs, which are often programmed
using specialized programming languages like Structured Text (ST). Furthermore, these fuzzers
are ill suited to deal with complex input structures encapsulated in ST, as they are not specifically
designed to generate appropriate input sequences. This renders the application of traditional fuzzing
techniques less efficient on these platforms. To address this issue, this paper presents a fuzzing
framework designed explicitly for PLC software to discover logic bugs in applications written in
ST specified by the IEC 61131-3 standard. The proposed framework incorporates a custom-tailored
PLC runtime and a fuzzer designed for the purpose. We demonstrate its effectiveness by fuzzing a
collection of ST programs that were crafted for evaluation purposes. We compare the performance
against a popular fuzzer, namely, AFL++. The proposed fuzzing framework demonstrated its
Citation: Koffi, K.A.; Kampourakis, capabilities in our experiments, successfully detecting logic bugs in the tested PLC control logic
V.; Song, J.; Kolias, C.; Ivans, R.C. applications written in ST. On average, it was at least 83 times faster than AFL++, and in certain cases,
StructuredFuzzer: Fuzzing Structured for example, it was more than 23,000 times faster.
Text-Based Control Logic Applications.
Electronics 2024, 13, 2475. https:// Keywords: PLC; fuzzing; structured text; AFL; AFL++; ICS
doi.org/10.3390/electronics13132475

Academic Editor: Manohar Das

Received: 11 May 2024


1. Introduction
Revised: 31 May 2024
Accepted: 15 June 2024
Industrial control systems (ICSs) include special devices such as supervisory control
Published: 25 June 2024 and data acquisition (SCADA) systems, distributed control systems (DCSs), and pro-
grammable logic controllers (PLCs) [1], and are designed to monitor and control processes
in critical infrastructures such as power plants, water treatment facilities, and oil refiner-
ies [2]. Focusing on PLC devices as enablers of operational technology (OT) [1], these
Copyright: © 2024 by the authors. devices were designed to support the automation of many processes in ICS with programs
Licensee MDPI, Basel, Switzerland. written in languages such as Structured Text (ST), ladder logic (LL), Sequential Function
This article is an open access article Chart (SFC), and Function Block Diagram (FBD) [3]. However, these programming lan-
distributed under the terms and guages are not widely used outside the ICS domain. As a result, the critical process of
conditions of the Creative Commons secure programming is often overlooked, leaving such critical devices vulnerable to log-
Attribution (CC BY) license (https://
ical errors. This, in turn, can lead to disastrous consequences. For example, in 2015, the
creativecommons.org/licenses/by/
Ukrainian power grid was attacked by the advanced persistent threat (APT) group known
4.0/).

Electronics 2024, 13, 2475. https://doi.org/10.3390/electronics13132475 https://www.mdpi.com/journal/electronics


Electronics 2024, 13, 2475 2 of 26

as Sandworm, using malware to shut down power to 225,000 customers [4]. In 2017, the
Triton malware was used to attack a petrochemical plant in Saudi Arabia [5]. Again, in 2021,
the US Cybersecurity and Infrastructure Security Agency (CISA) issued an alert warning
regarding the fact that some attackers had gained remote access to a water treatment facility
in Florida and attempted to poison the water supply [6].
The industry responded to such threats by increasing the security against external
threats targeting PLCs [7]. However, ensuring the security of PLCs is not solely about
defending against external attacks; it also involves rigorous testing down to the application
level, i.e., the control logic, to prevent internal errors leading to attacks or catastrophic
failures. In this direction, developing and implementing advanced fuzzing techniques for
PLCs, which can uncover security vulnerabilities and logical errors, is an essential step to
enhance the overall security capacity of ICSs.
Fuzzing, or fuzz testing, is an automated software testing technique that provides
unexpected or invalid input to a target program to reveal some unintended behavior [8].
Put simply, the primary objective of a fuzzer is to uncover bugs and other errors in software,
including security vulnerabilities. Fuzzing has been widely used to find vulnerabilities in
various software programs, including web browsers, operating systems, and network proto-
cols [9]. Fuzzing techniques may prove vitally important for enhancing cybersecurity in ICS.
An effective fuzzing approach for ICS aids in identifying and rectifying vulnerabilities, thus
contributing to the overall fortification of critical infrastructure and ensuring operational
continuity in numerous industries. Although conventional fuzzing techniques have yielded
significant results for common software systems, their effectiveness is substantially reduced
when applied to PLCs due to their distinct and complex architecture. In fact, the application
of fuzzing to PLCs is still in its infancy, mainly due to the unique challenges posed by the
specialized nature of ICS programming languages like ST, with the need to adapt the fuzz
inputs to their expected input structures during fuzzing while ensuring the safety of the
physical process. ST is not foreign to these challenges, as it is one of the most widely used
standardized ICS programming languages. In view of this, fuzzing techniques applied
to PLCs appear extremely constrained. Actually, the majority of the existing research is
focused on the communication protocols [10] and the I/O modules. Fuzzing of the control
logic applications has been largely ignored, with the handful of works in this area being
limited to specific PLC technologies such as Codesys [3]. These challenges are discussed
further in the challenges subsection of our methodology section (Section 3.1).
This paper introduces a novel framework for fuzzing PLC control logic applications
to address this shortcoming. Unlike the existing body of work that focuses on industrial
protocols [10–15], our approach is optimized for fuzzing ST-based control logic applications.
The proposed framework offers a general-purpose solution to fuzzing internal logic flaws,
indirectly enhancing the reliability and security of ICS devices against external cyber threats.
Among ICS programming languages, the proposed framework is designed for fuzzing
applications written in ST, which is widely used in PLCs. The primary aim of the proposed
framework is to detect logical bugs in ST programs that could potentially lead to security
vulnerabilities. Although not all bugs may directly result in security vulnerabilities, the
detection of these bugs is crucial for preventing potential security threats. The proposed
framework is designed to detect these bugs and enhance the security and reliability of ICS
devices. The framework includes a PLC runtime and a custom fuzzer that automatically
generates inputs to fuzz control logic applications written in ST. The main novelty of the
proposed framework lies in integrating the PLC runtime with a custom fuzzer designed to
detect logical bugs that violate a correctness specification regarding the inputs and outputs
of ST programs. The contributions of this paper are as follows:
• A fuzzing framework for PLC control logic applications written in ST specified by
the IEC 61131-3 [16] standard. It is worth noting that the IEC 61131-3 standard is
widely recognized in the industry and defines the syntax and semantics for textual and
graphical programming languages for PLCs such as ST and LL or Ladder Diagram
(LD). This standardization ensures that the programs are portable across different
Electronics 2024, 13, 2475 3 of 26

PLC vendors. Our work, therefore, extends fuzzing to a broad range of real-world
PLC applications. The novelty lies in the framework’s ability to guide the fuzzing
process to fuzz internal logical flaws, thus potentially augmenting the robustness
of ICS devices against external threats. This has been found crucial since ST is a
widely utilized language in PLC programming, yet effective fuzzing tools specifically
designed and optimized for such languages have been lacking. This framework can
be a valuable tool for detecting bugs and verifying the correctness of ST programs
based on a specification.
• A custom PLC runtime is integrated into the fuzzing process. This is unique, as it
provides contextual execution information for ST applications, permitting a more
targeted and efficient fuzzing process. This substantially improves upon conven-
tional techniques in which the runtime and fuzzing components frequently operate
in isolation.
• A custom fuzzer for effective input generation is explicitly designed to generate
inputs for fuzzing ST-based control logic applications. This fuzzer’s utility stems
from its competence in generating diverse inputs, considering the program’s context,
thereby enhancing the chance of uncovering vulnerabilities that might otherwise be
overlooked by a generic fuzzer.
• An evaluation of the efficacy of our framework is performed using a collection of
carefully crafted ST programs. This rigorous evaluation reinforces confidence in
our proposed framework’s utility and presents a benchmark for future research in
this area.
The remainder of this paper is organized as follows. Section 2 provides background
information on PLCs, fuzzing, and some motivating examples. Section 3 describes the
proposed fuzzing framework. Section 4 presents the experiments and results. Finally,
Section 5 presents the related work, and Section 6 concludes the paper.

2. Background
In this section, we provide background information on PLCs and fuzzing, along with
two examples that indicate the need for a novel fuzzing framework optimized for PLC
control logic applications.

2.1. Programmable Logic Controllers


PLCs are specialized industrial devices implementing solid-state control systems with
a user-programmable memory containing instructions for performing specific functions,
such as I/O control, logic, timing, counting, and arithmetic [17]. They are specialized
computers that are geared toward automating various manufacturing processes, utilities,
and infrastructure systems. PLCs are designed to perform control functions within harsh
industrial environments while withstanding extreme temperatures, vibrations, and noise
conditions, among others. In other words, PLCs are tasked with the real-time control and
monitoring of machinery and processes, making them indispensable components in various
sectors, including automotive manufacturing, water treatment facilities, oil refineries, and
power plants [3,5,18,19]. Given the crucial role of PLCs in critical infrastructures, their
security and reliability are decisive. Historically, PLCs were designed to focus on safety
and control, operating in isolated environments. However, the integration of PLCs with
modern IT technologies, including the Internet of Things (IoT), Artificial Intelligence (AI),
and cloud computing and analytics, has increased their exposure to a plethora of cyber
threats. For instance, the Stuxnet worm attack in 2010 [20] highlighted the vulnerability
of PLCs to sophisticated cyberattacks. It demonstrated that PLCs could be targeted by
malware designed to reprogram them and, therefore, disrupt sensitive industrial processes.
Echoing the significance of PLCs in various essential services, the high degree of their
reliability stems from their deterministic nature, executing control logic in a predictable
and cyclical manner according to a user-defined run cycle. This deterministic execution is
critical for the real-time response required in automation tasks.
Electronics 2024, 13, 2475 4 of 26

At their core, PLCs are governed by user-created control logic applications, often
called ladder logic or control logic, written in domain-specific languages defined by the IEC
61131-3 standard [16]. The most commonly used PLC programming languages include:
• Structured Text (ST): A high-level, block-structured language resembling Pascal
or C, used for complex tasks that may be cumbersome to implement with graphi-
cal languages.
• Ladder logic (LL): A graphical language representing control logic in a form that
emulates electrical relay logic, making it intuitive for electricians and technicians.
• Sequential Function Chart (SFC): This graphical programming language is used for
designing sequential control systems and complex program structures with multiple
distinct states and transitions.
• Function Block Diagram (FBD): Another graphical language that represents func-
tions between input and output variables using blocks connected by lines, similar to
electronic circuit diagrams.

2.2. Fuzzing
Fuzzing is a technique for automatically discovering vulnerabilities in software by
submitting some arbitrary combination of inputs to the test target to reveal how it re-
sponds [8,21]. Historically, first introduced by Barton Miller [22], fuzzing has since been
used extensively and in diverse ways towards identifying various vulnerabilities in nu-
merous kinds of software [9]. Based on the degree of understanding of the target program,
fuzzers can be classified as black-box [23], grey-box [24], and white-box [25], with each
technique being sequential, having more information available that can be leveraged for
the analysis of the test target. Otherwise, fuzzers can also be classified, based on the type of
input they create, into mutation based [26], generation based [12,27], and hybrid [28]. The
first category mutates existing inputs to create new inputs, while the second generates new
inputs from scratch from a specification, often based on a specific grammar. Hybrid fuzzers,
on the other hand, combine both mutation and generation-based fuzzing techniques. An-
other categorization is according to the type of the adopted optimization criteria that the
fuzzer utilizes. To this end, coverage-based [29] fuzzers use code coverage information
to guide the generation of new inputs, while feedback-driven [30] fuzzers use runtime
feedback, such as feedback from dynamic binary instrumentation, to guide the generation
of new inputs. Finally, evolutionary [31] fuzzers use evolutionary algorithms to guide the
creation of new inputs, considering the efficacy of the previous test cases while generating
the new test cases. In this paper, we consider mutation, generation, and coverage-based
fuzzing practices. These fuzzing techniques provide state-of-the-art performance [32].
In particular, we consider the American Fuzzy Lop (AFL) fuzzer [33], a coverage and
mutation-based fuzzer, and specifically the AFL++ variant [34], which incorporates several
improvements towards identifying vulnerabilities. It has been utilized to find critical bugs
in many open-source programs, including the Linux kernel.

2.3. Motivating Examples


Logical errors or bugs in control logic applications can lead to catastrophic failures
with far-reaching consequences. These errors are oftentimes the root causes of security
incidents and system malfunctions in critical infrastructures. However, traditional testing
approaches, including fuzzing, face challenges in detecting such errors, mainly due to
real-time constraints and physical process interactions that are the common denominator
among all control logic applications. Below are two of the most common scenarios that can
lead to bugs in control logic applications.
One prevalent type of bug in control logic applications occurs when the input values
are later subjected to incorrect arithmetic operations [35]. These wrong values are subse-
quently used in conditional statements, leading to unexpected behaviors that are often
difficult to detect or prevent in practice.
Electronics 2024, 13, 2475 5 of 26

Consider the example of a safety-critical automated temperature control system in a


power plant, illustrated in Listing 1. The program aims to regulate the reactor’s temper-
ature for safe and efficient operation. A logical bug, marked with 1 on line 14, involves
incorrect arithmetic operations that affect the branch conditions on lines 16, 19, and 22,
annotated with 2 , 3 , and 4 , respectively. This bug poses potential risks during the
plant’s operations.

Listing 1. Example of a logical bug in a control logic application for an automated tempera-
ture control system.
1 PROGRAM A u t o m a t e d T e m p e r a t u r e C o n t r o l
2 VAR
3 c u r r e n t T e m p e r a t u r e AT % ID 0 : REAL ; (* Current temperature in the reactor (
in Celsius ) *)
4 d e s i r e d T e m p e r a t u r e AT % ID 1 : REAL ; (* Desired operational temperature ( in
Celsius ) *)
5 c o o l i n g S y s t e m A c t i v a t e d AT % QX 0 . 0 : BOOL ; (* State of the cooling system *)
6 h e a t i n g S y s t e m A c t i v a t e d AT % QX 0 . 1 : BOOL ; (* State of the heating system *)
7 alertRaised AT % QX 0 . 2 : BOOL ; (* Flag for raising an alert *)
8 END_VAR
9
10 VAR
11 t e m p e r a t u r e D i f f e r e n c e : REAL ; (* Difference between current and
desired temperature *)
12 END_VAR
13
14 t e m p e r a t u r e D i f f e r e n c e : = c u r r e n t T e m p e r a t u r e - d e s i r e d T e m p e r a t u r e ; (* 1
15 Logical Bug : Incorrect arithmetic operations in temperature control logic *)
16 IF t e m p e r a t u r e D i f f e r e n c e > 1 0 THEN (* 2 Bug : missing absolute value operator can
lead to the temperature going below the desired level by more than 1 0 degrees *)
17 c o o l i n g S y s t e m A c t i v a t e d : = TRUE ;
18 h e a t i n g S y s t e m A c t i v a t e d : = FALSE ;
19 ELSIF t e m p e r a t u r e D i f f e r e n c e > 0 THEN (* 3 Bug : similar to 2 ( missing absolute value
) *)
20 c o o l i n g S y s t e m A c t i v a t e d : = FALSE ;
21 h e a t i n g S y s t e m A c t i v a t e d : = TRUE ;
22 ELSE (* 4 Bug : Deactivating both systems when the temperature is within the
threshold *)
23 c o o l i n g S y s t e m A c t i v a t e d : = FALSE ;
24 h e a t i n g S y s t e m A c t i v a t e d : = FALSE ;
25 END_IF ;
26
27 (* Raise an alert if the temperature deviates significantly from the desired level *)
28 IF ABS_REAL ( t e m p e r a t u r e D i f f e r e n c e ) > 2 0 THEN
29 alertRaised : = TRUE ;
30 ELSE
31 alertRaised : = FALSE ;
32 END_IF ;
33 END_PROGRAM

More specifically, the principal error involves neglecting to apply the absolute value
operation (ABS_REAL) in the evaluation of the temperature difference used in the condition
used on line 16, noted with 2 , leading to both cooling and heating systems deactivating
when not intended on lines 21 and 22. Figure 1 illustrates the Control Flow Graph (CFG) of
the program and the path taken by alternative inputs, including ones that trigger the bug.
In the example, the desired temperature is 500 ◦ C. When the current temperature is 520 ◦ C,
the temperature difference is 20 ◦ C, which is within the acceptable range. Similarly, a
current temperature of 505 ◦ C leads to a temperature difference of 5 ◦ C still within the valid
range. However, when the current temperature is 480 ◦ C, the difference is −20 ◦ C outside
the acceptable range. The correct approach would use the absolute value to ascertain the
true magnitude of deviation from the desired temperature, ensuring that temperature
calibration is applied as necessary to keep it within the acceptable range. Additionally,
either the cooling or heating systems should remain active, ideally, to maintain the desired
temperature. However, the control logic deactivates both systems when the temperature
is within the allowed threshold. A more prudent implementation would deactivate the
cooling system when the temperature is above the threshold and activate the heating
system when it is below to maintain the desired temperature. Overall, such a mistake in
Electronics 2024, 13, 2475 6 of 26

logic could lead to temperature fluctuations within the reactor, potentially impacting the
safety and efficiency of the power plant operation.

Figure 1. Illustrative CFG of the automated temperature control example.

Another common source of control logic bugs is when the program’s outputs are
assigned erroneous values. Ideally, values of certain variables should be within acceptable
ranges according to the specifications of the particular application. However, this cannot
always be trivially enforced in the code during the declaration or the assignment of a
variable, thus allowing typos to occur during the development time and subsequently
evolve into bugs during runtime.
For example, variables corresponding to actuator states are typically defined so as
REAL to achieve maximum precision. However, nothing prohibits the developer from
explicitly assigning the variable with a negative value by accident. This, in theory, is still
valid because negative values fall within the range of real numbers, and no alert will be
triggered during development time. However, in certain applications, negative values may
be incorrect.
Listing 2 is an example of a control application of a nuclear power plant’s automated
reactor control system. The system regulates the coolant flow rate and control rod posi-
tion within a reactor to ensure safe and efficient operation. In particular, based on the
reactor mode of operation, described by the variable reactorMode, the statement on line
10 redirects the control flow of the program to define appropriate actions, e.g., regarding
the coolant flow and the positioning of the control rods. In this example program, there
are two bugs involving the incorrect adjustments of the control rod position and coolant
flow rate, marked 1 and 2 , which could lead to operational risks. The first bug, marked
1 , involves the control rods not being fully inserted during shutdown mode as shown in
the assignment statement on line 20 in the code. The second bug, marked 2 , is that the
coolant flow rate is not maximized during the emergency mode as seen with the assignment
statement on line 23 in the code. As an example, correct values for the control rod position
and coolant flow rate for the shutdown and emergency modes, respectively, are 100% and
50.0 L per second. In the context of this example, these values can be considered safe and
optimal for the reactor’s operation during these modes.
Both the aforementioned examples demonstrate the need for rigorous testing methods
to ensure the security and reliability of control logic applications. In this respect, we present
a framework, dubbed StructuredFuzzer, specifically designed to fuzz PLC control logic.
A PLC runtime and fuzzer are also contributed to the framework. We demonstrate the
effectiveness of our approach by fuzzing a collection of carefully designed ST programs of
variable complexity using our custom-tailored fuzzer developed for the purpose. To com-
pare with existing fuzzers, we also fuzzed the same set of ST programs using AFL++ fuzzer.
Electronics 2024, 13, 2475 7 of 26

Listing 2. Example of a logical bug in a control logic application for an automated reactor
control system.
1 PROGRAM A u t o m a t e d R e a c t o r C o n t r o l
2 VAR
3 reactorMode AT % IW 0 : INT : = 0 ; (* Operational mode of the reactor ( 1
for startup , 2 for normal , 3 for shutdown , 4 for emergency ) *)
4 c oo l an tF l ow Ra t e AT % QD 0 : REAL ; (* Coolant flow rate ( in liters per second
) *)
5 c o n t r o l R o d P o s i t i o n AT % QD 1 : REAL ; (* Position of control rods ( 0 % to 1 0 0 % ,
where 1 0 0 % is fully inserted ) *)
6 ala rmActi vated AT % QX 0 . 0 : BOOL ; (* State of the alarm system *)
7 END_VAR
8
9 (* Logical Bugs : Inappropriate control rod and coolant flow adjustments for some
reactor modes *)
10 CASE reactorMode OF
11 1 : (* Startup mode *)
12 c oo l an tF l ow Ra t e : = 3 0 . 0 ; (* Moderate coolant flow *)
13 c o n t r o l R o d P o s i t i o n : = 2 0 . 0 ; (* Partially withdrawn control rods *)
14 2 : (* Normal operation mode *)
15 c oo l an tF l ow Ra t e : = 5 0 . 0 ; (* High coolant flow *)
16 c o n t r o l R o d P o s i t i o n : = 5 0 . 0 ; (* Halfway inserted control rods *)
17 3 : (* Shutdown mode *)
18 c oo l an tF l ow Ra t e : = 2 0 . 0 ; (* Low coolant flow *)
19 (* Control rods should be fully inserted for shutdown *)
20 c o n t r o l R o d P o s i t i o n : = 5 0 . 0 ; (* 1 Bug : Incorrectly halfway inserted control
rods *)
21 4 : (* Emergency mode *)
22 (* Coolant flow should be maximized in emergency mode *)
23 c oo l an tF l ow Ra t e : = 3 0 . 0 ; (* 2 Bug : Insufficient coolant flow for emergency
*)
24 c o n t r o l R o d P o s i t i o n : = 1 0 0 . 0 ; (* Fully inserted control rods *)
25 ala rmActi vated : = TRUE ;
26 ELSE
27 (* Default safe state in case of an unrecognized mode *)
28 ala rmActi vated : = TRUE ;
29 c oo l an tF l ow Ra t e : = 0 . 0 ;
30 c o n t r o l R o d P o s i t i o n : = 1 0 0 . 0 ; (* Fully insert control rods *)
31 END_CASE ;
32
33 IF reactorMode <> 4 THEN
34 ala rmActi vated : = FALSE ;
35 END_IF ;
36 END_PROGRAM

3. Proposed Fuzzing Framework


In this section, we present challenges in fuzzing PLC applications and propose a
fuzzing framework for addressing them.

3.1. Challenges in Fuzzing PLCs Control Applications


In this section, we elaborate on the most prominent challenges when it comes to
fuzzing PLC control applications written in ST. More specifically, we have the following.
PLC Programming Languages and Runtime: Despite its potential, fuzzing has been under-
utilized in the ICS domain, mainly due to the unique challenges posed by the specialized
nature of ICS programming languages and the real-time constraints under which these
systems operate. PLC control binaries are compiled into specific formats for each vendor,
which makes it tedious to apply a general analysis technique to secure them. The lack of
standardization of the PLC runtime environments greatly exacerbates this issue. Specifi-
cally, the runtime is the software environment, running as a process of the PLC operating
system (OS) in which the control logic is executed. It is responsible not only for executing
the applications but also for interfacing with the physical I/O modules. Therefore, the
lack of standardization of the runtime environments makes it challenging to develop a
general-purpose fuzzer for control logic applications. Additionally, the runtime is itself
often proprietary and closed-source, rendering the development of a fuzzer that can work
across different PLC vendors even more difficult. Since the PLC runtime is often tightly
integrated with the I/O modules, dissociating and fuzzing each one independently is
quite cumbersome. Finally, the runtime is often optimized for real-time performance,
Electronics 2024, 13, 2475 8 of 26

which makes it nearly impossible to fuzz the control logic without a degradation in the
performance of the PLC [3].
Complex Input Structures: Unlike traditional programming languages like C, ST requires
explicit memory and I/O addressing during variable declaration as shown in Figure 2.
Nevertheless, memory addressing is specific to the hardware of the target device in ST, in
contrast to C, which is generally portable.

Figure 2. Comparison of variable declarations in ST and C programming languages. Notice


the presence of an explicit memory address that makes the declaration in ST non-trivial.

Moreover, conventional fuzzers like AFL++ are not configured to understand structure
in values assigned to variables. In most cases, that is not an issue in C-like programs.
However, in ST programs, altering the value of a variable randomly permits the alteration
of the memory address portion, which in turn may lead to invalid memory locations for the
target hardware, with high probability as illustrated in Figure 3. These generated values
are downright rejected by the runtime. Although valid values may be eventually generated
and utilized by the fuzzer, a significant amount of time is wasted in producing meaningless
values. Bearing this in mind, it is rather clear that conventional fuzzers are inefficient when
it comes to ST programs.

Figure 3. ST Input structure and example of mutated inputs generated by AFL++ and our
fuzzer for the automated temperature control ST program. The mutated parts of the inputs
are highlighted in blue. Notice how AFL++ is free to mutate the address part of the inputs,
while our fuzzer is restricted to mutating the actual values.

Nevertheless, it is possible to compile ST programs directly (i.e., without a runtime)


to the C equivalent binary to avoid this issue. However, in this case, the behavior of the
resulting binary might not be close to the actual behavior of the control application. This
is because, without a PLC runtime, the resulting ST binary is not bound by the PLC run
cycle and the I/Os and their response times. Consequently, many types of bugs might be
missed, e.g., bugs related to the interaction with the physical environment. We address
these issues with a custom input generation technique that utilizes static code analysis on
Electronics 2024, 13, 2475 9 of 26

the ST program to generate fuzz inputs that conform to the input structure expected by the
ST binary.
Physical Process Interactions and Safety Concerns: PLC roles typically involve perceiving
changes in the physical environment and controlling or influencing them. This means
that ST applications frequently interact with physical processes, which directly affects the
status of machinery. Generally, during the fuzzing process, valid inputs are extensively
altered, potentially leading to software crashes of the test target. However, in cases where
the target interacts with a physical process, such inputs may have calamitous consequences.
Therefore, to maintain the system’s safety and reliability, it is critical to identify these issues
in advance, possibly even offline, without interacting with the environment.
In this regard, the suggested framework allows users to define beforehand what
constitutes correct behavior through a mechanism known as a fuzzing harness, which is
subsequently utilized by the fuzzer to identify harmful side effects and logical errors. Note
that this is performed in a virtual setting that is decoupled from hardware components.
Unlike physical environments where hardware components are tightly integrated and often
depend on each other’s outputs, our framework enables the independent examination
of different system components and the generation of arbitrary inputs as needed. This
capability supports concurrent fuzzing as shown in Figure 4. Note that fuzzing the ST
binary using our framework is possible in both real and controlled environments, as well
as in virtual settings.

Figure 4. Fuzzing the automated temperature control ST program in a virtual environment


enables parallel fuzzing compared to a physical/controlled environment. Note that both
the heating and cooling systems can be fuzzed independently.

In this context, the proposed PLC runtime provides a safe environment for fuzzing,
allowing the user to test control logic applications without risking any actual system.
Furthermore, the proposed runtime simulates a generalized PLC environment, enabling
any fuzzer to interact with the control logic applications as if they were running on a
real PLC. Equally important, it can also be modified or extended to offer a more faithful
simulation of the physical environment, such as the behavior of I/O modules and sensors.
The choice of focusing on ST was driven by several reasons. First, ST, specified by the
IEC 61131-3 standard, is a widely used language for PLC applications and shares many
similarities with high-level languages like C, which simplifies our development process and
enhances the general understanding and applicability of our method [16]. Secondly, while
non-textual languages such as LD are commonly utilized in ICS, they also harbor additional
complexities not present in ST, primarily due to their inherent graphical nature. In the case
of LD, its visual component could potentially complicate the fuzzing process and pose
Electronics 2024, 13, 2475 10 of 26

challenges in effectively crafting fuzzed inputs. Notwithstanding, we fully acknowledge


the relevance of LD and other IEC 61131-3 specified languages in industry, and we see
the extension of our proposed framework to other ICS languages, including LD, as an
important future work direction. Therefore, while our novel fuzzing framework currently
focuses on ST, future work should enhance this platform’s versatility to cover additional
languages, such as LD, used in PLC programming.

3.2. Proposed Framework Overview


We introduce StructuredFuzzer, a fuzzing framework that describes the effective imple-
mentation of ST-based PLC applications fuzzing, also bearing in mind potential remedies
for the challenges discussed in Section 3.1. As illustrated in Figure 5, the framework is
a four-step process comprising (1) the fuzzing harness specification, (2) the ST program
compilation, (3) the fuzzing input corpus generation, and (4) the actual fuzzing of the PLC
control logic.

Figure 5. The proposed fuzzing framework.

Step 1: Specifying a Fuzzing Harness (Optional): The first step involves creating a harness,
i.e., a user-defined set of specifications regarding the correctness of the target ST programs.
In particular, the harness should provide input restrictions that are considered valid when
certain outputs are observed, or the system is in certain states. If these are violated, then it
is assumed that it is due to a bug. Therefore, a code for signaling a fuzzer about this should
exist. The latter can be achieved through code that aborts the execution of the program or
emulates a crash. Thus, the harness can be implemented in C to express some violations of
the desired program’s behavior (specifications) as assertion failures. Listing 3 provides an
example of a harness for the automated temperature control system application. Precisely,
it specifies invalid states or conditions (violations) as crashes that the fuzzer can detect, i.e.,
those that deviate from the specifications 1 to 4 . The above-described step is optional,
and it typically occurs when the fuzzing process is meant to be conducted offline and in
the absence of a controlled environment.
The example harness, depicted in Listing 3, is a C program that signals to a fuzzer
when to detect a crash using the abort() statements. It defines the desired behavior as
specifications marked by 1 to 4 . These conditions are translated into IF statements using
the PLC I/O. This provides a flexible way to test for the correctness of the control logic and
enforce secure behavior.
In this context, the runtime is simply a set of linked C programs that comprise (a) the
C version of the ST program and (b) a set of functions for interfacing with the hardware
components of the system, e.g., I/O and network modules. As depicted in Figure 6, when a
harness is provided, the PLC runtime binary includes the default networking module and
an I/O adapter module instead of the default I/O module, which enables the interaction
with the physical I/Os. The I/O adapter replaces the interactions with the physical I/Os
Electronics 2024, 13, 2475 11 of 26

with the interactions with the fuzzer. In this way, the fuzzer can provide inputs to the
control logic and receive outputs from it.

Listing 3. Example of a harness for the automated temperature control system application
for a desired temperature of 500 ◦ C.
1 # include " iec_types . h "
2 # include " iec_std_lib . h "
3 # include < stdio .h >
4 # include < stdlib .h >
5
6 void config_init__ ( void ) ;
7
8 extern REAL * __ID 0 , * __ID 1 ; // External references to c u r r e n t T e m p e r a t u r e and
desiredTemperature
9 extern BOOL * __QX 0 _ 0 ; // External reference to c o o l i n g S y s t e m A c t i v a t e d
10 extern BOOL * __QX 0 _ 1 ; // External reference to h e a t i n g S y s t e m A c t i v a t e d
11 extern BOOL * __QX 0 _ 2 ; // External reference to alertRaised
12
13 void fuzzer _harne ss ( void ) {
14 printf ( " [ + ] Current Temperature ( ID 0 ) = % f \ n " , * __ID 0 ) ;
15 printf ( " [ + ] Desired Temperature ( ID 1 ) = % f \ n " , * __ID 1 ) ;
16 printf ( " [ + ] Alert Raised ( QX 0 . 0 ) = % s \ n " , * __QX 0 _ 0 ? " TRUE " : " FALSE " ) ;
17
18 // 1 The desired temperature should be 5 0 0 degrees Celsius
19 if (* __ID 1 != 5 0 0 ) {
20 printf ( " Test failed : Incorrect settings for desired temperature \ n " ) ;
21 abort () ;
22 }
23
24
25 // 2 When cooling = TRUE and heating = FALSE , the current temperature should be
greater than 5 1 0 , otherwise abort
26 if (* __QX 0 _ 0 && !* __QX 0 _ 1 ) {
27 if (* __ID 0 < 5 1 0 ) {
28 printf ( " Test failed : Incorrect settings for heating and cooling systems \ n
");
29 abort () ;
30 }
31 }
32
33 // 3 When cooling = FALSE and heating = TRUE , the current temperature should between
4 9 0 and 5 1 0 , otherwise abort
34 else if (!* __QX 0 _ 0 && * __QX 0 _ 1 ) {
35 if (* __ID 0 >= 4 9 0 && * __ID 0 <= 5 1 0 ) {
36 printf ( " Test failed : Incorrect settings for heating and cooling systems \ n
");
37 abort () ;
38 }
39 }
40
41 // 4 When cooling = FALSE and heating = FALSE , the current temperature should be 5 0 0
, otherwise abort
42 else {
43 if (* __ID 0 != 5 0 0 ) {
44 printf ( " Test failed : Incorrect settings for heating and cooling system \ n "
);
45 abort () ;
46 }
47 }
48 }

Step 2: ST Program Compilation: The second step of the framework depicted in Figure 5
is to transcode the ST programs to the corresponding PLC runtime. In our implementation,
the compilation process is performed with the aid of Matiec iec2c compiler [36]. It is a
source-to-source compiler that compiles ST programs to C. This compiler is used by many
open-source projects such as OpenPLC [37].
Moreover, the harness can be omitted if the aim of the fuzzing process is not to find
bugs in the control logic. When the harness is not provided, the program is fuzzed without
any restrictions and executes as it would on actual hardware. In this particular case, the
fuzzer is expected to find bugs mainly in the runtime. Unlike typical workflows, we also
provide a wrapper for the compiler to consider the harness as an additional input. By
doing so, assertions are injected into the produced binary. These cause the fuzzer to trigger
Electronics 2024, 13, 2475 12 of 26

crashes for illegal conditions. Finally, the PLC runtime is responsible for executing the
control logic, also capable of receiving inputs from the fuzzer.

Figure 6. Compilation process of the ST program to the PLC runtime.

Step 3: Input Generation: The third step involves generating the initial fuzzing inputs
(seeds). This step is critical since using seeds from a previous fuzzing (i.e., one that was not
provided with initial seeds) of the same program can be ineffective. The importance of good
initial seeds for fuzzing has been demonstrated by prior studies [38,39]. For this reason,
we developed a static code analysis (SCA) tool for generating good initial seeds. It utilizes
the Tree-Sitter library to parse the ST program. Parsing the ST provides a more reliable
way to perform various program analyses, unlike regular expressions, which are generally
error-prone. Tree-Sitter [40] is a parser generator tool as well as an incremental parsing
library previously used for similar purposes [41]. To parse the programs with Tree-Sitter, a
grammar for the target language is required. However, there is a lack of extensive research
on grammar specifically tailored for ST programming. To address this shortcoming, we
construct a Tree-Sitter grammar for ST that enables us to build an abstract syntax tree (AST)
from an ST source file. We utilize the AST in our analysis to extract the types and addresses
of the variables used in the programs as shown in Algorithm 1. Importantly, this step is
required to ensure the fuzzer generates inputs compatible with the types and addresses
used within the ST program.

Algorithm 1 Algorithm for automatic fuzzing harness generation.


Require: st_program ▷ ST program source file
Ensure: c_input_adapter ▷ Source file for the input adapter program
1: ast ← tree_sitter_parse (st_program )
2: variables ← ∅ ▷ Initialize the list of variables in the ST program
3: for node ∈ visit ( ast.root_node ) do
4: if node.type = ”variable_declaration” then
5: variable_name ← get_node_value(node.children[1])
6: variable_type ← get_node_value(node.children[0])
7: variable_address ← get_node_value(node.children[2])
8: variables.append(variable_name, variable_type, variable_address)
9: end if
10: end for
11: c_input_adapter ← generate_c_input_adapter (variables )
12: return c_input_adapter
Electronics 2024, 13, 2475 13 of 26

During the variables extraction, the algorithmic procedure traverses the nodes of the
AST from the root node to the leaves as depicted in Figure 7. If a node contains a variable
declaration or definition, the variable name, type, and address are extracted into a set
of PLC variables as described in Algorithm 1. These variables are subsequently fed to a
function for generating the I/O adapter program (written in C) that makes them available
to the fuzzer as depicted in Algorithm 2.

Algorithm 2 Function generate_c_input_adapter (Generate PLC Input Adapter Function).


Require: variables ▷ A list of PLC input variables.
Ensure: input_adapter ▷ C source file of the input adapter program
1: function generate_c_input_adapter(variables)
2: input_adapter ← c_headers ▷ Initialize the C source file with the PLC runtime C
headers file
3: set_plc_input ← ∅ ▷ Source of the function for setting PLC inputs from C
4: for var ∈ variables do
5: cast_type ← get_type_cast(var.type) ▷ Casting from PLC to C variables
6: append(set_plc_input, var.name, var.address, cast_type) ▷ Add PLC input to set
7: end for
8: input_adapter ← f ormat(set_plc_input) ▷ Format to a C function file
9: return input_adapter
10: end function

The algorithm takes the list of variables for the generation of a C function. For each
variable, the procedure determines its C equivalent type from the ST type. Consequently,
according to line 6 of Algorithm 2, a piece of C code is added to the set_plc_input()
function for declaring and setting the value of the variable based on its name, address,
and casting type. After adding all the variables of the ST program to the function, the C
program is finalized, incorporating the I/O adapter program and including the necessary
headers to make the function accessible from the PLC runtime.

Figure 7. Example of an AST generated by Tree-Sitter for the variable declaration of


reactorMode in the automated reactor control program. Notice that Algorithm 1 would
traverse each variable_declaration node to extract the variable name, type, and address from
its children.

Step 4: Fuzzing: The final step is fuzzing the control logic using the proposed PLC
runtime along with a fuzzer. To do that, we implemented a custom fuzzer in Rust based
on the LibAFL [42] fuzzing library. In further detail, LibAFL is a popular library that
Electronics 2024, 13, 2475 14 of 26

provides a set of utilities for building custom fuzzers. It separates fuzzers into several
modules, each providing core functionalities such as mutators, generators, feedbacks,
observers, monitors, and executors. The LibAFL plugin-like system enables adding new
components or reusing existing modules to construct fuzzers. To this extent, the proposed
fuzzer reuses some core functionalities present in AFL++ but with a new custom mutator,
namely, PLCRandomInputMutator, designed specifically for fuzzing control applications.
As depicted in Algorithm 3, the mutator is fed with inputs derived from the provided
corpus, the current state of the fuzzer, and the index of the current fuzzing stage. At the
end of the procedure, the mutated inputs and a new state of the fuzzer are expected to
be output. In detail, first, a random number generator based on the state of the fuzzer is
initialized. Next, the current inputs are parsed into a set of ST variable structures. If the
parsing fails, i.e., the list of variables is empty, the fuzzer state is set to Skipped, indicating
a failed mutation; otherwise, it is set to Mutated to indicate a successful mutation. Note
that for each variable in the set of PLC variables, the mutation procedure determines its
size (in bits) for generating alternative inputs, using the random number generator from
the fuzzer’s state to generate random values for the control logic inputs. Following, the
fuzzer utilizes the mutation procedure (mutate) and the PLC runtime to fuzz the native
control logic code. The execution of the program is monitored during fuzzing of the control
logic until a STOP (e.g., SIGTERM or SIGKILL signals in Linux) signal is received. If the
harness is provided during the compilation of the binary, the fuzzer would detect the
crashes (e.g., signaled via an abort() statement). In the same vein, during fuzzing, the
runtime binary would execute the code of the harness on each execution with the mutated
inputs. Alternatively, a fuzzer such as AFL++ can be coupled with the proposed runtime to
fuzz the control application.

Algorithm 3 PLCRandomInputMutator (Random Input Generation for Fuzzing).


Require: state ▷ Fuzzer’s state
Require: input ▷ Current input to fuzz
Require: stage_idx ▷ Current fuzzing stage index
Ensure: mutated_inputs ▷ Mutated PLC inputs
Ensure: new_state ▷ New fuzzing state to indicate whether the mutation was applied
1: procedure M UTATE (state, input, stage_idx)
2: mutated_inputs ← ∅ ▷ Initialize the mutated inputs
3: rng ← init_rng(state) ▷ Initialize the random number generator from state
4: variables ← parse_input(inputs) ▷ Get the C variables from ST
5: if variables ∈ ∅ then
6: new_state ← States.Skipped
7: end if
8: for var ∈ variables do
9: if var.type.size = 1 then ▷ Variable size is 1 bit
10: input_value ←!var.value ▷ Flip boolean value
11: else if var.type.size = 8 then ▷ Variable size is 8-bit (byte)
12: input_value ← generate(rng, 8) ▷ Generate random 8-bit
13: else if var.type.size = 16 then ▷ Variable size is 16-bit (word)
14: input_value ← generate(rng, 16) ▷ Generate random 16-bit
15: else if var.type.size = 32 then ▷ Variable size is 32-bit (double)
16: input_value ← generate(rng, 32) ▷ Generate random 32-bit
17: else if var.type.size = 64 then ▷ Variable size is 64-bit (long)
18: input_value ← generate(rng, 64) ▷ Generate random 64-bit
19: end if
20: mutated_inputs.append(input_value)
21: new_state ← States.Mutated
22: end for
23: return new_state, mutated_inputs
24: end procedure
Electronics 2024, 13, 2475 15 of 26

4. Experimental Evaluation
In this section, we present the experimental evaluation of the proposed framework,
providing also a detailed discussion revolving around its key findings.

4.1. Experimental Setup


To evaluate our framework, we created a collection of ST programs that implement
common PLC control logic application scenarios. Note that every program uses common
programming structures, such as if statements, case statements, etc. The programs were
created with incremental levels of complexity across several characteristics, including var-
ious branch depths and branch widths. More precisely, three of them exhibit increasing
branch depth, three showcase increasing branch widths, and three demonstrate progres-
sively complex branch conditions. Additionally, we designed 10 more complex programs
resembling real-world PLC control logic. The list of programs and their descriptions are
given in Table 1.

Table 1. Description of the ST programs used in the experiments.


Programs Characteristics Description
Depth 1 to 3 Branch Depth Programs with increasing branch depths
Width 1 to 3 Branch Width Programs with increasing branch widths
Condition 1 to 3 Branch Condition Programs with various branch conditions complexities
Complex 1 to 10 Real-world Program Programs resembling real-world PLC programs

Recall that fuzzing incorporates random processes, often leading to different results in
each run. To ensure the results of the evaluation are accurate, we fuzzed each test subject
of Table 1 multiple times. More specifically, with the help of the HPC, we performed
the fuzzing of the individual programs 20 times for 24 h, each on a node of a computing
cluster. All executions were performed in the Falcon high-performance computing (HPC)
cluster [43]. Each fuzzing task was given 4 GB of RAM and 4 CPUs. The fuzzers utilized
for comparison purposes include our custom fuzzer and stock AFL++. One may speculate
that the input generation process may be the main contributor to any speedup. To provide
a more comprehensive answer, we also considered the case of AFL++ when utilizing
the proposed input generation technique for creating its initial fuzzing input corpus as
presented in the third step of the proposed framework (See Section 3.2). From now on,
the latter test platform will be referred to as AFL++/IG. To ensure the results would be
comparable, we applied filters to include only executions that lead to valid crashes (bugs).
Overall, on average, 6 to 18 crashes were observed per program evaluation cycle.

4.2. Results and Discussion


We compared the results of the three fuzzers, AFL++, AFL++/IG, and our fuzzer,
to quantify their crash-finding capabilities and efficiency based on the average time and
number of executions required to find the logic bug. We also computed and reported the
speedup achieved. We define speedup as the ratio of the average time taken by the target
fuzzer (e.g., AFL++) to the average time taken by our custom-made fuzzer.
As a general remark, the results given in Table 2 show that the proposed fuzzer
significantly outperforms both AFL++ and AFL++/IG. Based on the results, it is observed
that (a) the proposed fuzzer can locate the bug in less than a second consistently for all test
cases regardless of the complexity of their structure, (b) it usually finds the bug by at least
two (frequently three and four) orders of magnitude faster than AFL++ and AFL++/IG.
For example, the proposed fuzzer takes only 0.21 s to find the bug in the program with
a branch width of 1 as opposed to 3954.17 and 3870.00 s, which AFL++ and AFL++/IG
require, respectively. Similarly, while AFL++ and AFL++/IG take 1509.67 and 887.17 s to
find the bug in a program with a branch depth of 3, the proposed fuzzer only needs 0.17 s.
Notably, a substantial improvement in terms of performance across virtually all the
considered test cases is observed even in the case of the AFL++/IG fuzzer, where we simply
Electronics 2024, 13, 2475 16 of 26

incorporate the proposed input generation into AFL++ to create the initial fuzzing input
corpus. The performance increase in AFL++/IG is up by two orders of magnitude and a
factor of two in the worst case when compared to traditional AFL++. With reference to
Table 2, this performance rectification can be observed in all the tested programs except the
ones of Width 3 and Depth 2, where AFL++/IG takes more time to find the bug compared
to AFL++. For example, AFL++/IG requires 2298.20 and 427 s, while AFL++ needs 1114.47
and 358 s, respectively, in Width 3 and Depth 3. Especially for all the considered real-world
programs, AFL++/IG always outperforms AFL++ by a factor of ×63 and ×18, on average.
Particularly, the results depicted in Figure 8 confirm the efficiency of the proposed
fuzzer vis-a-vis the AFL++ and AFL++/IG fuzzers. In detail, the y-axis of the figures
illustrates the time required to discover logical errors, while the x-axis indicates the vary-
ing complexity levels of the different tested ST programs. It is easy to observe that our
fuzzer consistently exhibits superior performance compared to AFL++ and AFL++/IG as
evidenced by the lower average times across all test cases. Notably, for all the considered
real-world programs and those with various branch depths, widths, and condition test
cases, our fuzzer demonstrates a distinctive cutback in the interquartile range (IQR).
Moreover, in the results with reference to Figure 8, only a few outliers were observed,
affirming a consistent performance across different programs. Specifically, the outliers
observed for the Depth and Width test cases (top and second figures of Figure 8) indi-
cate that although our input generation consistently delivers strong performance—on
average—when combined with AFL++, additional mutation strategies are required to im-
prove the results on the edge cases. This gap in performance compared to our fuzzer once
again underscores the importance of the custom mutator. Furthermore, the performance
disparities observed in real-world programs suggest that, mainly due to the nature of the
logic bugs in ST programs, a one-size-fits-all approach, like in the case of AFL++, may not
be optimal. Our PLC runtime environment, designed specifically for fuzzing ST programs,
enables a more precise and targeted bug discovery process through the use of a harness
function, as it allows one to define program specifications used to detect violations during
fuzzing. Through the experimental evaluation, we also highlight the constraints of AFL++
when applied to domain-specific languages like ST, underlining the need for specialized
fuzzing tools for PLCs.
To fortify our findings, we further calculated the speedup of the proposed fuzzer
against AFL++ and AFL++/IG. The results depicted in Table 2 demonstrate that the
proposed fuzzer achieves a speedup ranging from a few ×100 to more than ×10, 000 over
AFL++ and AFL++/IG. Indicatively, the proposed fuzzer exhibits a speedup factor of
×8880.41 over AFL++ and a factor of ×5218.65 over AFL++/IG when considering the
program with a branch depth of 3. For programs resembling real-world PLC control logic,
the proposed fuzzer achieves a speedup of ×23, 088.15 over AFL++ as opposed to ×365.69
over AFL++/IG in finding the bug in the program Complex 2.
Furthermore, Figure 9 corroborates a significant improvement in speed in terms of
logic bug detection, showcasing a consistently superior speedup factor of the proposed
fuzzer over the AFL++ and AFL++/IG ones. This speed discrepancy is even more apparent,
particularly in programs with an increased level of the considered characteristics. This
enhanced performance stems from our input generation scheme paired with our customized
mutator mechanism because of the focused mutation to the PLC inputs and their adaption
to the expected input structures within the ST programs. As a characteristic example,
the substantial speedup observed for programs like Complex 2 and Complex 5 suggests
that our fuzzer’s logic-oriented testing approach is particularly effective for programs
that incorporate certain control flow statements, such as case and if statements. Moreover,
integrating our input generation method with AFL++ demonstrates improved performance,
albeit not as conspicuous as with our fuzzer. Despite the prevalence of AFL++/IG compared
to AFL++, both are significantly slower than the proposed fuzzer. AFL++ and AFL++/IG
often require several hours as opposed to less than a second to find the bug in all the
considered programs. Based on these findings, the performance increase cannot solely be
Electronics 2024, 13, 2475 17 of 26

attributed to the proposed input generation technique. These findings imply that while the
initial fuzzing corpus generation can indeed enhance the performance of an existing fuzzer
(AFL++), the primary driver of efficiency lies in our custom mutator detailed in the fourth
step of the proposed framework (See Section 3.2).

Table 2. Average time in sec (lower is better) and speedup (higher is better) to find the
crash for each fuzzer.
Speedup Speedup
Characteristics AFL++ AFL++/IG Our Fuzzer AFL++ AFL++/IG
Fuzzer Fuzzer
Branch
Depth
Depth 1 559.29 16.86 0.13 4302.23 129.69
Depth 2 358.00 427.00 0.14 2557.14 3050.00
Depth 3 1509.67 887.17 0.17 8880.41 5218.65
Branch
Width
Width 1 3954.17 3870.00 0.21 18,829.38 18,428.57
Width 2 2174.33 1943.50 0.19 11,443.84 10,228.95
Width 3 1114.47 2298.20 0.20 5572.35 11,491.00
Branch
Condition
Condition 1 220.47 19.88 0.14 1574.79 142.00
Condition 2 522.14 140.00 0.15 3480.93 933.33
Condition 3 561.50 75.25 0.14 4010.71 537.50
Real-world
Program
Complex 1 780.67 20.08 0.24 3252.79 83.67
Complex 2 6002.92 95.08 0.26 23,088.15 365.69
Complex 3 1361.44 844.22 0.19 7165.47 4443.26
Complex 4 5378.27 2655.82 0.41 13,117.73 6477.61
Complex 5 3975.45 909.00 0.20 19,877.25 4545.00
Complex 6 2379.80 44.40 0.16 14,873.75 277.50
Complex 7 993.38 77.62 0.17 5843.41 456.59
Complex 8 1223.70 1167.00 0.28 4370.36 4167.86
Complex 9 1082.22 380.56 0.28 3865.07 1359.14
Complex 10 1496.67 473.11 0.55 2721.22 860.20

The results depicted in Table 3 show the average total executions for programs re-
sembling real-world PLC programs and those with varying branch widths, depths, and
conditions. The results demonstrate that our fuzzer has fewer executions of the binary
during fuzzing, which is a desirable property. That is, on average, it executes the binary
less than 100 times compared to AFL++/IG, which has several hundreds of executions.
Nevertheless, AFL++/IG also executes the binary fewer times than AFL++. Obviously, the
proposed input generation allows AFL++/IG to apply a more focused fuzzing strategy,
which reduces the number of executions required to find the bug. In contrast, AFL++ re-
quires a significantly higher number of executions, ranging from ×10, 000 to ×100, 000, 000.
As evident in Figure 10, our fuzzer exhibits the best efficiency in terms of the number
of executions of the binary during fuzzing. A smaller number of executions is desired
because a high number of executions increases the workload of the fuzzer. This metric is
correlated to the speed of the fuzzer since a faster fuzzer would find the bugs with fewer
executions of the binary. The AFL++/IG has the second-best performance based on the
executions of the test cases. These findings showcase the improvement enabled by the
input generation technique adopted in our fuzzer and in AFL++/IG.
Electronics 2024, 13, 2475 18 of 26

Figure 8. Time to find the bugs for the programs with various branch depths (top), widths
(second from the top), conditions (third from the top), and real-world programs (bottom).
Through the evaluation of the proposed fuzzing framework, we showcased its effi-
ciency. In particular, by leveraging the proposed PLC runtime to design an input generation
mechanism, we significantly improved the performance of the AFL++ fuzzer, putting for-
ward the AFL++/IG paradigm. More importantly, our custom-made fuzzer, embedding
a custom mutator, consistently surpassed AFL++ and AFL++/IG in detecting logic bugs
within ST control logic programs of diverse complexities.
However, the derived results should be cautiously interpreted, as the experimental
setup involved carefully designed programs to evaluate the capabilities of the considered
fuzzers. A more comprehensible dataset of more realistic ST programs may introduce
additional challenges.
Nevertheless, the experimental evaluation validates the hypothesis that conventional
fuzzing tools are sub-optimal for discovering logic errors in ST-based PLC control logic
applications. In this direction, our novel fuzzer significantly accelerates the logic bug
discovery process and offers a more robust and targeted testing mechanism, thereby
contributing to the overall security posture of PLCs.
Electronics 2024, 13, 2475 19 of 26

Figure 9. Speedup of the proposed fuzzer in finding the bugs compared against AFL++ for
the programs with various branch depths (top), widths (second from the top), conditions
(third from the top), and real-world programs (bottom).
Electronics 2024, 13, 2475 20 of 26

Table 3. Average total number of executions for each fuzzer for the depth, width, condition
test cases, and real-world programs. A small number of executions is desirable.
Characteristics AFL++ AFL++/IG Our Fuzzer
Branch Depth
Depth 1 273,970.00 5591.57 7.43
Depth 2 179,891.75 334,971.25 9.88
Depth 3 942,404.50 441,799.67 13.50
Branch Width
Width 1 1,882,189.50 1,459,524.83 1.0
Width 2 710,572.67 577,395.33 1.0
Width 3 765,733.93 1,677,735.47 1.0
Branch Condition
Condition 1 110,527.24 6581.53 3.65
Condition 2 91,400.43 16,189.00 1.00
Condition 3 122,671.00 7353.38 4.38
Real-world Program
Complex 1 64,996.17 772.92 1.00
Complex 2 2,841,554.00 3275.00 13.62
Complex 3 367,426.44 124,724.56 5.56
Complex 4 2,967,611.73 1,427,264.82 1.00
Complex 5 1,615,857.82 106,716.45 7.64
Complex 6 734,122.60 1464.20 1.00
Complex 7 96,081.50 2249.12 3.25
Complex 8 189,611.80 181,804.10 58.70
Complex 9 141,941.11 18,508.11 60.11
Complex 10 402,542.33 36,779.22 95.11

Figure 10. Cont.


Electronics 2024, 13, 2475 21 of 26

Figure 10. Total number of executions for programs with varying branch depths (top),
widths (third from top), conditions (second from bottom), and real-world programs
(bottom). Lower is better.
5. Related Work
In this section, we review the existing literature, focusing on works that introduce
some fuzzing techniques in the realm of ICS. Generally, ICS Fuzzing can be categorized
into network protocol fuzzing and device fuzzing. Although our fuzzer lies in the sec-
ond category, for completeness reasons, we also discuss studies in the field of network
protocol fuzzing.
Network protocol fuzzing: Fuzzing often involves the security testing of communication
protocols [10–12]. For instance, in PropFuzz [13], the authors present a protocol fuzzer
designed for proprietary ICS protocols. The tool fuzzes network protocols by analyzing the
communication between a device, say, a PLC, and an integrated development environment
(IDE) to extract and mutate the relevant network fields. Then, it sends the sniffed (mutated)
packets to the device. In addition, the fuzzer receives execution feedback by monitoring an
output channel of the PLC. Similarly, Luo et al. present Polar [14], a protocol fuzzer that
extracts semantic information from ICS protocol packets to identify vulnerable protocol
function fields. The tool uses static analysis and dynamic taint analysis to identify the fields
that are most likely to contain vulnerable operations and to fuzz them. The authors in
CGFuzzer [15] propose a deep learning-based approach for fuzzing IIoT protocols, focusing
on the DNP3 protocol. Their tool uses a coverage-guided generative adversarial network
model (GAN), namely, CovGAN, to learn the specifications of the underlying network
protocol and generate fuzz test cases. The authors demonstrate the effectiveness of CGFuzzer
in identifying vulnerabilities in the DNP3 protocol by evaluating the fuzzer on a public
dataset and an in-house capture dataset. Overall, the discussed studies underscore the
significance of protocol fuzzing in improving the security of ICS devices, emphasizing the
need for tools and methodologies to address the unique challenges of ICS security testing.
Electronics 2024, 13, 2475 22 of 26

Device Fuzzing: Fuzzing has also been applied to test the security of ICS devices like
PLCs. The most common approaches include emulation-based, harness-based, and on-
device fuzzing [44]. Emulation-based fuzzing involves testing the firmware of the device
through an emulator, i.e., a technique also known as re-hosting. For instance, developed by
Scharnowski et al., Fuzzware [45] is a fuzzing tool that uses memory-mapped I/O (MMIO)
to model the peripherals of devices to fuzz their firmware. It is designed to identify
vulnerabilities in the firmware of embedded devices via concolic execution-based fuzzing.
Similarly, Tychalas et al. present IFFSET [46], a fuzzing tool that uses Quick-Emulation
(QEMU) to emulate the Linux-based ICS firmware of Codesys PLCs. The approach relies on
reverse engineering the firmware to extract the linked shared objects of I/Os and network-
related code that are called from a harness during fuzzing. The authors of P2 IM [47]
propose a hardware-independent firmware fuzzing via peripherals modeling. Their tool
instantiates a device model from an abstract model for the ARM Cortex-M architecture.
During fuzzing, their tool can discriminate between benign and crashing inputs through
the proposed model. In Sizzler [48], the authors present a tool for fuzzing QEMU-based
emulated PLC firmware. It utilizes a sequential generative adversarial network (SeqGAN)
to generate test cases for mutation-based fuzzing. Unlike emulation-based fuzzing, harness-
based fuzzing involves using a harness to connect the fuzzer and the device. For example,
SP-Fuzz [49] is a tool that generates a harness in a semi-automated fashion using context
information from the execution of the PLC runtime. In contrast, on-device fuzzing involves
executing the fuzzer directly on the device, e.g., ICSFuzz [3].
In detail, ICSFuzz [3] is a novel fuzzing technique designed for ICS control applica-
tions. Their framework investigates the potential for exploiting PLC binaries and their
environment by repurposing binary code to perform instrumented fuzzing. Their frame-
work stands out for its capacity to manipulate I/Os and fuzz the PLC runtime. To evaluate
ICSFuzz, the authors use a set of in-house PLC binaries, along with functional control applica-
tions from online repositories. During instrumentation, they use angr [50] to identify locations
within the binary, where instructions could be injected for receiving execution feedback.
Although our work shares similarities with the one presented by Tychalas et al. [3],
it also addresses several limitations in the ICSFuzz framework. First, ICSFuzz’s focus on
vulnerabilities that can be exploited with conventional attacks is prone to missing logical
bugs arising from the unique programming paradigms of the PLCs. Contrarily, our fuzzer
is designed to discern and generate inputs that explore the logical flow of ST applications,
going beyond the binary execution level to reveal logic-based vulnerabilities. Second,
ICSFuzz heavily relies on an existing cross-compiler and operates natively on the PLC,
which may restrict its usability across different PLC hardware and software configurations.
Conversely, our framework tackles this limitation by incorporating a PLC runtime that
abstracts the hardware layer, allowing for a more flexible and adaptable testing environment
that can be applied across various PLC platforms. Last, operating ICSFuzz is constrained
by Codesys-based applications modified for Wago PLCs, posing a challenge for broader
applicability. In contrast, our fuzzer is developed per the IEC 61131-3 standard, ensuring
compatibility with a broader range of industrial programming environments and making
it a broadly applicable tool in the domain of PLC security testing.
The work on the symbolic execution of programmable logic controller code in Sym-
PLC [41] is designed to automatically test PLC software written in languages specified by
the IEC 61131-3 standard and introduces PLC-specific reduction techniques to eliminate
redundant interleavings. While SymPLC represents a methodological advance, particularly
in its systematic approach to exploring program paths, it differs from our fuzzing-based
approach in several key aspects. Symbolic execution, as implemented in SymPLC, is inher-
ently static and relies on a priori knowledge of all possible inputs and states, which may
not be feasible for complex industrial control software that interacts with dynamic and
unpredictable physical environments. In contrast, our fuzzing technique does not require
exhaustive knowledge of all possible states. Instead, it dynamically generates inputs that
probe the control logic in ways likely to occur during actual operation, potentially revealing
Electronics 2024, 13, 2475 23 of 26

logical errors that would not be manifested through static analysis alone. This dynamic
aspect is particularly crucial, given the real-time operational constraints and the need
for immediate response to physical process changes in industrial settings. Furthermore,
SymPLC may encounter challenges when scaling to large, complex control systems due to
the state explosion problem inherent in symbolic execution. On the other hand, our fuzzing
methodology deftly scales as the complexity of the control logic increases since it is guided
by runtime behavior and feedback, allowing it to focus on the most promising areas of
the code.

6. Conclusions and Future Work


This research presents a novel approach for fuzzing PLC control logic applications,
particularly targeting ST programs as specified in the IEC 61131-3 standard. The empirical
evaluation of the proposed fuzzer through an extensive suite of ST programs with varying
levels of complexity of alternative characteristics has yielded significant insights into the
effectiveness of our methodology.
The proposed fuzzer demonstrates a consistent superiority over the conventional
AFL++ fuzzer, achieving substantial speedups of several orders of magnitude and reduced
bug detection times (less than a second) across all considered dimensions. This performance
advantage may be attributed to our custom fuzzing mutator engine, which adapts the
structure of fuzz inputs to ST programs and to the input generation mechanism, which
provides good initial inputs for fuzzing. By feeding random input to targeted locations
with the help of a finely tuned runtime environment, the proposed fuzzer has been proven
to be an efficient tool for fuzzing PLC control applications.
The robustness of our fuzzer is evident in its ability to handle wide branches, deep
nested conditions, and various program constructs, outperforming AFL++ in terms of
speed. Through the evaluation of our fuzzer, we showcase its potential for improving
the security and reliability of PLC software, also underscoring the limitations of applying
general-purpose fuzzing tools like AFL++ to such specialized programming environments.
While the tests were conducted in a controlled software environment with carefully
designed programs, the promising results advocate for the deployment and further testing
of our fuzzer in real-world industrial settings. An obvious avenue for future work includes
refining the fuzzing algorithms, testing the harness in a controlled environment, and
validating its effectiveness on a more extensive dataset. Additionally, we plan to extend
the framework to support other IEC 61131-3 languages, such as Ladder Diagram (LD),
which is widely used in industry. Fuzzing LD poses unique challenges due to its graphical
nature, and we aim to address these challenges in future work to enhance further the
framework’s applicability and utility in real-world industrial settings. Another intriguing
direction for future research involves integrating open-source language models to automate
the generation of the fuzzing harness as a specification of PLC software, thus further
improving the performance and usability of the proposed framework.

Author Contributions: Conceptualization, C.K.; Software, K.A.K. and J.S.; Validation, V.K. and J.S.;
Formal analysis, J.S.; Investigation, K.A.K.; Data curation, V.K.; Writing—original draft, K.A.K. and
C.K.; Writing—review & editing, V.K., C.K. and R.C.I.; Supervision, C.K.; Project administration,
C.K.; Funding acquisition, R.C.I. All authors have read and agreed to the published version of
the manuscript.
Funding: Work supported through the INL Laboratory Directed Research & Development (LDRD)
Program under DOE Idaho Operations Office Contract DE-AC07-05ID14517.
Data Availability Statement: All data and scripts are publicly accessible through the following link:
https://github.com/kandersonko/StructuredFuzzer, accessed on 31 May 2024.
Conflicts of Interest: The authors have no other conflicts of interest to disclose.
Electronics 2024, 13, 2475 24 of 26

Abbreviations
The following abbreviations are used in this manuscript:

IG Input Generation
AFL American Fuzzy Lop
AFL++ American Fuzzy Lop Plus Plus
ST Structured Text
SCA Static Code Analysis
IEC International Electrotechnical Commission
PLC Programmable Logic Controller
LL Ladder Logic
LD Ladder Diagram
FBD Function Block Diagram
SFC Sequential Function Chart
ICS Industrial Control Systems
HMI Human–Machine Interface

References
1. Stouffer, K.; Pease, M.; Tang, C.; Zimmerman, T.; Pillitteri, V.; Lightman, S.; Hahn, A.; Saravia, S.; Sherule, A.; Thompson, M.
Guide to Operational Technology (OT) Security; Technical Report NIST Special Publication (SP) 800-82 Rev. 3; NIST: Gaithersburg,
MD, USA, 2023. https://doi.org/10.6028/NIST.SP.800-82r3.
2. Bhamare, D.; Zolanvari, M.; Erbad, A.; Jain, R.; Khan, K.; Meskin, N. Cybersecurity for industrial control systems: A survey.
Comput. Secur. 2020, 89, 101677.
3. Tychalas, D.; Benkraouda, H.; Maniatakos, M. {ICSFuzz}: Manipulating {I/Os} and Repurposing Binary Code to Enable
Instrumented Fuzzing in {ICS} Control Applications. In Proceedings of the 30th USENIX Security Symposium (USENIX Security
21), Vancouver, BC, Canada, 11–13 August 2021; pp. 2847–2862.
4. Shehod, A. Ukraine power grid cyberattack and US susceptibility: Cybersecurity implications of smart grid advancements in the
US. Cybersecur. Interdiscip. Syst. Lab. MIT 2016, 22, 2016–22.
5. Myung, J.w.; Hong, S. ICS malware Triton attack and countermeasures. Int. J. Emerg. Multidiscip. Res. 2019, 3, 13–17.
6. Robles, F.; Perlroth, N. Dangerous Stuff’: Hackers Tried to Poison Water Supply of Florida Town. The New York Times, 2021.
7. Hajda, J.; Jakuszewski, R.; Ogonowski, S. Security challenges in industry 4.0 PLC Systems. Appl. Sci. 2021, 11, 9785.
8. NIST Glossary: Fuzz Testing. Available online: https://csrc.nist.gov/glossary/term/fuzz_testing (accessed on 20 April 2024).
9. Li, J.; Zhao, B.; Zhang, C. Fuzzing: A survey. Cybersecurity 2018, 1, 1–13.
10. Chen, Y.; Poskitt, C.M.; Sun, J.; Adepu, S.; Zhang, F. Learning-Guided Network Fuzzing for Testing Cyber-Physical System
Defences. In Proceedings of the 2019 34th IEEE/ACM International Conference on Automated Software Engineering (ASE),
San Diego, CA, USA, 11–15 November 2019; pp. 962–973. https://doi.org/10.1109/ASE.2019.00093.
11. Wijaya, H.; Aniche, M.; Mathur, A. Domain-Based Fuzzing for Supervised Learning of Anomaly Detection in Cyber-Physical
Systems. In Proceedings of the IEEE/ACM 42nd International Conference on Software Engineering Workshops, ICSEW’20, Seoul,
Republic of Korea, 27 June–19 July 2020; pp. 237–244. https://doi.org/10.1145/3387940.3391486.
12. Kampourakis, V.; Chatzoglou, E.; Kambourakis, G.; Dolmes, A.; Zaroliagis, C. Wpaxfuzz: Sniffing out vulnerabilities in wi-fi
implementations. Cryptography 2022, 6, 53.
13. Niedermaier, M.; Fischer, F.; von Bodisco, A. PropFuzz—An IT-security fuzzing framework for proprietary ICS protocols. In
Proceedings of the 2017 International Conference on Applied Electronics (AE), Pilsen, Czech Republic, 5–6 September 2017;
pp. 1–4. https://doi.org/10.23919/AE.2017.8053600.
14. Luo, Z.; Zuo, F.; Jiang, Y.; Gao, J.; Jiao, X.; Sun, J. Polar: Function Code Aware Fuzz Testing of ICS Protocol. ACM Trans. Embed.
Comput. Syst. 2019, 18, 93:1–93:22. https://doi.org/10.1145/3358227.
15. Yu, Z.; Wang, H.; Wang, D.; Li, Z.; Song, H. CGFuzzer: A Fuzzing Approach Based on Coverage-Guided Generative Adversarial
Networks for Industrial IoT Protocols. IEEE Internet Things J. 2022, 9, 21607–21619. https://doi.org/10.1109/JIOT.2022.3183952.
16. Tiegelkamp, M.; John, K.H. IEC 61131-3: Programming Industrial Automation Systems; Springer: Berlin/Heidelberg, Germany, 2010;
Volume 166.
17. Editor, C.C. Programmable Logic Controller—Glossary|CSRC. Available online: https://csrc.nist.gov/glossary/term/
programmable_logic_controller (accessed on 22 April 2024).
18. Di Pinto, A.; Dragoni, Y.; Carcano, A. TRITON: The first ICS cyber attack on safety instrument systems. Proc. Black Hat USA 2018,
2018, 1–26.
19. Kampourakis, V.; Gkioulos, V.; Katsikas, S. A systematic literature review on wireless security testbeds in the cyber-physical
realm. Comput. Secur. 2023, 133, 103383. https://doi.org/10.1016/j.cose.2023.103383.
20. Kushner, D. The real story of stuxnet. IEEE Spectr. 2013, 50, 48–53.
21. Eisele, M.; Maugeri, M.; Shriwas, R.; Huth, C.; Bella, G. Embedded fuzzing: A review of challenges, tools, and solutions.
Cybersecurity 2022, 5, 18. https://doi.org/10.1186/s42400-022-00123-y.
Electronics 2024, 13, 2475 25 of 26

22. Miller, B.P.; Fredriksen, L.; So, B. An empirical study of the reliability of UNIX utilities. Commun. ACM 1990, 33, 32–44.
https://doi.org/10.1145/96267.96279.
23. Gascon, H.; Wressnegger, C.; Yamaguchi, F.; Arp, D.; Rieck, K. Pulsar: Stateful black-box fuzzing of proprietary network protocols.
In Proceedings of the Security and Privacy in Communication Networks: 11th EAI International Conference, SecureComm 2015,
Dallas, TX, USA, 26–29 October 2015; Springer: Berlin/Heidelberg, Germany, 2015; pp. 330–347.
24. Böhme, M.; Pham, V.T.; Nguyen, M.D.; Roychoudhury, A. Directed greybox fuzzing. In Proceedings of the 2017 ACM SIGSAC
Conference on Computer and Communications Security, Dallas Texas, USA, 30 October–3 November, 2017; pp. 2329–2344.
25. Zhang, M.; Arcuri, A.; Li, Y.; Liu, Y.; Xue, K. White-box fuzzing RPC-based APIs with EvoMaster: An industrial case study. ACM
Trans. Softw. Eng. Methodol. 2023, 32, 1–38.
26. Lyu, C.; Ji, S.; Zhang, C.; Li, Y.; Lee, W.H.; Song, Y.; Beyah, R. {MOPT}: Optimized mutation scheduling for fuzzers. In Proceedings
of the 28th USENIX Security Symposium (USENIX Security 19), Santa Clara, CA, USA, 14–16 August 2019; pp. 1949–1966.
27. Wang, J.; Chen, B.; Wei, L.; Liu, Y. Skyfire: Data-driven seed generation for fuzzing. In Proceedings of the 2017 IEEE
Symposium on Security and Privacy (SP), San Jose, CA, USA, 25 May 2017; IEEE: Piscataway, NJ, USA, 2017; pp. 579–594.
https://doi.org/10.1109/SP.2017.23.
28. Chen, Y.; Li, P.; Xu, J.; Guo, S.; Zhou, R.; Zhang, Y.; Wei, T.; Lu, L. SAVIOR: Towards Bug-Driven Hybrid Testing. In Proceedings
of the 2020 IEEE Symposium on Security and Privacy (SP), San Francisco, CA, USA, 21 May 2020, pp. 1580–1596, ISSN 2375-1207.
https://doi.org/10.1109/SP40000.2020.00002.
29. Hsu, C.C.; Wu, C.Y.; Hsiao, H.C.; Huang, S.K. Instrim: Lightweight instrumentation for coverage-guided fuzzing. In Proceedings
of the Symposium on Network and Distributed System Security (NDSS), Workshop on Binary Analysis Research, San Diego, CA,
USA, 18–21 February 2018; Volume 40.
30. Li, W.; Shi, J.; Li, F.; Lin, J.; Wang, W.; Guan, L. µAFL: Non-intrusive feedback-driven fuzzing for microcontroller firmware. In
Proceedings of the 44th International Conference on Software Engineering, Pittsburgh Pennsylvania, San Diego, CA, USA, 8–27
May 2022; pp. 1–12. https://doi.org/10.1145/3510003.3510208.
31. Rawat, S.; Jain, V.; Kumar, A.; Cojocar, L.; Giuffrida, C.; Bos, H. VUzzer: Application-aware Evolutionary Fuzzing. In Proceedings
of the NDSS, San Diego, CA, USA, 26 February–1 March 2017; Volume 17, pp. 1–14.
32. FuzzBench: Oss-Fuzz-Benchmarks Report (Running). Available online: https://commondatastorage.googleapis.com/fuzzbench-
reports/oss-fuzz-benchmarks/index.html (accessed on 22 April 2024).
33. American Fuzzy Lop. Available online: https://lcamtuf.coredump.cx/afl/ (accessed on 12 April 2024).
34. Fioraldi, A.; Maier, D.; Eißfeldt, H.; Heuse, M. {AFL++}: Combining incremental steps of fuzzing research. In Proceedings of the
14th USENIX Workshop on Offensive Technologies (WOOT 20), Boston, MA, USA, 10–11 August 2020.
35. Serhane, A.; Raad, M.; Raad, R.; Susilo, W. Programmable logic controllers based systems (PLC-BS): Vulnerabilities and threats.
SN Appl. Sci. 2019, 1, 924. https://doi.org/10.1007/s42452-019-0860-2.
36. Catalão, T.H.A.A. An LLVM Based Compiler for the IEC 61131-3. Master’s Thesis, University of Porto, Porto, Portugal, 2020.
37. Alves, T.R.; Buratto, M.; De Souza, F.M.; Rodrigues, T.V. OpenPLC: An open source alternative to automation. In Proceedings of
the IEEE Global Humanitarian Technology Conference (GHTC 2014), San Jose, CA, USA, 10–13 October 2014; IEEE: Piscataway,
NJ, USA, 2014; pp. 585–589. https://doi.org/10.1109/GHTC.2014.6970342.
38. Wang, M.; Liang, J.; Chen, Y.; Jiang, Y.; Jiao, X.; Liu, H.; Bin Zhao, X.; Sun, J. SAFL: Increasing and accelerating testing
coverage with symbolic execution and guided fuzzing. In Proceedings of the 2018 IEEE/ACM 40th International Conference
on Software Engineering: Companion (ICSE-Companion), Gothenburg, Sweden, 27 May–3 June 2018; pp. 61–64. https:
//doi.org/10.1145/3183440.3183494.
39. Cheng, L.; Zhang, Y.; Zhang, Y.; Wu, C.; Li, Z.; Fu, Y.; Li, H. Optimizing seed inputs in fuzzing with machine learning. In
Proceedings of the 2019 IEEE/ACM 41st International Conference on Software Engineering: Companion Proceedings (ICSE-
Companion), Montreal, QC, Canada, 25–31 May 2019; IEEE: Piscataway, NJ, USA, 2019; pp. 244–245.
40. Latif, A., Azam, F., Anwar, M. & Zafar, A. Comparison of Leading Language Parsers – ANTLR, JavaCC, SableCC, Tree-sitter, Yacc,
Bison. In Proceedings of the 2023 13th International Conference On Software Technology And Engineering (ICSTE), Osaka, Japan,
27–29 October 2023; pp. 7–13. https://doi.org/doi:10.1109/ICSTE61649.2023.00009.
41. Guo, S.; Wu, M.; Wang, C. Symbolic execution of programmable logic controller code. In Proceedings of the 2017 11th Joint
Meeting on Foundations of Software Engineering, ESEC/FSE 2017, Paderborn, Germany, 4–8 September 2017; pp. 326–336.
https://doi.org/10.1145/3106237.3106245.
42. Fioraldi, A.; Maier, D.C.; Zhang, D.; Balzarotti, D. Libafl: A framework to build modular and reusable fuzzers. In Proceedings
of the 2022 ACM SIGSAC Conference on Computer and Communications Security, Los Angeles, CA, USA, 11 November 2022;
pp. 1051–1065.
43. Falcon. 2023. Available online: https://www.c3plus3.org/falcon/ (accessed on 17 January 2024).
44. Yun, J.; Rustamov, F.; Kim, J.; Shin, Y. Fuzzing of Embedded Systems: A Survey. ACM Comput. Surv. 2023, 55, 1–33.
https://doi.org/10.1145/3538644.
45. Scharnowski, T.; Bars, N.; Schloegel, M.; Gustafson, E.; Muench, M.; Vigna, G.; Kruegel, C.; Holz, T.; Abbasi, A. Fuzzware: Using
Precise {MMIO} Modeling for Effective Firmware Fuzzing. In Proceedings of the 31st USENIX Security Symposium (USENIX
Security 22), Boston, MA, USA, 10–12 August 2022; pp. 1239–1256.
Electronics 2024, 13, 2475 26 of 26

46. Tychalas, D.; Maniatakos, M. IFFSET: In-Field Fuzzing of Industrial Control Systems using System Emulation. In Proceedings of
the 2020 Design, Automation & Test in Europe Conference & Exhibition (DATE), Grenoble, France, 9–13 March 2020; pp. 662–665,
ISSN 1558-1101. https://doi.org/10.23919/DATE48585.2020.9116365.
47. Feng, B.; Mera, A.; Lu, L. {P2IM}: Scalable and Hardware-independent Firmware Testing via Automatic Peripheral Interface
Modeling. In Proceedings of the 29th USENIX Security Symposium (USENIX Security 20), Boston, MA, USA, 12–14 August 2020 ;
pp. 1237–1254.
48. Feng, K.; Cook, M.M.; Marnerides, A.K. Sizzler: Sequential Fuzzing in Ladder Diagrams for Vulnerability Detection and
Discovery in Programmable Logic Controllers. IEEE Trans. Inf. Forensics Secur. 2024, 19, 1660–1671. https://doi.org/10.1109/
TIFS.2023.3340615.
49. Jeon, S.; Seo, J.T. SP-Fuzz: Fuzzing Soft PLC with Semi-automated Harness Synthesis. In Proceedings of the Information
Security Applications (WISA 2023), Jeju Island, Republic of Korea, 23–25 August 2023; Kim, H., Youn, J., Eds., 2023; pp. 282–293.
https://doi.org/10.1007/978-981-99-8024-6_22.
50. Wang, F.; Shoshitaishvili, Y. Angr-The Next Generation of Binary Analysis. In Proceedings of the 2017 IEEE Cybersecurity
Development (SecDev), Cambridge, MA, USA, 24–26 September 2017; pp. 8–9. https://doi.org/10.1109/secdev.2017.14.

Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual
author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to
people or property resulting from any ideas, methods, instructions or products referred to in the content.

You might also like