Information

File: rdp.c
Function: rdp_in_unistr()

When calling this method from “process_redirect_pdu()” the argument “in_len” is controllable and can be ANY SIGNED int value.
Using a series of Integer-Overflow we can cause the following:
in_len = 0x80000000
xmalloc(in_len * 2) ==> xmalloc(0)
*str_size = in_len * 2 = 0
0x40000000 = len < *str_size - 1 = 0xFFFFFFFF
And a copy loop of 0x40000000 (1GB) will trigger a massive memory corruption.

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
=================================================================
==27872==ERROR: AddressSanitizer: negative-size-param: (size=-2147483648)
    #0 0x7f28fdfac194  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x76194)
    #1 0x4596e9 in rdp_in_unistr /home/XXX/rdesktop-1.8.3/rdp.c:301
    #2 0x462305 in process_redirect_pdu /home/XXX/rdesktop-1.8.3/rdp.c:1594
    #3 0x462e8f in rdp_loop /home/XXX/rdesktop-1.8.3/rdp.c:1731
    #4 0x462cdf in rdp_main_loop /home/XXX/rdesktop-1.8.3/rdp.c:1697
    #5 0x40b88e in main /home/XXX/rdesktop-1.8.3/rdesktop.c:1181
    #6 0x7f28fc66882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #7 0x407bb8 in _start (/home/XXX/rdesktop-1.8.3/rdesktop+0x407bb8)

0x62100001411e is located 30 bytes inside of 4096-byte region [0x621000014100,0x621000015100)
allocated by thread T0 here:
    #0 0x7f28fdfce602 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 0x7f28fc66882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: negative-size-param ??:0 ??
==27872==ABORTING

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