PROFINET IO devices are industrial automation components (like sensors, actuators, drives, or I/O blocks) that communicate over the PROFINET protocol, a real-time Ethernet-based standard widely used in OT networks. These devices enable deterministic and low-latency data exchange with PLCs, supporting both cyclic (real-time) and acyclic (diagnostic/configuration) communication. In OT networks, they are critical for controlling and monitoring physical processes in sectors like manufacturing, energy, and transportation, often forming the backbone of Industrial Ethernet communication.
In this blog, we investigate ten vulnerabilities uncovered during a fuzzing campaign targeting the P-Net C library, an open-source implementation of the PROFINET protocol for IO devices, developed by RT-Labs. These flaws were discovered as part of Nozomi Networks Labs' ongoing efforts to assess the security posture of industrial communication protocols commonly used in OT environments.
We responsibly disclosed all findings to the RT-Labs team, who responded swiftly and effectively, addressing every issue in the latest release of the library (version 1.0.2). Notably, following our report, RT-Labs also integrated fuzz testing into their development process using libFuzzer, further strengthening the overall security of their software.
In the sections that follow, we will walk through the key takeaways from our research, explore the potential impact of these vulnerabilities on industrial devices, and share the methodology and tooling we used to fuzz the PROFINET stack.
リサーチ範囲
RT-Labs specializes in software solutions for embedded systems, with a strong focus on industrial communication and automation. Their platform simplifies the development of complex fieldbus integrations, allowing companies to focus on product functionality and performance. They provide unified communication solutions for industries with demanding real-time and networking requirements and offer advanced test automation tools that enhance software quality and development efficiency.
RT-Labs collaborates with major industrial players, including Toyota and ABB, and promotes open collaboration through their GitHub-based open-source initiative, where developers can explore and contribute to parts of their codebase.
In our research, we targeted the P-Net PROFINET library, developed by RT-Labs to implement the PROFINET protocol for IO devices. This C-based library is highly flexible and OS-independent, making it suitable for bare-metal systems, real-time operating systems like RT-Kernel, or even Linux. Its only platform requirement is the ability to send and receive raw Ethernet packets. An evaluation version of the P-Net library is publicly available on RT-Labs’ GitHub, which served as the basis for our research.
これらの脆弱性の影響
After analyzing version 1.0.1 of the P-Net library, we identified 10 memory corruption vulnerabilities related to the UDP RPC functionalities of the PROFINET protocol. These issues can be exploited by unauthenticated attackers with network access to the targeted device. If successfully exploited, these vulnerabilities can cause the device to become unreachable, experience severe instabilities, and enter denial-of-service states.
Practically speaking, exploiting CVE-2025-32399, an attacker can force the CPU running the P-Net library into an infinite loop, consuming 100% CPU resources. This condition could result in excessive power drain, a critical situation especially for battery-powered IO devices which might require manual intervention to restore normal operations. Another vulnerability, tracked as CVE-2025-32405, allows an attacker to write beyond the boundaries of a connection buffer, corrupting memory and making the device entirely unusable.
Given that these IO devices are commonly deployed within OT networks, such malfunctions could have serious implications, potentially disrupting or degrading the reliability of entire industrial production lines.
脆弱性リストと影響を受けるバージョン
The following table list all the vulnerabilities Nozomi Networks Labs has found on the P-Net library version 1.0.1 during this vulnerability research:
Setup of the Fuzzing Campaign
In this section, we outline the approach, and the unique challenges faced while fuzz testing a network protocol stack such as the P-Net library.
Fortunately for us, the P-Net library supports Linux, and a pre-compiled demo IO device binary was available on the project's GitHub page. Our first step was to download and experiment with this demo binary to understand the remote attack surface, including identifying the network services that could potentially be exploited by an attacker.
During runtime analysis, we observed that the IO daemon listens for UDP packets on ports 34964, 49155 (used by the PROFINET CMRPC protocol) as well as for raw Ethernet traffic (Figure 1).

Given that the UDP-based RPC service is externally accessible, we selected it as the primary target of our fuzzing campaign. A key requirement when fuzzing such targets is building a test harness that exercises meaningful parts of the code in a deterministic and repeatable way.
Determinism is vital for crash reproducibility and root cause analysis. Furthermore, since PROFINET is a stateful protocol, we would like to send multiple packets to the library before terminating the harness, allowing us to explore deeper protocol states beyond just the initial shallow ones.
Since the P-Net library implements the RPC functionalities as a daemon that listens for incoming connections, the demo binary could not be used as-is for our fuzzing campaign. To make it suitable, we had to modify the source code so that the network stack would process a fixed number of packets and then terminate.
Fortunately, the library includes a test suite based on GoogleTest (gtest), which mocks most of the network functionalities, including the RPC stack. This greatly simplified our work. For example, the following snippet from the test suite demonstrates how an RPC Connect request is tested to ensure it is parsed correctly.

The key functions are the following:
- mock_set_pnal_udp_recvfrom_buffer
, which allows us to set the network packet that will be processed by the library.
- run_stack
, which executes the PROFINET stack on the prepared packet.
By using these two functions, we were able to build a simple fuzzing harness that processes a sequence of UDP packets, with each packet's payload read from stdin. Figure 3 shows a sketch implementation of our harness.

The highlighted functions were omitted for brevity, their functionalities are:
read_all
: read the whole data from stdin, and save it in a global bufferget_next
: split the read data using a pre-defined token that subdivides each UDP packet
Our approach is straightforward: we read input from stdin and divide it into multiple UDP packets using a simple delimiter (e.g., the string AAAA). While we could have employed a more sophisticated strategy, such as using a custom mutator, our method avoids the need for a deep understanding of the PROFINET protocol. Instead, it relies on having a meaningful initial corpus from which the fuzzer can generate new, diverse test cases.
To generate the initial corpus, we once again took inspiration from the test suite, extracting the packets fed into the mock interface during testing. We then combined these packets using our chosen delimiter to create a sequence of UDP packets suitable for fuzzing.
With both the harness and the initial corpus in place, we had everything needed to kick off our fuzzing campaign with AFL++, one of the most widely used and effective open source fuzzers. This tool is known for its coverage-guided fuzzing, powerful instrumentation techniques and extensive customization options, making it ideal for targeting complex codebases like P-Net.
To run the campaign, we just needed to compile the test binary using AFL++, and then feeding it to the fuzzer in the following way:
Despite the simplicity of our approach, we were able to uncover seven vulnerabilities using this basic harness (CVE-2025-32396 to CVE-2025-32402). Encouraged by these results, we decided to develop a second harness that always includes a predefined sequence of packets simulating a scenario where an attacker has already established a connection with the device. This allowed us to fuzz deeper protocol states.
Below is a sketch implementation of this enhanced harness:

As we can see, the harness is quite similar to the previous one, reusing the same read_all and run_stack functions, but this time we prepend the necessary packets to simulate an established connection before processing the packets generated by the fuzzer.
Using this new harness, we were able to uncover other three vulnerabilities in the library (CVE-2025-32403, CVE-2025-32404, CVE-2025-32405).
脆弱性スポットライト
In this section, we highlight the vulnerability tracked as CVE-2025-32405, which we discovered using our second fuzzing harness. This vulnerability allows an unauthenticated remote attacker to write outside the bounds of a buffer that stores context information about the Application Relation (AR) between the IO device and a PLC.
Specifically, we discovered that when the library parses ArVendorBlock requests, it increments a counter and uses it as an index to write data from the UDP packet into an array. The vulnerability arises because the counter is not properly bounded: if an attacker sends enough packets, the index can exceed the array’s limits, leading to out-of-bounds writes. Below is a snippet of the vulnerable code:

修復
In this blog, we announced the disclosure of 10 memory corruption vulnerabilities affecting the P-Net PROFINET library, up to and including version 1.0.1. If exploited, these vulnerabilities could enable serious attacks against embedded IO devices that use the library.
After receiving our findings, RT-Labs, the developer of P-Net, promptly released version 1.0.2, which addresses and fixes all the reported issues. Additionally, following our report, RT-Labs integrated fuzz testing into their development process using libFuzzer, significantly strengthening the security posture of their libraries.
Given the security implications of these vulnerabilities, we strongly recommend that all developers and organizations using the P-Net library upgrade to the latest version to ensure their systems are protected.