Talos Vulnerability Report

TALOS-2023-1727

Mitsubishi Electric Corporation MELSEC iQ-F FX5U MELSOFT Direct memory corruption vulnerability

May 26, 2023
CVE Number

CVE-2023-1424

SUMMARY

A memory corruption vulnerability exists in the MELSOFT Direct functionality of Mitsubishi Electric Corporation MELSEC iQ-F FX5U v1.240 and v1.260. A specially crafted network packet can lead to a buffer overflow. An attacker can send a malicious packet to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Mitsubishi Electric Corporation MELSEC iQ-F FX5U v1.240
Mitsubishi Electric Corporation MELSEC iQ-F FX5U v1.260

PRODUCT URLS

MELSEC iQ-F FX5U - https://www.mitsubishielectric.com/fa/products/cnt/plcf/items/index.html

CVSSv3 SCORE

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

CWE

CWE-121 - Stack-based Buffer Overflow

DETAILS

The iQ-F FX5U is one of several members of the iQ-F series of Programmable Logic Controllers from Mitsubishi. The FX5U comes with built-in processor, power supply, Ethernet and 16 I/O points. The PLC can be configured to host several network services, such as an HTTP Server, FTP Server, FTP Client, MODBUS/TCP interface and several Mitsubishi-specific protocols.

The MELSOFT Direct protocol is used by the GXWorks Engineering software tool to interact with the PLC, enabling functionalities such as downloading and uploading files to the device, monitoring diagnostic information, updating device configurations and many others. The service responsible for implementing this protocol on the iQ-F is bound to UDP port 5560.

Each MELSOFT Direct request contains a field identifying the feature set being requested, as well as a second field identifying a subset of the specified feature. We have identified a stack-based buffer overflow in the feature set identified by the constant 0xC, as well as the sub-features identified by the constants 0x10 and 0x11.

For reference, MELSOFT Direct packets received on UDP port 5560 are initially dispatched from a function located at offset 0xffc4e24c in version 1.260 of the iQ-FX5U firmware. The function responsible for parsing the 0xC functionality is located at offset 0xffc4e508, and this feature only implements handlers for command subset 0x10 (at offset 0xffce2602e) and 0x11 (at offset 0xffe260a5). Both the 0x10 and 0x11 implementations make use of a vulnerable function located at offset 0xffe260f4, which is responsible for mapping the provided filepath to an internal reference identifier.

The vulnerable function expects four arguments: * arg1: must always be the value 0x0004 * filepath_length: a value trusted to contain the length of the filepath argument * filepath: a wchar filepath * result: a pointer to where the successful result of this function should be stored

Of these arguments, arg1, filename_length and filename are all taken directly from the incoming MELSOFT Direct packet, and there are no sanitization or validation checks that occur on the supplied filename or filename_length parameters.

The callsite for the 0x10 feature is simply as follows:

0ffe26028    PUSHM    r6-r8
0ffe2602a    SUB      #0x4, sp
0ffe2602c    MOV.l    r1, r8          # A reference to the MELSOFT Direct message structure, passed in `r1`, is copied to r8 to avoid clobbering
0ffe2602e    MOV.w    #0x0, #0x10[r8] 
0ffe26032    MOV.l    #0x8[r8], r7    # move a reference to the packet payload body into `r7`
0ffe26035    MOV.l    #0xc[r8], r6    
0ffe26038    MOVU.w   #0xc[r7], r2    # `filepath_length` = *body->filepath_length
0ffe2603a    MOVU.w   #0xa[r7], r1    # `arg1` = *body->arg1
0ffe2603c    ADD      #0xe, r7, r3    # `filepath` = &body->filepath
0ffe2603f    MOV.l    sp, r4          # `result` = &result
0ffe26041    BSR.W    #sub_ffe260f4   # sub_ffe260f4(*body->arg1, *body->filepath_length, &body->filepath, &result)

Below is an annotated decompilation of the vulnerable portion of function sub_ffe260f4.

0ffe260f4   F_ERR sub_ffe260f4(int16_t arg1, uint16_t filepath_length, wchar16_t* filepath, uint8_t* result)
0ffe26100      uint16_t adjusted_length = filepath_length - 0x12    # Removing `wstrlen("$MELPRJ$")` from the provided length
0ffe26107      if (arg1 != 4)
0ffe26103      {
0ffe26108          return 0x40b0
0ffe26108      }
0ffe26111      else
0ffe26111      {
0ffe2611e          wchar16 filename[0x42]
0ffe2611e          memcpy(&filename, &filepath[9], adjusted_length) # Similarly, this memcpy is intended to remove `$MELPRJ$` directory from the start of the filepath
                                                                    # Note the implicit trust in the attacker-controlled filepath and filepath_length fields
0ffe26128          ...
0ffe26132      }

The vulnerable memcpy call at 0xFFE2611E will attempt to move part of the attacker-controlled filepath into a local stack variable, filename, which is only 0x84 bytes long, but it will do so using the attacker-controlled filepath_length parameter, such that up to 0xFFFF bytes of data can be copied over top of the stack variable. An attacker who sends an 0xC -> 0x10 or 0x11 MELSOFT Direct packet to a vulnerable device can provide arbitrary data that will be used to overflow an inadequately sized stack variable, leading to a denial-of-service within the RTOS task responsible for parsing the MELSOFT Direct protocol, and potentially remote code execution.

VENDOR RESPONSE

Vendor advisory: https://www.mitsubishielectric.com/en/psirt/vulnerability/pdf/2023-003_en.pdf

CISA advisory: https://www.cisa.gov/news-events/ics-advisories/icsa-23-143-03

TIMELINE

2023-02-22 - Vendor Disclosure
2023-05-23 - Vendor Patch Release
2023-05-26 - Public Release

Credit

Discovered by Matt Wiseman of Cisco Talos.