Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

[R1] RSLinx Classic Buffer Overflows

Critical

Synopsis

While researching Rockwell Automation RSLinx Classic, Tenable found a couple of buffer overflow issues in RSLinx Classic Lite 4.0.1.2. The vulnerabilities may allow an unauthenticated remote attacker to achieve remote code execution or denial of service.

RSLinx Classic Lite (RSLINX.exe) implements the EtherNet/IP protocol which encapsulates Common Industrial Protocol (CIP) messages. An EtherNet/IP packet consists of a 24-byte header followed by command specific data:

struct hdr
{
	uint16 command;	 
	uint16 length;	// length of the command excluding the header
	uint32 SessionHandle;
	uint32 status;
	octet  SenderContext[8];
	unit32 options
};

Inside the command specific data block, various CIP-specific length fields can be specified. These include the length of a type ID (a 2-byte field), the length of a connection path (a 1-byte field), and the length of an extended link address in the port path segment in the connection path.

uint16 TypeLength;		// length of a Type ID
octet  ConnectionPathLength;    // number of 16-bit items 
octet  LinkAddressSize;	        // length of an Extended Link Address

Although RSLINX.exe limits the command specific data block to 4500 bytes:

.text:5878CEDF      movzx   edx, [ecx+CLinxServer.hdr_in.len]
.text:5878CEE6      mov     [ebp+var_BodyLen], edx
.text:5878CEE9      cmp     [ebp+var_BodyLen], 0
.text:5878CEED      jl      short invalid_len
.text:5878CEEF      cmp     [ebp+var_BodyLen], 4500 ; command specific block max length
.text:5878CEF6      jle     short read_body

It does not check various CIP-specific length fields against the number of received network data in many code paths. An unauthenticated remote attacker can exploit this to cause memory corruption issues.

CVE-2018-14829: Stack Buffer Overflow

There is a function in ENGINE.dll that parses a connection path to extract a port path segment and stores it in a stack buffer. The attacker can specify a large port path segment to overflow the stack buffer:

.text:6950B0E4      movzx   eax, [ebp+var_sizeFromPortSeg] ; size from input port path segment; attacker-controlled
.text:6950B0E8      push    eax ; size_t
.text:6950B0E9      mov     ecx, [ebp+var_pConnPath]
.text:6950B0EC      push    ecx ; void *
.text:6950B0ED      mov     edx, [ebp+arg_pOut_PortSegLen] ; set to 0 on function entry
.text:6950B0F0      movzx   eax, word ptr [edx]
.text:6950B0F3      add     eax, [ebp+arg_pOut_PortSeg] ; buffer on the stack; 128ish bytes
.text:6950B0F6      push    eax ; void *
.text:6950B0F7      call    memcpy

The attacker can specify up to 255 bytes of port path segment as the length field for the segment is 1-byte wide. On a 32-bit Windows 7 SP1 with ENGINE.dll version 4.0.1.2, the stack buffer is about 0xD4 bytes from the function return address. So the local variables after stack buffer and data after the return address can be overwritten. The following WinDbg output shows 0x102 bytes of attacker-controlled data is being copied to a 128-byte stack buffer:

0:018> r
eax=07faf988 ebx=0015f328 ecx=012d2dba edx=07fafa0a esi=012e9508 edi=00000674
eip=6950b0f7 esp=07faf6ec ebp=07faf738 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ENGINE!ReleaseASADispatcherPathHandle+0x93a7:
6950b0f7 e8869f0700      call    ENGINE!VLink_FindFirstLinkID+0xaac2 (69585082)
0:018> dd esp L3
07faf6ec  07faf988 012d2dba 00000102
0:018> db 012d2dba L102
012d2dba  10 ff 41 41 41 41 41 41-41 41 41 41 41 41 41 41  ..AAAAAAAAAAAAAA
012d2dca  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2dda  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2dea  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2dfa  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e0a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e1a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e2a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e3a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e4a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e5a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e6a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e7a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e8a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2e9a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2eaa  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
012d2eba  41 01

CVE-2018-14821 - Heap Buffer Overflow

When type ID 0xb2 is specified in command 0x6f (send RR data), the type's data is copied to a heap buffer within a CPacket object. If the attacker specifies a large type length, they can overflow the heap buffer in the CPacket object:

.text:5F6421B3      jle     short loc_5F6421D3
.text:5F6421B5      movzx   ecx, [ebp+arg_TypeDataLen] ; attacker-controlled len up to 0xffff
.text:5F6421B5                                         ; heap overflow!
.text:5F6421B9      push    ecx                        ; size_t
.text:5F6421BA      mov     edx, [ebp+arg_pTypeData]   ; attacker-controlled data
.text:5F6421BD      push    edx                        ; void *
.text:5F6421BE      mov     eax, [ebp+var_pCPacket]
.text:5F6421C1      mov     ecx, [eax+CPacket.pAppData]
.text:5F6421C7      add     ecx, TYPE.data
.text:5F6421CA      push    ecx                        ; heap buffer of 0x1330ish bytes
.text:5F6421CB      call    _memcpy

The vulnerable function attempts to copy 0x1fff bytes from the source buffer to a heap buffer. However, the destination heap buffer has less than that. An exception is thrown when attempting to copy 0x1fff bytes of data to a heap buffer of less than 0x1336 bytes:

0:017> g
(80c.f38): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000071 ebx=0027f488 ecx=00000000 edx=00000000 esi=016e9418 edi=000006a8
eip=69364e8e esp=08e5f6e4 ebp=08e5f750 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
ENGINE!CProtocolASA::OnRequestMsg+0xee:
69364e8e 668901          mov     word ptr [ecx],ax        ds:0023:00000000=????

Solution

Rockwell has issued patches and provided users with a list of recommended actions. Read their advisory for full details.

Disclosure Timeline

06-28-2018 - Vulnerabilities reported via encrypted email to Rockwell. Advised of 90 day deadline on September 28, 2018.
06-28-2018 - Rockwell responds that Tenable encrypted with an old key.
06-29-2018 - Tenable resends using the correct key.
06-29-2018 - Rockwell acknowledges the report and disclosure deadline.
07-25-2018 - Tenable asks for an update.
07-26-2018 - Rockwell says the team is still investigating.
09-17-2018 - Tenable asks for an update.
09-17-2018 - Rockwell indicates they plan to disclose on September 20th. Already coordinated with ICS-CERT. Asks Tenable if they need anything.
09-17-2018 - Tenable asks for a draft of the advisory. Offers to validate patches.
09-19-2018 - Rockwell provides a draft. Declines Tenable's offer to verify patches.
09-19-2018 - Tenable thanks Rockwell.
09-20-2018 - Rockwell publishes their advisory.

All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.

Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.

For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.

If you have questions or corrections about this advisory, please email [email protected]

Risk Information

Tenable Advisory ID: TRA-2018-26
CVSSv2 Base / Temporal Score:
10.0 / 7.4
CVSSv2 Vector:
AV:N/AC:L/Au:N/C:C/I:C/A:C
Nessus Plugin ID: 117671
Affected Products:
RSLinx Classic 4.00.01 and earlier
Risk Factor:
Critical
Additional Keywords:
ICSA-18-263-02

Advisory Timeline

09-20-2018 - [R1] Initial Release