File: protocols\rdp\plugins\guacai\guacai-messages.c
Function: guac_rdp_ai_read_format()

  1. When handling the RDP servers’ sound formats, the structure of each format is parsed from the network stream, and handled by the client.
  2. Each such struct also includes a variable length of extra data bytes with a matching length field (body_size) of 16 bits.
  3. Although skipped by the client, the entire format, including the extra body bytes, is sent back in the reply to the server.
  4. There are missing checks that the incoming request is big enough to include all of these extra bytes.
  5. A server could trick the client to send back more data than was initially received, thus triggering a massive information disclosure of up to 64KB.
    Note: This channel (guacai := Audio Input) is “off” by default.

Code Snippet:

/* Read audio format into structure */
Stream_Read_UINT16(stream, format->tag); /* wFormatTag */
Stream_Read_UINT16(stream, format->channels); /* nChannels */
Stream_Read_UINT32(stream, format->rate); /* nSamplesPerSec */
Stream_Read_UINT32(stream, format->bytes_per_sec); /* nAvgBytesPerSec */
Stream_Read_UINT16(stream, format->block_align); /* nBlockAlign */
Stream_Read_UINT16(stream, format->bps); /* wBitsPerSample */
Stream_Read_UINT16(stream, format->data_size); /* cbSize */

/* Read arbitrary data block (if applicable) */
if (format->data_size != 0) {
    format->data = Stream_Pointer(stream); /* data */
    // EI-DBG: Using a 16-bit length field, without a check that enough
    // EI-DBG: input was indeed received.
    Stream_Seek(stream, format->data_size);