Information

File: protocols\rdp\channels\rdpsnd\rdpsnd.c
Function: guac_rdpsnd_process_receive()

  1. When handling incoming rdpsnd PDU messages, the header of each PDU is parsed, and a length field (body_size) of 16 bits is extracted from it.
  2. There are missing checks that the incoming request is big enough to include so many input bytes.
  3. An RDP server could trick the proxy to encode (raw_encode := practically a memcpy) up to 64KB bytes from its memory and send them as “audio” to the remote client.

Code Snippet:

/* Read RDPSND PDU header */
Stream_Read_UINT8(input_stream, header.message_type);
Stream_Seek_UINT8(input_stream);
// EI-DBG: Should verify that the input indeed contains header.body_size amount of bytes.
// EI-DBG: Later on, these bytes will be written to the sound encoders, and disclose memory data.
Stream_Read_UINT16(input_stream, header.body_size);

/* Write rest of audio packet */
if (audio != NULL) {
    // EI-DBG: Here the “buffer” is sent to the client, although the proxy didn't receive so much input.
    guac_audio_stream_write_pcm(audio, buffer, rdpsnd->incoming_wave_size + 4);
    guac_audio_stream_flush(audio);
}


References:
https://research.checkpoint.com/2020/apache-guacamole-rce/
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-9497
https://github.com/apache/guacamole-server/commit/a0e11dc81727528224d28466903454e1cb0266bb