File: protocols\rdp\channels\rdpsnd\rdpsnd-messages.c
Function: guac_rdpsnd_formats_handler()

  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.

Code Snippet:

/* Remember position in stream */
Stream_GetPointer(input_stream, format_start);

/* Read format */
Stream_Read_UINT16(input_stream, format_tag);
Stream_Read_UINT16(input_stream, channels);
Stream_Read_UINT32(input_stream, rate);
Stream_Read_UINT16(input_stream, bps);

/* Skip past extra data */
Stream_Read_UINT16(input_stream, body_size);
// EI-DBG: No checks that input_stream contains "body_size" bytes.
// EI-DBG: This could be used for a 64KB info leak that will go right back to the RDP server.
Stream_Seek(input_stream, body_size);

/* If PCM, accept */
if (format_tag == WAVE_FORMAT_PCM) {

	/* If can fit another format, accept it */
	if (rdpsnd->format_count < GUAC_RDP_MAX_FORMATS) {
		/* Queue format for sending as accepted */
				18 + body_size);
		// EI-DBG: Writing back the data, and sending it to the RDP server.
		Stream_Write(output_stream, format_start, 18 + body_size);