ASA-2019-00062 – rdesktop: Integer underflow that leads to a heap-based buffer overflow in function lspci_process()


Allele Security Alert

ASA-2019-00062

Identifier(s)

ASA-2019-00062, CVE-2018-20179

Title

Integer underflow that leads to a heap-based buffer overflow in function lspci_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 lspci_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-20179
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20179

CVE-2018-20179
https://nvd.nist.gov/vuln/detail/CVE-2018-20179

If there is any error in this alert or you wish a comprehensive analysis, let us know.

Last modified: February 11, 2019

We are not responsible for any data loss, device corruption or any other type of issue due to the use of any information mentioned in our security alerts.