This is Part six of Team82's OPC UA Deep Dive Series, a comprehensive guide to the security of the OPC UA network protocol for unified OT communication. In this entry, we will unveil a unique exploit framework that was crucial to our OPC UA research journey. As of today, the framework will be freely and publicly available on our Git Hub repository.
Team82’s extensive Deep Dive Series on OPC UA has arrived at the point where we discuss the tools we’ve developed to examine this critical OT protocol, as well as the vulnerabilities uncovered throughout this lengthy research project.
The centerpiece tool of our research is an advanced OPC UA Exploit Framework we built and used to execute many unique attacks against OPC UA implementations. It’s been immensely useful in finding close to 50 vulnerabilities in products using the protocol from OPC-UA client to servers to protocol gateways. Today, we are announcing it during a presentation at the Black Hat Briefings in Las Vegas, and are making it publicly available on our GitHub repository. We invite fellow researchers and vendors to use this framework to test their code bases and the security of your respective products.
Download our Exploit Framework Here
Many leading vendors in the OPC UA community have already had limited access to our framework. We created a coalition of vendor representatives on a private Slack channel to share best practices around improving the security of the protocol stack and how it is implemented. These vendors have also used the framework to test their products, and numerous vulnerabilities have been uncovered and addressed since this effort started.
Researchers and vendors will find this one-of-a-kind framework useful because each of the attack techniques exploits specific functions within the OPC UA protocol implementation. Users can send attacks that contain malformed or malicious packets to subsets of OPC UA, for example, that could trigger vulnerabilities when parsed. While not all vendor implementations were vulnerable during our research, we did find exploits impacting OPC UA servers, for example, that were prone to specific classes of vulnerabilities.
We collected these methods and used the framework to test them on a wide range of servers; this is a unique capability that allowed us to trigger certain bugs or flaws in more than one server implementation.
Team82 has used iterations of this framework for some time, including our successful participation at the annual Pwn2Own Miami ICS hacking event run during the annual S4 Conference in Miami.
We hope that researchers and vendors take advantage of the free availability of the framework to test all the concepts we developed on their products. Our GitHub also includes a detailed explainer on how to use the tool.
In this blog, we’re going to explain how the framework is structured and reveal some of the unique attack capabilities available in the framework, and the currently supported OPC UA servers.
We divided the framework into four categories of payloads: Sanity, Attacks, Corpus, Server.
Sanity: Sanity payloads include Reading Nodes, specific NodeID information given a namespace and NodeID, etc.
Attacks: Unique OPC UA-specific attacks that can cause a denial of service, leak sensitive information, or even execute code remotely.
Corpus: Reproducing payloads from corpus; useful for fuzzing iterations and reproducers.
Server: Simple server implementations (currently one example with cross-site scripting (XSS) payloads).
Basic Usage: python main.py SERVER_TYPE IP_ADDR PORT ENDPOINT_ADDRESS FUNC_TYPE [DIR]
Examples:
Sanity: python main.py prosys 1.2.3.4 53530 /OPCUA/SimulationServer sanity
Attack (DoS): python main.py prosys 1.2.3.4 53530 /OPCUA/SimulationServer thread_pool_wait_starvation
python main.py prosys 1.2.3.4 53530 /OPCUA/SimulationServer opcua_file FILE_PATH NUM_REQUESTS
python main.py prosys 1.2.3.4 53530 /OPCUA/SimulationServer opcua_dir PATH_TO_DIR_WITH_CORPUS
python main.py prosys 1.2.3.4 53530 /OPCUA/SimulationServer boofuzz_db BOOFUZZ_DB_FILEPATH
python main.py prosys 1.2.3.4 53530 /OPCUA/SimulationServer threads_run FUNC_NAME COUNT
Server Types: softing, unified, prosys, kepware, triangle, dotnetstd, open62541, ignition, rust, node-opcua, opcua-python, milo
Function types: threads_run, sanity , sanity_read_nodes , sanity_translate_browse_path , sanity_read_diag_info , sanity_get_node_id_info , opcua_dir , opcua_file , boofuzz_db , attack_file_nodejs_opcua_v8_oom , attack_file_ASNeG_OpcUaStack_unhandled_exception , chunk_flood , open_multiple_secure_channels , close_session_with_old_timestamp , complex_nested_message , translate_browse_path_call_stack_overflow , thread_pool_wait_starvation , unlimited_persistent_subscriptions , function_call_null_deref , malformed_utf8 , race_change_and_browse_address_space , certificate_inf_chain_loop , unlimited_condition_refresh
Sanity Name | Description | Function Keyword | Reference |
Diagnostic Info | Diagnostic summary information for the server |
| |
Get Node ID Info | Node ID is an identifier for a node in an OPC server’s address space. |
| |
Read Nodes | Read service is used to read attributes’ Nodes |
| |
Translate Browse Path | Translates browse paths to NodeIds. Each browse path is constructed of a starting Node and a RelativePath |
|
Sanity Name | Description | Function Keyword | Reference |
Diagnostic Info | Diagnostic summary information for the server | sanity_read_diag_info | |
Get Node ID Info | Node ID is an identifier for a node in an OPC server’s address space. | sanity_get_node_id_info | |
Read Nodes | Read service is used to read attributes’ Nodes | sanity_read_nodes | |
Translate Browse Path | Translates browse paths to NodeIds. Each browse path is constructed of a starting Node and a RelativePath | sanity_translate_browse_path |
Attack Name | Description | Vulnerability Type | Function Keyword | CVE and Reference |
Certificate Infinite Chain Loop | Some servers implemented the certificate chain check by themselves and forgot to protect against a chain loop. Example: Cert A is signed by Cert B which is signed by Cert A | Denial of Service |
| |
Chunk Flooding | Sending large amount of OPC UA MSG chunks without the Final chunk | Denial of Service |
| CVE-2022-29864, CVE-2022-21208, CVE-2022-25761, CVE-2022-25304, CVE-2022-24381, CVE-2022-25888 |
Open Multiple Secure Channels | Flooding the server with many open channel requests leads to a denial of service | Denial of Service |
| |
Close Session With Old Timestamp | Sending bad timestamp in the CLOSE session message leads to an uncaught stacktrace with sensitive information | Information Leakage |
| |
Complex Nested Message | Sending a complex nested variant leads to a call stack overflow | Denial of Service / Information Leakage |
| |
Translate Browse Path Call Stack Overflow | Triggering a stack overflow exception in a server that doesn't limit TranslateBrowsePath resolving calls | Denial of Service |
| |
Thread Pool Wait Starvation | Thread pool deadlock due to concurrent worker starvation | Denial of Service |
| |
Unlimited Persistent Subscriptions | Flooding the server with many monitored items with “delete” flag set to False leads to uncontrolled memory allocation and eventually to a denial of service | Denial of Service |
| |
Function Call Null Dereference | Triggering an application crash after several OPC UA methods have been called and the OPC UA session is closed before the methods have been finished. | Denial of Service |
| |
Malformed UTF8 | Triggering an application crash after processing malformed UTF8 strings | Remote Code Execution |
| |
Race Change And Browse Address Space | Adding nodes to the server address space and removing the nodes in a loop while browsing the entire address space. | Denial of Service |
| |
Unlimited Condition Refresh | Sending many ConditionRefresh method calls leads to uncontrolled memory allocations and eventually to a crash | Denial of Service |
|
We've implemented a simple way to fire up an OPC UA corpus at the servers. Our framework will wrap these samples in an OPC UA session so it’s very easy to use. This is very useful to reproduce bugs that were found using fuzzers.
opcua_message_boofuzz_db
: can be used to shoot an entire boofuzz db at a target
opcua_message_file
: can be used to shoot an a single file or directory of files with OPC-UA payloads (OPC-UA content itself)
In the repository we also included a lot of corpus we collected from our fuzzing attempts; check: input_corpus_minimized
. They are the result of many hours of fuzzing different targets via various methods and tools.
Currently our simple server PoC is a standalone script that is built on top of Python OPC-UA (asyncua). The current example was used in some RCE client exploitation (for example, see here).
Server Name | Default URI | Default Port | Server Keyword |
| 49320 |
| |
| 62541 |
| |
| 4897 |
| |
| 53530 |
| |
| 48050 |
| |
| 62541 |
| |
| 4885 |
| |
| 4840 |
| |
| 4855 |
| |
| 26543 |
| |
| 4840 |
| |
| 62541 |
|
We urge vendors and researchers alike to use our OPC UA Exploit Framework to test the security of OPC UA implementations. This is a unique collection of attacks, a one-stop for security testing of this crucial OT protocol stack. We already shared this framework with representatives of some of the leading OT vendors, and close to 50 vulnerabilities surfaced and were addressed.
We’re hoping to see more of you leverage this tool to test your products and in your research, and coordinate the disclosure of any vulnerabilities you may find with the affected vendor.
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
Part 5: Inside Team82’s Research Methodology
CWE-1390 WEAK AUTHENTICATION:
The web server for ONS-S8 - Spectra Aggregation Switch includes an incomplete authentication process, which can lead to an attacker authenticating without a password.
Optigo Networks recommends users always use a unique management VLAN for the port on the ONS-S8 that is used to connect to OneView.
Optigo Networks also recommends users implement at least one of the following additional mitigations:
Use a dedicated NIC on the BMS computer and exclusively this computer for connecting to OneView to manage your OT network configuration.
Set up a router firewall with a white list for the devices permitted to access OneView.
Connect to OneView via secure VPN.
CVSS v3: 9.1
CWE-98: IMPROPER CONTROL OF FILENAME FOR INCLUDE/REQUIRE STATEMENT IN PHP PROGRAM ('PHP REMOTE FILE INCLUSION')
The web service for ONS-S8 - Spectra Aggregation Switch includes functions which do not properly validate user input, allowing an attacker to traverse directories, bypass authentication, and execute remote code. ONS-S8 - Spectra Aggregation Switch: 1.3.7 and prior are affected.
Optigo Networks recommends users always use a unique management VLAN for the port on the ONS-S8 that is used to connect to OneView.
Optigo Networks also recommends users implement at least one of the following additional mitigations:
Use a dedicated NIC on the BMS computer and exclusively this computer for connecting to OneView to manage your OT network configuration.
Set up a router firewall with a white list for the devices permitted to access OneView.
Connect to OneView via secure VPN.
CVSS v3: 9.8
CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition:
This vulnerability occurs when an attacker exploits a race condition between the time a file is checked and the time it is used (TOCTOU). By exploiting this race condition, an attacker can write arbitrary files to the system. This could allow the attacker to execute malicious code and potentially cause file losses.
CVSS v3: 5.3
CWE-24: Path Traversal:
The vulnerability allows an attacker to craft MQTT messages that include relative path traversal sequences, enabling them to read arbitrary files on the system. This could lead to the disclosure of sensitive information, such as configuration files and JWT signing secrets.
CVSS v3: 6.5
CWE-313: CLEARTEXT STORAGE IN A FILE OR ON DISK
The configuration file stores credentials in cleartext. An attacker with local access rights can read or modify the configuration file, potentially resulting in the service being abused because of sensitive information exposure.
Moxa recommends the following to address the vulnerabilities:
CVSS v3: 5.5