CVE-2018-8784
Information
File: libfreerdp\codecs\zgfx.c
Function: zgfx_decompress_segment()
The variable “count” is being derived from the input bitstream when reading using the “zgfx_GetBits()” macro.
Using the “while” loop, and as long as there are “1” bits in the stream, we can enlarge the value of “count” indefinitely.
Later on, the call to “zgfx_history_buffer_ring_read” uses “count”, and triggers a copy loop into “zgfx->OutputBuffer” which is of size 64KB.
Code Snippet:
if (distance != 0)
{
/* Match */
zgfx_GetBits(zgfx, 1);
if (zgfx->bits == 0)
{
count = 3;
}
else
{
count = 4;
extra = 2;
zgfx_GetBits(zgfx, 1);
while (zgfx->bits == 1)
{
count *= 2;
extra++;
zgfx_GetBits(zgfx, 1);
}
zgfx_GetBits(zgfx, extra);
count += zgfx->bits;
}
zgfx_history_buffer_ring_read(zgfx, distance, &(zgfx->OutputBuffer[zgfx->OutputCount]), count);
zgfx_history_buffer_ring_write(zgfx, &(zgfx->OutputBuffer[zgfx->OutputCount]), count);
zgfx->OutputCount += count;
}
References:
https://research.checkpoint.com/reverse-rdp-attack-code-execution-on-rdp-clients
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8784