In Part 7 of Team82's OPC UA Deep Dive Series, we will share examples of different denial-of-service attacks against OPC UA implementations. Successful exploits of implementation vulnerabilities can result in production stoppages, financial losses, and safety risks.
Throughout our extensive OPC UA Deep Dive Series, we researched the OPC UA protocol and its different functions and importance within operational technology (OT) environments. The centerpiece tool of our work is an advanced OPC UA Exploit Framework we built and used to execute many unique attacks against OPC UA implementations. We coordinated disclosures with affected vendors for all the vulnerabilities and attack concepts we discovered and developed. In this blog we will share some details of those vulnerabilities and their impact.
Denial of service (DoS) attacks on industrial networks utilizing OPC UA are particularly perilous due to their potential to disrupt critical operations. OPC UA-based systems play a vital role in industrial automation, and a DoS attack can overload network resources or flood communication channels, rendering the system unavailable.
This downtime can result in production stoppages, financial losses, and safety risks, because the affected industrial processes may not respond correctly in emergency situations. Furthermore, a prolonged DoS attack can exhaust resources needed for monitoring and recovery, making it challenging to mitigate the impact and might cause physical damage.
CVE-2023-32787:
OPC UA Stack, Prosys OPC UA Simulation Server implementation
Related CVEs: CVE-2022-29864, CVE-2022-21208, CVE-2022-25761, CVE-2022-25304, CVE-2022-24381, CVE-2022-25888
Short Description: Sending many OPC UA message chunks without providing the Final chunk leads to uncontrolled memory allocations and eventually to a crash.
The OPC UA specification determines that OPC UA messages are constructed of chunks (“message chunks”). Each message chunk has an OPC UA header with the following attributes:
Message Type (MSG, OPN, CLO)
Is Final Flag (F = Final, C = Chunk)
Message Size (32 bit)
SecureChannelID
In most cases, OPC UA protocol stacks will limit the allowed message size of each individual OPC UA message. If a large message needs to be sent, the message will be divided into multiple chunks each marked as C (chunk). When the final chunk arrives (marked as F Final) the full message will get decoded and handled.
However, we found that the application did not limit the amount of received chunks per a single session or in total for all concurrent sessions. Therefore, an attacker can abuse this to send an unlimited number of huge chunks (2 GB each) without ever sending the Final closing chunk. This will lead to an unlimited memory consumption because an increasing amount of heap allocation will be made until the entire RAM memory is consumed. Finally the OPC UA server will crash due to uncontrolled resource exhaustion.
In order to reproduce the issue:
While True:
Open a valid OPC UA session
Send many MSG chunks (IsFinal = Chunk)
Never send the Final chunk
Keep the session open
This specific vulnerability was assigned as CVE-2023-32787 and was fixed in Prosys OPC UA SDK for Java 4.10.4.
We would like to thank both ZDI and Prosys for their swift response and fixing all of our findings.
CVE-2023-27321
OPC Unified Architecture .NET Standard Protocol Stack implementation, and the ConditionRefresh method
Related CVEs: CVE-2023-27334, CVE-2023-39477
Short Description: Invoking many method calls (e.g. ConditionRefresh) leads to uncontrolled memory allocations and eventually to a crash.
The OPC UA specifications recommend servers to implement the ConditionRefresh Method. ConditionRefresh allows a Client to request a Refresh of all Condition instances that currently are important for the client to know. This includes previous states of a Condition instance for which the Server maintains Branches. A Client would typically invoke this Method when it initially connects to a Server and following any situation, such as communication disruptions, in which it would require resynchronization with the Server. This Method is only available on the ConditionType or its subtypes. To invoke this Method, the call shall pass the well-known Method Id of the Method on the ConditionType and the ObjectId shall be the well-known ObjectId of the ConditionType Object.
We found that the OPC UA stack handles this method asynchronously and does not limit the number of times that the client can call this method. The result is that a malicious client can call this procedure an unlimited number of times, forcing the server to reach an extreme memory and resource exhaustion which results in a crash due to insufficient resources.
The ConditionRefresh handling starts with a call back OnConditionRefresh.
Inside, there is an async call to DoConditionReresh. This call will be executed in the background by starting a new thread.
By calling this method multiple times, we are forcing the server to start many new threads that will do some work.
This work includes iterating through the current OPC UA objects and copying them while allocating huge amounts of memory.
Eventually, the server will consume all existing heap memory.
And finally, it will crash due to an “out-of-memory” error or hitting a heap guard.
This specific vulnerability was assigned as CVE-2023-27321 and was fixed in version v1.4.371.86.
We would like to thank both ZDI and OPC Foundation and the maintainer of UA-.NETStandard for their swift response and fixing all of our findings.
In this blog we’ve discussed three different attack concepts against OPC UA servers that cause denial of service conditions. All of these vulnerabilities were responsibly disclosed and fixed long ago.
In upcoming parts of our OPC UA Deep Dive Series, we will present other findings such as remote code execution vulnerabilities against OPC UA servers and even clients.
A Complete Guide to the OPC UA Attack Surface
Part 1: History of the OPC UA Protocol
Part 3: Exploring the OPC UA Protocol
Part 4: Targeting Core OPC UA Components
CWE-191 INTEGER UNDERFLOW (WRAP OR WRAPAROUND):
The affected product is vulnerable to an integer underflow. An unauthenticated attacker could send a malformed HTTP Requesty, which could allow the attacker to crash the program.
Planet Technology recommends users upgrade to version 1.305b241111 or later.
CVSS v3: 5.3
CWE-78 IMPROPER NEUTRALIZATION OF SPECIAL ELEMENTS USED IN AN OS COMMAND ('OS COMMAND INJECTION'):
The affected product is vulnerable to a command injection. An unauthenticated attacker could send commands through a malicious HTTP request which could result in remote code execution.
Planet Technology recommends users upgrade to version 1.305b241111 or later.
CVSS v3: 9.8
CWE-121 STACK-BASED BUFFER OVERFLOW:
The affected product is vulnerable to a stack-based buffer overflow. An unauthenticated attacker could send a malicious HTTP request that the webserver fails to properly check input size before copying data to the stack, potentially allowing remote code execution.
Planet Technology recommends users upgrade to version 1.305b241111 or later.
CVSS v3: 9.8
CWE-359 Exposure of Private Personal Information to an Unauthorized Actor:
Ruijie Reyee OS versions prior to 2.260.0.1329 contains a a feature that could enable sub accounts
or attackers attackers to view and exfiltrate sensitive information from all cloud accounts registered to Ruijie's services.
CVSS v3: 6.5
CWE-1391 Use of Weak Credentials:
Ruijie Reyee OS versions prior to 2.260.0.1329 uses weak credential mechanism that could allow
an attacker to easily calculate MQTT credentials.
Ruijie reports that the issues have been fixed on the cloud and no action is needed by end users.
CVSS v3: 7.5