Information

File: bitmap.c
Function: process_plane()

Although the loop checks that “indexw < width”, later on the inner loop can write up to “collen” bytes into the output buffer.
Using the following values (as an example) we can write outside of the allocated heap buffer:
width = 1
height = 1
Bpp = 4 (otherwise we won’t reach this function)
code = 0xFF
replen = 0xF
collen = 0xF
revcode = 0xFF
And the inner loop will preform 0xF write operations, although “width” should be limited to 1.

Code Snippet:

if (last_line == 0)
{
	while (indexw < width)
	{
		code = CVAL(in);
		replen = code & 0xf;
		collen = (code >> 4) & 0xf;
		revcode = (replen << 4) | collen;
		if ((revcode <= 47) && (revcode >= 16))
		{
			replen = revcode;
			collen = 0;
		}
		while (collen > 0)
		{
			color = CVAL(in);
			*out = color;
			out += 4;
			indexw++;
			collen--;
		}

ASAN Output:

Connection established using SSL.
WARNING: Remote desktop does not support colour depth 24; falling back to 16
=================================================================
==17795==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000005a77 at pc 0x000000483491 bp 0x7ffee2724f90 sp 0x7ffee2724f80
WRITE of size 1 at 0x602000005a77 thread T0
    #0 0x483490 in process_plane /home/XXX/rdesktop-1.8.3/bitmap.c:799
    #1 0x48383d in bitmap_decompress4 /home/XXX/rdesktop-1.8.3/bitmap.c:877
    #2 0x4839bf in bitmap_decompress /home/XXX/rdesktop-1.8.3/bitmap.c:910
    #3 0x460d3b in process_bitmap_updates /home/XXX/rdesktop-1.8.3/rdp.c:1318
    #4 0x486407 in rdp5_process /home/XXX/rdesktop-1.8.3/rdp5.c:89
    #5 0x45841e in rdp_recv /home/XXX/rdesktop-1.8.3/rdp.c:120
    #6 0x462d9c in rdp_loop /home/XXX/rdesktop-1.8.3/rdp.c:1717
    #7 0x462cdf in rdp_main_loop /home/XXX/rdesktop-1.8.3/rdp.c:1697
    #8 0x40b88e in main /home/XXX/rdesktop-1.8.3/rdesktop.c:1181
    #9 0x7f02e969982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x407bb8 in _start (/home/XXX/rdesktop-1.8.3/rdesktop+0x407bb8)

0x602000005a77 is located 3 bytes to the right of 4-byte region [0x602000005a70,0x602000005a74)
allocated by thread T0 here:
    #0 0x7f02eafff602 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 0x460d10 in process_bitmap_updates /home/XXX/rdesktop-1.8.3/rdp.c:1317
    #3 0x486407 in rdp5_process /home/XXX/rdesktop-1.8.3/rdp5.c:89
    #4 0x45841e in rdp_recv /home/XXX/rdesktop-1.8.3/rdp.c:120
    #5 0x462d9c in rdp_loop /home/XXX/rdesktop-1.8.3/rdp.c:1717
    #6 0x462cdf in rdp_main_loop /home/XXX/rdesktop-1.8.3/rdp.c:1697
    #7 0x40b88e in main /home/XXX/rdesktop-1.8.3/rdesktop.c:1181
    #8 0x7f02e969982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/XXX/rdesktop-1.8.3/bitmap.c:799 process_plane
Shadow bytes around the buggy address:
  0x0c047fff8af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff8b40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[04]fa
  0x0c047fff8b50: fa fa fd fd fa fa fd fd fa fa fd fd fa fa 00 02
  0x0c047fff8b60: fa fa 00 02 fa fa 00 00 fa fa fd fa fa fa 00 fa
  0x0c047fff8b70: fa fa 00 fa fa fa 00 00 fa fa 00 00 fa fa 00 fa
  0x0c047fff8b80: fa fa 00 fa fa fa 00 00 fa fa fd fa fa fa 00 00
  0x0c047fff8b90: fa fa 00 07 fa fa 00 00 fa fa 00 07 fa fa fd fd
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
==17795==ABORTING

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