Information

File: rdpsnd.c
Function: rdpsnddbg_process()

When reaching this function we can be in an Out-Of-Bound read situation, meaning that “s->end < s->p”.
This can lead to that “pkglen + 1” will be 0, triggering a memory allocation of zero bytes.
Later on, the “STRNCPY(, , pkglen + 1)” macro will use “pkglen + 1 - 1” == “-1”, doing the following set of actions:

  1. strncpy(dst,src,-1)
  2. dst[-1] = 0
    As “strncpy()” receives a length of type “size_t”, the value “-1” will be interpreted as “4GB”, allowing an unlimited string copy.

Code Snippet:

static void
rdpsnddbg_process(STREAM s)
{
	unsigned int pkglen;
	static char *rest = NULL;
	char *buf;

	pkglen = s->end - s->p;
	/* str_handle_lines requires null terminated strings */
	buf = (char *) xmalloc(pkglen + 1);
	STRNCPY(buf, (char *) s->p, pkglen + 1);

	str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL);

	xfree(buf);
}

ASAN Output:

Connection established using SSL.
WARNING: Remote desktop does not support colour depth 24; falling back to 16
=================================================================
==27914==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000005a71 at pc 0x7fdb029f96c3 bp 0x7ffd0c2939b0 sp 0x7ffd0c293158
WRITE of size 4294967295 at 0x602000005a71 thread T0
    #0 0x7fdb029f96c2 in __interceptor_strncpy (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x766c2)
    #1 0x443c81 in rdpsnddbg_process /home/XXX/rdesktop-1.8.3/rdpsnd.c:676
    #2 0x487109 in channel_process /home/XXX/rdesktop-1.8.3/channels.c:171
    #3 0x455ac2 in sec_recv /home/XXX/rdesktop-1.8.3/secure.c:924
    #4 0x45835c in rdp_recv /home/XXX/rdesktop-1.8.3/rdp.c:108
    #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 0x7fdb010b582f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x407bb8 in _start (/home/XXX/rdesktop-1.8.3/rdesktop+0x407bb8)

0x602000005a71 is located 0 bytes to the right of 1-byte region [0x602000005a70,0x602000005a71)
allocated by thread T0 here:
    #0 0x7fdb02a1b602 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 0x443c43 in rdpsnddbg_process /home/XXX/rdesktop-1.8.3/rdpsnd.c:675
    #3 0x487109 in channel_process /home/XXX/rdesktop-1.8.3/channels.c:171
    #4 0x455ac2 in sec_recv /home/XXX/rdesktop-1.8.3/secure.c:924
    #5 0x45835c in rdp_recv /home/XXX/rdesktop-1.8.3/rdp.c:108
    #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 0x7fdb010b582f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 __interceptor_strncpy
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[01]fa
  0x0c047fff8b50: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c047fff8b60: fa fa fd fd fa fa fd fd fa fa fd fd fa fa 00 02
  0x0c047fff8b70: fa fa 00 02 fa fa 00 00 fa fa fd fa fa fa 00 fa
  0x0c047fff8b80: fa fa 00 fa fa fa 00 00 fa fa 00 00 fa fa 00 fa
  0x0c047fff8b90: fa fa 00 fa fa fa 00 00 fa fa fd fa fa fa 00 00
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
==27914==ABORTING

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