Talos Vulnerability Report

TALOS-2019-0771

Schneider Electric UnityPro PLC simulator remote code execution vulnerability

June 10, 2019
CVE Number

CVE-2019-6808

Summary

An exploitable remote code execution vulnerability exists in the UMAS strategy programming functionality of the Schneider Electric Unity Pro L Programming Software PLC Simulator. A specially crafted sequence of UMAS commands sent to the software’s PLC simulator can cause a modified strategy to be programmed, resulting in code execution when the simulator is switched into the start mode. An attacker can send unauthenticated commands to trigger this vulnerability.

Tested Versions

Unity Pro L V13.0 - 170914B EcoStruxure Control Expert V14.0 - 190112

Product URLs

https://www.schneider-electric.com/en/work/campaign/m580-epac/

CVSSv3 Score

10.0 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-284: Improper Access Control

Details

The Modicon M580 is the latest in Schneider Electric’s Modicon line of programmable automation controllers. The device contains a Wurldtech Achilles Level 2 certification and global policy controls to quickly enforce various security configurations. Communication with the device is possible over FTP, TFTP, HTTP, SNMP, EtherNet/IP, Modbus and a management protocol referred to as “UMAS.”

To aid in the testing process of developed strategies, a PLC simulator is included in UnityPro. When the simulator mode is started, it opens 0.0.0.0:502 on the host, allowing for any supported UMAS command to be sent and executed by the system, including the programming of a new device strategy.

When programming a new strategy to the PLC simulator, six UMAS commands must be used in a specific order. First a valid session and additional privilege must be obtained via a TAKE_PLC_RESERVATION request. This request gives the session the ability to successfully send privileged commands.

The structure of a TAKE_PLC_RESERVATION command takes a form similar to:

    0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C | D | E |   F   | G |               H
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1                          < H continued >
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

A --> Modbus Function Code (0x5A)
B --> Session
C --> UMAS Function Code   (0x10)
D --> Unknown              (0x3B)
E --> Unknown              (0x0E)
F --> Unknown              (0x0000)
G --> Client Name Length   (size of Client Name)
H --> Client Name          (variable size)

With a valid reservation obtained an INITIALIZE_UPLOAD command must be sent, indicating that the new program will be following. The structure of a INITIALIZE_UPLOAD command takes a form similar to:

    0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C |   D   |
  +---+---+---+---+---+

A --> Modbus Function Code (0x5A)
B --> Session
C --> UMAS Function Code   (0x30)
D --> Unknown              (0x0001)

After the upload has been initialized, the first block of data must be sent to the device using an UPLOAD_BLOCK command. Failure to do so will prevent the device from accepting the upload. The structure of a UPLOAD_BLOCK command takes a form similar to:

    0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C |   D   |   E   |   F   |               G
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1                          < G continued >
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

A --> Modbus Function Code (0x5A)
B --> Session
C --> UMAS Function Code   (0x31)
D --> Unknown              (0x0001)
E --> Block Number
F --> Block Size           (0x03F4)
G --> Data                

Next a command with the function code 0x6D must be sent. The structure of the 0x6D command takes a form similar to:

    0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C |
  +---+---+---+

A --> Modbus Function Code (0x5A)
B --> Session
C --> UMAS Function Code   (0x6D)

When this command is successfully received, the new strategy must be sent to the device in chunks of size 0x3F4 using the UPLOAD_BLOCK command. When sending the strategy it is important to resend the first block. Failure to do so will prevent the device from accepting the upload. Once the strategy has been successfully sent, an END_STRATEGY_UPLOAD request must be sent to indicate that the last block has been sent. The structure of a END_STRATEGY_UPLOAD command takes a form similar to:

    0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C |   D   |   E   |
  +---+---+---+---+---+---+---+

A --> Modbus Function Code (0x5A)
B --> Session
C --> UMAS Function Code   (0x32)
D --> Unknown              (0x0001)
E --> Blocks Sent

Finally, a RELEASE_PLC_RESERVATION command must be sent to give back the device reservation and restore the normal operating state. The structure of a RELEASE_PLC_RESERVATION command takes a form similar to:

    0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C | 
  +---+---+---+

A --> Modbus Function Code (0x5A)
B --> Session
C --> UMAS Function Code   (0x11)

When this process is used to transfer a modified strategy to the PLC simulator, it is possible to gain code execution by replacing the strategy’s logic with any desired shellcode and recalculating all necessary integrity checks.

Timeline

2019-01-29 - Vendor Disclosure
2019-04-17 - 90 day notice, extended public disclosure to 2019-05-29
2019-04-19 - Vendor provided timeline estimates for fixes/disclosures for multiple issues
2019-05-14 - Vendor patched
2019-05-20 - Vendor confirmed CVE assignment
2019-06-10 - Public Release

Credit

Discovered by Jared Rittle of Cisco Talos.