Information

File: rdp.c
Function: process_demand_active()

The variable “len_src_descriptor” is parsed from the input stream “s”, and can reach the range: 0 - 0xFFFF.
Later on, the macro “in_uint8s(s, len_src_descriptor)” increments the stream according to “len_src_descriptor”, without checking that the stream contains at least “len_src_descriptor” bytes.
In the following call to “rdp_process_server_caps”, an access violation will occur when reading from a potentially unmapped memory page.

Code Snippet:

in_uint32_le(s, g_rdp_shareid);
in_uint16_le(s, len_src_descriptor);
in_uint16_le(s, len_combined_caps);
in_uint8s(s, len_src_descriptor);

logger(Protocol, Debug, "process_demand_active(), shareid=0x%x", g_rdp_shareid);

rdp_process_server_caps(s, len_combined_caps);

Code Snippet:

void
rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size)
{
	/* Dynamic allocate of destination string if not provided */
	*string = xmalloc(in_len * 2);
	*str_size = in_len * 2;

	...
	else
	{
		int i = 0;
		int rem = 0;
		uint32 len = in_len / 2;

		if (len > *str_size - 1)
		{
			warning("server sent an unexpectedly long string, truncating\n");
			len = *str_size - 1;
			rem = in_len - 2 * len;
		}

		while (i < len)
		{
			in_uint8a(s, &string[i++], 1);
			in_uint8s(s, 1);
		}

		in_uint8s(s, rem);
		string[len] = 0;
		*str_size = len;
	}
}

ASAN Output:

Connection established using SSL.
WARNING: Remote desktop does not support colour depth 24; falling back to 16
=================================================================
==27985==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62100002401c at pc 0x00000045fa2c bp 0x7fff11009140 sp 0x7fff11009130
READ of size 2 at 0x62100002401c thread T0
    #0 0x45fa2b in rdp_process_server_caps /home/XXX/rdesktop-1.8.3/rdp.c:1065
    #1 0x45fe04 in process_demand_active /home/XXX/rdesktop-1.8.3/rdp.c:1110
    #2 0x462de3 in rdp_loop /home/XXX/rdesktop-1.8.3/rdp.c:1723
    #3 0x462cdf in rdp_main_loop /home/XXX/rdesktop-1.8.3/rdp.c:1697
    #4 0x40b88e in main /home/XXX/rdesktop-1.8.3/rdesktop.c:1181
    #5 0x7f656a01c82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #6 0x407bb8 in _start (/home/XXX/rdesktop-1.8.3/rdesktop+0x407bb8)

AddressSanitizer can not describe address in more detail (wild memory access suspected).
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/XXX/rdesktop-1.8.3/rdp.c:1065 rdp_process_server_caps
Shadow bytes around the buggy address:
  0x0c427fffc7b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc7c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc7d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc7e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc7f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c427fffc800: fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffc850: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==27985==ABORTING

Attachments:
CVE-2018-20178_PoC.py
private_no_pass.key
selfsigned.crt

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