Information

File: rdp.c
Function: process_bitmap_updates()

Variables “width” and “height” are read from the input stream “s” and can be in the range: 0 - 0xFFFF.
Variable “bpp” is read from the input stream “s”, and later on variable “Bpp” can be in the range: 0 - 0x2000
During the “xmalloc(width * height * Bpp)” allocation call there is an Integer Overflow, and the result is chopped to 32 bits.
Using the following values, we were able to set the allocation size to 0 = (0xF000 * 0xF000 * 0x0A00) & 0xFFFFFFFF.
Later on, the following “for” loop will copy input bytes outside of the small array, causing a memory corruption.

Code Snippet:

for (i = 0; i < num_updates; i++)
{
	in_uint16_le(s, left);
	in_uint16_le(s, top);
	in_uint16_le(s, right);
	in_uint16_le(s, bottom);
	in_uint16_le(s, width);
	in_uint16_le(s, height);
	in_uint16_le(s, bpp);
	Bpp = (bpp + 7) / 8;
	in_uint16_le(s, compress);
	in_uint16_le(s, bufsize);

	cx = right - left + 1;
	cy = bottom - top + 1;

	logger(Graphics, Debug,
		   "process_bitmap_updates(), [%d,%d,%d,%d], [%d,%d], bpp=%d, compression=%d",
		   left, top, right, bottom, width, height, Bpp, compress);

	if (!compress)
	{
		int y;
		bmpdata = (uint8 *) xmalloc(width * height * Bpp);
		for (y = 0; y < height; y++)
		{
			in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
				  width * Bpp);
		}
		ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
		xfree(bmpdata);
		continue;
	}

ASAN Output:

Connection established using SSL.
WARNING: Remote desktop does not support colour depth 24; falling back to 16
=================================================================
==17627==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000015100 at pc 0x7f75a3ee5935 bp 0x7ffe3ffa8080 sp 0x7ffe3ffa7828
READ of size 157286400 at 0x621000015100 thread T0
    #0 0x7f75a3ee5934 in __asan_memcpy (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8c934)
    #1 0x460b8f in process_bitmap_updates /home/XXX/rdesktop-1.8.3/rdp.c:1294
    #2 0x486407 in rdp5_process /home/XXX/rdesktop-1.8.3/rdp5.c:89
    #3 0x45841e in rdp_recv /home/XXX/rdesktop-1.8.3/rdp.c:120
    #4 0x462d9c in rdp_loop /home/XXX/rdesktop-1.8.3/rdp.c:1717
    #5 0x462cdf in rdp_main_loop /home/XXX/rdesktop-1.8.3/rdp.c:1697
    #6 0x40b88e in main /home/XXX/rdesktop-1.8.3/rdesktop.c:1181
    #7 0x7f75a258b82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #8 0x407bb8 in _start (/home/XXX/rdesktop-1.8.3/rdesktop+0x407bb8)

0x621000015100 is located 0 bytes to the right of 4096-byte region [0x621000014100,0x621000015100)
allocated by thread T0 here:
    #0 0x7f75a3ef1602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x40c222 in xmalloc /home/XXX/rdesktop-1.8.3/rdesktop.c:1317
    #2 0x44bac0 in tcp_connect /home/XXX/rdesktop-1.8.3/tcp.c:518
    #3 0x44e5cf in iso_connect /home/XXX/rdesktop-1.8.3/iso.c:227
    #4 0x4506a7 in mcs_connect_start /home/XXX/rdesktop-1.8.3/mcs.c:317
    #5 0x455cae in sec_connect /home/XXX/rdesktop-1.8.3/secure.c:944
    #6 0x46311d in rdp_connect /home/XXX/rdesktop-1.8.3/rdp.c:1762
    #7 0x40b779 in main /home/XXX/rdesktop-1.8.3/rdesktop.c:1142
    #8 0x7f75a258b82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 __asan_memcpy
Shadow bytes around the buggy address:
  0x0c427fffa9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffa9e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffa9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffaa00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffaa10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c427fffaa20:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffaa30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffaa40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffaa50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffaa60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffaa70: 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
==17627==ABORTING

Attachments:
CVE-2018-8794_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-8794