Information

File: libfreerdp\codec\nsc.c
Function: nsc_rle_decode()

The decode loop makes sure that “left > 4” since the last operation in the function will copy 4 bytes from the input to the output: “((UINT32)out) = ((UINT32)in);”.
However, the write operation does not check this condition, meaning that if “left” will be reduced to “1” (for example), the write operation will write 3 (= 4 - 1) bytes outside of the “out” buffer.

Code Snippet:

static void nsc_rle_decode(BYTE* in, BYTE* out, UINT32 originalSize)
{
	UINT32 len;
	UINT32 left;
	BYTE value;
	left = originalSize;

	while (left > 4)
	{
		value = *in++;

		if (left == 5)
		{
			*out++ = value;
			left--;
		}
		else if (value == *in)
		{
			in++;

			if (*in < 0xFF)
			{
				len = (UINT32) * in++;
				len += 2;
			}
			else
			{
				in++;
				len = *((UINT32*) in);
				in += 4;
			}

			FillMemory(out, len, value);
			out += len;
			left -= len;
		}
		else
		{
			*out++ = value;
			left--;
		}
	}

	*((UINT32*)out) = *((UINT32*)in);
}


References:
https://research.checkpoint.com/reverse-rdp-attack-code-execution-on-rdp-clients
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8788