Advanced OPC-UA framework for vulnerability research & exploitation.
Using this framework, we've implemented many unique attacks against OPC-UA implementation - all of which we, or other researchers, responsibly disclosed. So far, using OPC-UA Exploitation Framework
we found & disclosed ~50 CVEs.
In the past few years we (Claroty Research - Team82) conducted an extensive analysis of the OPC-UA network protocol prevalent in operational technology (OT) networks worldwide. During that research, we found and privately disclosed critical vulnerabilities in OPC-UA implementations from a number of leading vendors that have built their respective products on top of the protocol stack. The affected vendors sell these products to companies operating in many industries within the ICS domain and so with each vulnerability found in a protocol-stack library there are many other pieces of software and applications that are becoming vulnerable.
With our OPC-UA Exploitation Framework
we hope that both software companies and OPC-UA vendors could test their code-base and improve the security of their products. We also welcome other security researchers to use this framework and responsibly disclose vulns/bugs they find to the respective vendors.
We used this framework many times, including:
As part of our research we also wrote a detailed series into OPC-UA - OPC UA Deep Dive: A Complete Guide to the OPC UA Attack Surface and even released an OPC-UA Network Fuzzer
We divided the framework to four categories: attacks
, corpus
, sanity
, and server
Sanity
: sanity payloads such as reading nodes, getting 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 implementation (currently one example with 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
,s2opc
- 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 | sanity_read_diag_info |
Server Diagnostics Summary Data |
Get Node ID Info | Node ID is an identifier for a node in an OPC server’s address space. | sanity_get_node_id_info |
NodeID |
Read Nodes | Read service is used to read attributes Nodes | sanity_read_nodes |
Read Service |
Translate Browse Path | Translates browse paths to NodeIds. Each browse path is constructed of a starting Node and a RelativePath | sanity_translate_browse_path |
Translate Browse Path Service |
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: CertA is signed by CertB which is signed by CertA | Denial of Service | certificate_inf_chain_loop |
CVE-2022-37013 |
Chunk Flooding | Sending huge amount of chunks without the Final chunk | Denial of Service | chunk_flood |
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 | open_multiple_secure_channels |
CVE-2023-32787 |
Close Session With Old Timestamp | Sending bad timestamp on closing session leads to an uncaught stacktrace with sensitive information | Information Leakage | close_session_with_old_timestamp |
CVE-2023-31048 |
Complex Nested Message | Sending a complex nested variant leads to a call stack overflow | Denial of Service / Information Leakage | complex_nested_message |
CVE-2022-25903, CVE-2021-27432, CVE-2023-3825 |
Translate Browse Path Call Stack Overflow | Triggering a stack overflow exception in a server that doesn't limit TranslateBrowsePath resolving calls | Denial of Service | translate_browse_path_call_stack |
CVE-2022-29866 |
Thread Pool Wait Starvation | Thread pool deadlock due to concurrent worker starvation | Denial of Service | thread_pool_wait_starvation |
CVE-2022-30551 |
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 | unlimited_persistent_subscriptions |
CVE-2022-25897,CVE-2022-24375,CVE-2022-24298 |
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 | function_call_null_deref |
CVE-2022-1748 |
Malformed UTF8 | Triggering an application crash after processing malformed UTF8 strings | Remote Code Execution | malformed_utf8 |
CVE-2022-2825, CVE-2022-2848 |
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 | race_change_and_browse_address_space |
CVE-2023-32172 |
Unlimited Condition Refresh | Sending many ConditionRefresh method calls leads to uncontrolled memory allocations and eventually to a crash | Denial of Service | unlimited_condition_refresh |
CVE-2023-27321, CVE-2023-27334 CVE-2023-39477 |
We've implemented a couple of corpus usage attacks, mostly to reproduce bugs we found using fuzzers.
opcua_message_boofuzz_db
- can be used to shoot an entire boofuzz db at a targetopcua_message_file
- can be used to shoot an a single file or directory of files with OPC-UA payloads (OPC-UA content itself)
Take a look at the corpus we have collected - input_corpus_minimized
. They are the result of many hours of fuzzing different targets via various methods and tools.
Currently, the server is a stand-alone script which 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 |
---|---|---|---|
PTC Kepware KepServerEx | / |
49320 | kepware |
OPC UA .NET Standard Protocol Stack | /Quickstarts/ReferenceServer |
62541 | dotnetstd |
OPC UA Secure Integration Server | /Softing/dataFEED/Server |
4897 | softing |
Prosys OPC UA Simulation Server | /OPCUA/SimulationServer |
53530 | prosys |
Unified Automation UaGateway | / |
48050 | unified |
Inductive Automation Ignition | / |
62541 | ignition |
Triangle Microworks Scada Data Gateway (SDG) | /SDG |
4885 | triangle |
open62541 OPC-UA Protocol Stack | / |
4840 | open62541 |
Locka99 OPC-UA Protocol Stack | / |
4855 | rust |
Node OPC-UA Protocol Stack | / |
26543 | node-opcua |
Python OPC-UA Protocol Stack | /freeopcua/server/ |
4840 | opcua-python |
Milo OPC-UA Protocol Stack | /milo |
62541 | milo |
S2OPC OPC-UA Protocol Stack | / |
4841 | s2opc |
git clone https://github.com/claroty/opcua-exploit-framework.git
cd opcua-exploit-framework
python3 -m venv venv
source ./venv/bin/activate
pip install -r requirements.txt
then for example, python main.py ignition 10.10.6.40 62541 "" sanity
do python main.py -h
for help
The framework was mainly developed by Claroty Research - Team82 including:
- Vera Mens
- Uri Katz
- Noam Moshe
- Sharon Brizinov
- Amir Preminger
Some of the implemented attacks are based on vulnerabilities and/or research conducted by other researchers including JFrog, Computest Sector7, OTORIO, and others.