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=????