Allele Security Alert
ASA-2019-00063
Identifier(s)
ASA-2019-00063, CVE-2018-20180
Title
Integer underflow that leads to a heap-based buffer overflow in function rdpsnddbg_process()
Vendor(s)
rdesktop team
Product(s)
rdesktop
Affected version(s)
rdesktop versions up to and including v1.8.3
Fixed version(s)
rdesktop v1.8.4
Proof of concept
Unknown
Description
rdesktop versions up to and including v1.8.3 contain an integer underflow that leads to a heap-based buffer overflow in function rdpsnddbg_process() and results in a memory corruption and probably even a remote code execution.
Technical details
Throughout the code of the client, there is an assumption that the server sent enough bytes to the client to process. One example for this assumption can be found in the following code snippet below:
void channel_process(STREAM s, uint16 mcs_channel) { uint32 length, flags; uint32 thislength; VCHANNEL *channel = NULL; unsigned int i; STREAM in; ... in_uint32_le(s,length) in_uint32_le(s,flags) if((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST)) { /* single fragment - pass straight up */ channel->process(s); } }
Parsing 2 fields from stream “s” without first checking its size
As we can see, the fields “length” and “flags” are parsed from the stream “s”, without checking that “s” indeed contains the required 8 bytes for this parsing operation. While this usually only leads to an Out-Of-Bounds read, we can combine this vulnerability with an additional vulnerability in several of the inner channels and achieve a much more severe effect.
There are three logical channels that share a common vulnerability:
lspci
rdpsnddbg – yes, this debug channel is always active
seamless
The vulnerability itself can be seen below:
/* process new data from virtual channel */ static void(STREAM *s) { unsigned int pkglen; static char *rest = NULL; char *buf; pkglen = s->end - s->p; /* str_handle_lines requires null terminated strings */ // EI-DBG: In case we over-read here, we can do the following: // EI-DBG: 1. buf = xmalloc(0); // EI-DBG: 2. STRNCPY(buf, s->p,0) // EI-DBG: a) strncpy(buf, s->p, -1) // EI-DBG: b) buf[-1] = '\0' // EI-DBG: And s->p can be controlled using data from the previous packet buf = xmalloc(pkglen + 1); STRNCPY(buf,(char *)s->p,pkglen + 1); ... str_handle_lines(buf,&rest,lspci_process_line,NULL); xfree(buf) }
Integer underflow when calculating the remaining “pkglen”
By reading too much data from the stream, i.e. sending a chopped packet to the client, the invariant that “s->p <= s->end” breaks. This leads to an integer underflow when calculating “pkglen”, and to an additional integer overflow when allocating “xmalloc(pkglen + 1)” bytes for our buffer, as can be seen in my comment above the call to “xmalloc”.
Together with the proprietary implementation of “STRNCPY”, seen below, we can trigger a massive heap-based buffer overflow when copying data to the tiny allocated heap buffer.
#define STRNCPY(dst,src,n) {strncpy(dst,src,n-1); dst[n-1] = 0;}
Proprietary implementation of the “strncpy” function
By chaining together these two vulnerabilities, found in three different logical channels, we now have three remote code execution vulnerabilities.
Credits
Eyal Itkin (Checkpoint Research)
Reference(s)
Reverse RDP Attack: Code Execution on RDP Clients
https://research.checkpoint.com/reverse-rdp-attack-code-execution-on-rdp-clients/
Updated ChangeLog and bumped version to 1.8.4
https://github.com/rdesktop/rdesktop/commit/34b8a18fe5d4de795851defe34b3ad3e1f43532b
CVE-2018-20180
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20180
CVE-2018-20180
https://nvd.nist.gov/vuln/detail/CVE-2018-20180
If there is any error in this alert or you wish a comprehensive analysis, let us know.
Last modified: February 11, 2019