This is Part 1 of Team82's OPC UA Deep Dive series, a comprehensive guide to the security of the OPC UA network protocol for unified OT communication.
Team82 kicks off it's OPC UA Deep Dive Series
Part 1 is a history lesson the OPC protocol, the prevalent OT networking protocol
We will examine in Part 1 how and why OPC evolved into different flavors of the protocol
In the past few years Team82 has conducted an extensive analysis of the OPC network protocol prevalent in operational technology (OT) networks worldwide. During that research, Claroty found and privately disclosed critical vulnerabilities in OPC 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.
In a series of blogs that begins today, we intend to share the knowledge we have learned through our journey, starting here in Part 1 with a history lesson on OPC, why connectivity made a standard communication protocol a necessity, and a deeper dive into some of the foundational OPC flavors.
Future parts in this series will explore the OPC attack surface, security features in the protocol, and attack vectors. We’ll go in depth on each and also discuss how we can better protect and improve this vital communication protocol.
Operational technology (OT) describes equipment that controls physical processes in the real world, whether passively recording information about a process or actively monitoring and/or changing its values. Industrial control systems (ICS) include all sorts of devices and protocols; however, one of their major components is the programmable logic controller (PLC). A PLC is the device responsible for the correct operation of field devices such as sensors, pumps, servomechanisms, and other devices.
One challenge is the lack of interoperability between ICS/SCADA protocols and the PLCs using them. Most protocols are proprietary, and often products from different vendors are unable to exchange data. The development of the OPC protocol was meant to solve this problem. The idea was to create a standardized protocol for process control to allow easy maintenance from a single server that is capable of communicating with all endpoint devices in the OT network.
The OPC Foundation defines OPC as the interoperability standard used for the secure and reliable exchange of data in the industrial automation environment and in other industries; the fact that OPC is platform independent allows devices from different vendors to seamlessly communicate.
To achieve this goal, a few components were introduced:
The OPC server includes protocol converters that are capable of communicating with devices, such as PLCs, using their proprietary protocols, including Modbus, EtherNet/IP, S7, and more. The OPC server will constantly query devices for specific predefined memory values that are known as tags or points, and store them in a special database. Later, an OPC client, such as an human machine interface (HMI), can communicate with the server using the generic OPC protocol to get the values of these tags/points. Lastly, the OPC gateway is responsible for converting proprietary protocols into OPC.
The first generation of the OPC standard and specification was developed 25 years ago. It was created to abstract PLC-specific protocols such as Modbus and Profibus, for example, into a standardized interface. This would allow HMIs and other SCADA systems to interface with “a middle man” that would convert OPC read/write requests for proprietary devices. This gave birth to a segment of the ICS and SCADA markets filled with products that seamlessly interact through implementations of the OPC standard.
The original protocol, OPC Classic, enabled devices built on different specifications to exchange process data, alarms, and historical data. OPC Classic specifications consisted of:
OPC Data Access (OPC DA)
OPC Alarms & Events (OPC AE)
OPC Historical Data Access (OPC HDA)
OPC XML Data Access (OPC XML DA)
OPC Data eXchange (OPC DX)
Each had its own read/write and other commands that applied to one protocol at a time, regardless of whether an OPC server supported multiple protocols. Data access (DA) is the oldest and most common; it extracts data from control systems and communicates with other systems on a shop floor.
At its core, OPC Classic is built on Windows, using COM/DCOM (Distributed Component Object Model) for communication among software components in a distributed client-server network. Initially, OPC was Windows-only (its acronym comes from OLE, or object linking and embedding, for Process Control). OPC Classic is widely adopted in many sectors such as manufacturing, building automation, oil and gas, renewable energy, and utilities, among others.
As manufacturing and technology evolved toward service oriented architectures (SOA), data modeling and security challenges bubbled to the surface. This prompted the OPC Foundation to develop OPC UA (Unified Architecture) to address these issues and at the same time provide a feature-rich technology and open-platform architecture that was future-proof, scalable and extensible.
The original OPC Classic protocols had nothing in common. Each of the protocols—DA, AE, HDA, XML DA, and DX—have their own commands that apply only to the respective protocol, regardless if the OPC server supported several protocols. We will cover each in this section.
The Data Access protocol extracts data from control systems and communicates that information to other systems on the shop floor. It represents actual device values such as timestamps, temperatures, and more.
Unlike the DA protocol, alarms and events have no current value. It’s similar to a subscription-based service where clients receive every event. Events are not tagged, and have no name or quality attribute.
HDA contains historical data and supports long record sets for one or more data points. It was designed to provide a unified way to extract and distribute historical data stored in SCADA or historian systems.
OPC UA, unlike OPC Classic, does not rely on Microsoft OLE or COM/DCOM for communication; therefore, it’s cross-platform and can be used on various operating systems including Mac, Linux, or Windows systems. Also, structures or models may be used with UA, meaning that data tags or points can be grouped and be given context, simplifying governance and maintenance. Models may be identified in runtime, making it possible for clients to explore possible connections by making a server request.
OPC UA supports numerous custom and proprietary transport capabilities, and must do so in order to be a scalable solution. This architecture can be found in everything from shop floor sensors to Windows servers.
The OPC UA specification defines several transports that clients are required to support. This includes SOAP over HTTP/HTTPS or raw OPC UA over TCP transport. The latter is designed for server devices lacking the resources to implement XML encoding and HTTP/SOAP type transports. UA TCP uses binary encoding and a simple message structure that can be implemented on low-end servers.
OPC UA transports are powerful mechanisms that allow standardized messages to be sent between the factory floor, crossing the OT spectrum to communicate with IoT/IT devices. This is accomplished through OPC UA requests to read/write attributes using standard web services languages and protocols. For example, UA requests and responses can be encoded as XML inside SOAP requests and transferred to IT applications that are interoperable with these mechanisms.
With the significant amount of sub-protocols and transport layers, a new component had to be introduced into the network architecture: the OPC Gateway, also known as an OPC Tunneller. The OPC Gateway allows for connections between different OPC servers and OPC clients regardless of the specific OPC protocol being used, vendor, version, or number of connections each OPC Server supports. For example, using an OPC gateway, you can connect any OPC DA server or client to any OPC UA server or client, locally or over the plant network.
Our network diagram now looks like this:
As mentioned earlier, DCOM is used as the lower transport for the OPC DA service. This means that the initial connection is constructed above a DCERPC connection—the remote procedure call used in distributed computing environments—with OPC functionality. From a high-level perspective, the connection starts when the client initiates a DCOM connection, then the parties synchronize the mapped interfaces, which means each interface gets a unique identifier, and finally the client is able to use the functions exposed by the OPC interfaces, such as add group or item.
The following diagram shows the basic connection initialization of DCERPC. After the TCP handshake, the client binds to the
IOXIDResolver interface and calls the
ServerAlive2 method. The server replies with a
ServerAlive2 response which contains a string and security bindings (for example the server’s different IP addresses) and the client chooses the best settings that are compatible with both client and server. Finally the
RemoteCreateInstance is called and the connection moves to a new high port for further OPC communications.
The OPC protocol, like all COM-based protocols, has pre-built interfaces that describe the OPC functionality that can be called remotely. After the initial connection is made, the client maps these interfaces, which are identified by their UUID, to a
Context ID using the
AlterContext method. After the mapping is done the
Context ID is used as the identifier for the interface. This means that to know which interface is called, one needs to also have the
AlterContext packet sequence that mapped the UUID to the interface.
Each interface has predefined functions that are addressable by the
opnum parameter. As with every COM object which implements the
IUnknown interface, the first three functions are always
Release so the actual function
opnum begins right after the
OPC Groups provide a mechanism to logically organize items. Groups allow you to control and manage multiple items at once. Each group also has its own custom parameters and reading mechanism. Items must be inside a group so adding a group is usually what you see after mapping the interfaces.
Items are data points that represent elements. For example, an item can represent the current temperature received from a temperature sensor. The client can interact with items using item handles which represent the connection to a data source in the server and have
TimeStamp attributes associated with them. Item handles are obtained by calling the
AddItem method. The client first browses the server items using the
Browse method and obtains the
itemID linked to each item. The client sends the
AddItem command along with the
itemID of the requested item and finally, the server returns a handle for that item.
Given all this information, here is a typical OPC DA packet sequence to read an item from the OPC server:
And here is a an example of OPC read item request as we captured in Wireshark:
Every OPC UA message starts with a three byte ASCII code that makes the message type. The four main message types are:
HEL: Hello message
MSG: A generic message container (secured with the channel’s keys)
The first message sent is the
HEL message. The
HEL message contains basic parameters to initialize the connection, such as the URL that the client wished to connect to, and the maximum message size the client expects to receive. The
HEL message is typically followed by the
OPN opens the secure channel, and if all goes well, the server responds with the
SecureChannelID. With the channel open, the client and server can send
MSG type messages over the open channel. For example, a common message being used is the
MonitoredItemsCreate which the client uses in order to track items. The session ends with the
CLO message which terminates the connection.
Here is a typical example of OPC UA packets sequence flow to monitor items’ values:
Beside the normal reading method where a client periodically reads data from the server, OPC UA provides a more efficient way of transferring data using subscriptions. In the subscription model, the client specifies which items to track and the server takes care of the monitoring of these items. The client will only be notified in case of a change in one of the monitored items. The client can subscribe to the change of data values, object events, or aggregated values calculated at a client-defined interval.
Team82 has conducted extensive research into OPC, the network protocol that standardizes communication within OT networks. OPC is a critical facet of OT cybersecurity as well given that it ensures the integrity of data exchanged between devices built on proprietary ICS and SCADA protocols. OPC is the standardized protocol for process control that allows easy maintenance from a single server that is capable of communicating with all endpoint devices in the OT network.
In part one of Team82’s series examining the OPC protocol, we look at its history and the different flavors of OPC that have been developed throughout the past two decades. This blog sets the table for the remainder of this series, which will examine the OPC attack surface, security features in the protocol, and attack vectors. In the next part of this series, we’ll dig deeper into OPC-UA, the dominant specification today.
CWE-749 Exposed Dangerous Method or Function
When user authentication is not enabled the shell can execute commands with the highest privileges. Red Lion SixTRAK and VersaTRAK Series RTUs with authenticated users enabled (UDR-A) any Sixnet UDR message will meet an authentication challenge over UDP/IP. When the same message comes over TCP/IP the RTU will simply accept the message with no authentication challenge.
CVSS V3: 10
CWE-288: Authentication Bypass Using an Alternative Path or Channel
Red Lion SixTRAK and VersaTRAK Series RTUs with authenticated users enabled (UDR-A) any Sixnet UDR message will meet an authentication challenge over UDP/IP. When the same message is received over TCP/IP the RTU will simply accept the message with no authentication challenge.
CVSS V3: 10
The vulnerability is caused by the using deprecated deserialization functions and/or classes such as BinaryFormatter in the zenon internal graphic utility DLLs.
CVSS V3: 6.3
The vulnerability is caused by the default directory permissions for the Zenon Projects directory in the engineering studio default workspace. By allowing access to all the users on the system, the attacker may alter the zenon project itself to load arbitrary zenon projects in the zenon runtime.
CVSS V3: 5.9
Code Execution through overwriting service executable in utilities directory. The vulnerability is caused by the weakly configured default directory permission for the ABB Utilities directory.
CVSS V3: 7.0