CVE-2024-24963,CVE-2024-24962
A stack-based buffer overflow vulnerability exists in the Programming Software Connection FileSelect functionality of AutomationDirect P3-550E 1.2.10.9. A specially crafted network packet can lead to stack-based buffer overflow. An attacker can send an unauthenticated packet to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
AutomationDirect P3-550E 1.2.10.9
9.8 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-121 - Stack-based Buffer Overflow
The P3-550E is the most recent CPU module released in the Productivity3000 line of Programmable Automation Controllers from AutomationDirect. It is an affordable control CPU which communicates remotely via ethernet, serial, and USB and exposes a variety of control services, including MQTT, Modbus, ENIP and the engineering workstation protocol DirectNET.
The P3-550E exposes a “Programming Software Connection” service over UDP port 9999 that is used by the engineering workstation software to program and otherwise configure the device. The protocol is not well documented and what information we do have is pieced together from reverse engineering efforts.
Each message of the protocol is prefixed with a 12-byte header containing the requesting client’s IP address and originating port, two 16-bit fields only referred to as ‘GBS’ and ‘IMM’, and is followed by a payload which varies by type of request.
0 1
0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| GBS | Client Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Client IP |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IMM | Undetermined |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The first byte of the IMM field acts as a function code, dictating which high-level feature set is being requested, and the second byte dictates the exact functionality expected. The protocol format for the remainder of the message is dependent on the IMM
value.
These two vulnerabiliies arise in the file-system related feature set, reachable when the first byte of IMM
is 0xF
. The function responsible for implementing these features is located at offset 0xb6784
and we refer to it as _DISCOVERY_CALLBACK_F
. Within this function, the second byte of IMM
is used in a switch-case to identify the exact feature being requested. For this report, we are most interested in the implementation of the handler associated with IMM[1] = 0x12
. This sub-function expects the following payload.
0 1
0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Path Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Path |
+ .... +
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Within the switch-case associated with IMM[1] = 0x12
a function we refer to as IMM_0F_FileSelect_Handler
is called, receiving the pkt
variable as its only parameter. It should be noted that this particular feature is one of several requests associated with transferring a file to or from the device. This particular request appears to be used to select the file being transferred. This function begins at offset 0xb6df0
of v1.2.10.9 of the firmware. The vulnerabilities occur quite early in this function, so for the purposes of this report we will only include the first few lines of the decompilation.
0000b6df0 int32_t IMM_0F_FileSelect_Handler(struct packet* pkt) {
0000b6e28 // [1] data_1d7ca0 is a field in a structure used to track ongoing file transfers
0000b6e28 if (data_1d7ca0 != 0 && pkt->path_len != 0) {
0000b6e40 char constructed_filename[0x100];
0000b6e40 strcpy(&constructed_filename, "c:\fw_image");
0000b6e4c strcat(&constructed_filename, "\");
0000b6e64 if (strchr(&pkt->path, '\\') == 0)
// [2] Construct a local copy of the provided filepath and store it into `constructed_filename`
0000b6e98 strncat(&constructed_filename, &pkt->path, pkt->pathlen);
0000b6e84 else
// [2] Construct a normalized local copy of the provided filepath, removing any directory data preceding the file
0000b6e84 strncat(&constructed_filename, &strchr(&pkt->path, '\\')[1], pkt->path_len);
0000b6eb0 constructed_filename[pkt_1->path_len] = 0;
0000b6eb8 ...
0000b6eb8 }
0000b6ed0 ...
The first vulnerability occurs at 0xb6e98
, which is called conditionally based on whether the provided path contains a backslash character. The vulnerability is caused by the call to strncat
, which attempts to construct a filepath using an 0x100 byte long stack-allocated character array, but without any validation that the attacker-provided path_len
will not exceed 0x100 bytes. An attacker who submits an appropriately formatted series of requests can overflow the constructed_filename
stack buffer, potentially corrupting the return address on the stack and gaining remote code execution.
The second vulnerability occurs at 0bx6e84
, which is the alternative condition where the provided path contains directory information. The vulnerability is caused by the call to strncat
, which attempts to construct a filepath using an 0x100 byte long stack-allocated character array, but without any validation that the attacker-provided path_len
will not exceed 0x100 bytes. An attacker who submits an appropriately formatted series of requests can overflow the constructed_filename
stack buffer, potentially corrupting the return address on the stack and gaining remote code execution.
A CISA advisory can be found here: https://www.cisa.gov/news-events/ics-advisories/icsa-24-144-01
2024-02-14 - Initial Vendor Contact
2024-02-15 - Vendor Disclosure
2024-05-23 - Vendor Patch Release
2024-05-28 - Public Release
Discovered by Matt Wiseman of Cisco Talos.