Rapid7 researcher Andreas Galauner has discovered two vulnerabilities affecting the TwinCAT PLC environment. The first, CVE-2019-5637 describes a denial-of-service (DoS) condition resulting from a divide-by-zero error CWE-369 when processing a malformed UDP packet, and has a CVSSv3 base score of 7.5. The second, CVE-2019-5636, describes a DoS condition by removing a routing table after processing an empty UDP packet, and has a CVSSv3 base score of 5.3.

Credit

These issues were discovered by Andreas Galauner of Rapid7 and reported in accordance with Rapid7's vulnerability disclosure policy.

TwinCAT product description

TwinCAT is a PLC runtime developed by the company Beckhoff. It runs on top of Windows and extends the Windows kernel with real-time capabilities, a number of network protocol stacks for industrial fieldbuses, a runtime for programming languages defined in IEC 61131-3, and additional components for motion control.

This runtime is used to perform typical industrial control tasks for use in machines or other industrial processes. Different fieldbuses like EtherCAT, Profinet, CANopen, EtherNet/IP, etc. can be used to attach I/O devices like sensors, actuator or motor controllers, and even other PLCs for periodic data exchange.

Current runtime versions can be installed on Windows 7 or Windows 10 LTSC. These full versions can run on any Windows-compatible machine and turn it into a PLC. However, Beckhoff offers specially designed industrial PCs for use with its software as well. There is a Windows CE-based variant available as a lightweight embedded alternative for use on Beckhoff's industrial PCs if a full Windows OS isn't required.

The following bugs were verified on the following versions of the TwinCAT runtime, which were the latest available from Beckhoff:

  • Version 3.1.4022.30 running two Beckhoff CX2030 and CX5140 industrial PCs using their OEM Windows 10 LTSC 1607 image
  • Version 3.1.4022.29 running on a Beckhoff CX5140 industrial PC on Windows CE

R7-2019-32.1: Profinet DCP DoS (CVE-2019-5637)

Exploitation of TwinCAT CVE-2019-5637

When the TwinCAT environment is configured to be a Profinet controller or device, the Profinet protocol stack is running on the PLC and needs to reply to "Discovery and Configuration Protocol" (DCP) requests, a part of the Profinet protocol suite. It is, as the name suggests, used for initial device discovery and configuration of certain parameters like the station name, network address, and netmask. It is usually done during initial setup of the devices but isn't disabled after that.

Device discovery is performed by sending an "Ident Request" Ethernet broadcast frame to the special MAC Address 01:0e:cf:00:00:00. Along with a transaction ID to associate possible replies from other stations with the request, the service ID and type of the action to be performed, and some additional payload for the requested action, it also contains a field called "ResponseDelay." This field is used to control a delay of the responses sent by the stations answering to the identification request packet. Without this delay and hundreds of devices on a network, the resulting load caused by all stations sending replies out could cause network congestion and lead to dropped responses, or even negatively impact the exchange of important process data.

Impact of TwinCAT CVE-2019-5637

When setting this "ResponseDelay" field to 0, a divide by zero exception is raised on all Beckhoff PLCs that have a Profinet controller or device configured and bound to the network card that received the malicious identification request. The result is an error message on the Desktop informing you about the exception and a crash of the complete PLC runtime, including a stop of all PLC programs and fieldbus activity, which results in a complete halt of the controlled process. After a short while, the TwinCAT runtime gets restarted but remains in CONFIG mode. A manual mode change back from CONFIG into RUN mode is possible after the runtime automatically recovered back into CONFIG mode—or, alternatively, users can configure devices ahead of time to boot directly into RUN mode after a restart.

When trying to find out what exactly that field does, we came across this bug report from the company Hilscher, which specializes in fieldbus communication controllers and the accompanying software stacks implementing all kinds of industrial protocols.

The delay after which the identification response is sent out depends on the two lowermost bytes of the MAC address of the device modulo the delay factor from the packet multiplied by some constant. The modulo operation would explain the division by zero exception in case of a value of 0 for this field in the packet. However, this was not confirmed by disassembling the relevant code from Beckhoff.

R7-2019-32.2: ADS discovery DoS (CVE-2019-5636)

Exploitation of TwinCAT CVE-2019-5636

TwinCAT relies heavily on a protocol called ADS, which is developed by Beckhoff. ADS is used for internal communication between different components in the same runtime, but it can also be tunneled over different other protocols and media like RS232/485 serial ports, EtherCAT, or plain TCP/IP.

ADS itself uses AMS Net IDs and ports that are similar to TCP/IP ports and addresses and packets can be sent from one component to another one. Beckhoff uses a Visual Studio plugin as its development environment. This environment also uses ADS to communicate with all the different subsystems on the runtime to configure them and upload code.

All ADS traffic crossing the boundary of the services running on the PLC itself is usually encapsulated in TCP/IP packets and sent to other machines. The runtime contains a component called the ADS router, described in the vendor's documentation. It listens on a TCP port and accepts AMS packets.

After parsing the packets, the PLC consults a local routing table to determine whether that host is supposed to be able to talk to local PLC components using ADS. If a route to the host that received the AMS/TCP packet from exists, the packet is decapsulated and forwarded to the addressed component on the local PLC. All traffic coming into the router from local ADS components is encapsulated in TCP again and sent out to the IP address associated with the destination AMS Net ID through its routing table.

To initially find devices, a proprietary companion protocol of ADS from Beckhoff can be used. It uses UDP broadcast packets for device discovery and modifications of the aforementioned routing tables. The handler thread executes recvfrom to receive a UDP packet in its runloop, after which it is parsed and an appropriate response is sent back. The receive loop, however, just exits when recvfrom returns 0. For TCP sockets, a recv call can return -1, 0, or n, whereas -1 is returned during an error condition (or when the socket is non-blocking and no data has been received in the meantime), 0 is returned when the opposing side closed the TCP connection, and n is returned when data has been received and n denoting how much. When a TCP connection is handled, the handler thread can usually safely perform local cleanup and exit once the remote connection is closed. UDP, on the other hand, has no concept of a connection. In the case of recvfrom, a return value of 0 means that a UDP packet was received but it was completely empty, which is a valid case for a UDP socket.

Impact of TwinCAT CVE-2019-5636

When sending an empty packet to UDP port 48899 of a PLC, the handler thread responsible for the ADS UDP protocol requests for device discovery or routing table modification exits. After this thread exited, the PLC is not discoverable on the network. All connections using existing routing table information on the PLC can still be used for communication and hence, process data can still be exchanged between PLCs and the development environment.

It is possible to restart the handler thread by switching the runtime into CONFIG or RUN mode, no matter what state the runtime is currently in. A switch from RUN to RUN or CONFIG to CONFIG has the same effect, but the running code is restarted even when switching from RUN mode to RUN mode.

Note, zero-byte UDP packets are sent by nmap and possibly other network scanners to determine whether a UDP port on a host might be open. Therefore, these devices can be temporarily DoS'ed by normal defensive network scanning/vulnerability management activity.

Remediating the TwinCAT vulnerabilities

Both vulnerabilities have been addressed by Beckhoff after being reported by Rapid7. CVE-2019-5636 is addressed by Advisory 2019-004, and CVE-2019-5637 is addressed by Advisory 2019-007. At the time of this disclosure, however, there is no software update available from the vendor.

In the absence of applying updates or implementing mitigations provided by the vendor, users are advised to not allow untrusted UDP packets to reach their TwinCat PLC environment. It is good security hygiene to not expose these devices to the general internet, and instead, keep them on a logically segmented network where only trusted devices and users can communicate with them.

Disclosure timeline

  • Wednesday, July 24, 2019: Initial disclosure to the vendor
  • Friday, July 26, 2019: Acknowledgement from the vendor, CVE IDs reserved
  • Wednesday, Aug. 7, 2019: Advisory 2019-04 for CVE-2019-5636 published
  • Thursday, Aug. 15, 2019: Vendor update regarding CVE-2019-5637
  • Monday, Oct. 7, 2019: Advisory 2019-007 for CVE-2019-5637 published
  • Tuesday, Oct. 8, 2019: R7-2019-32 vulnerability disclosure published (planned)