TUCoPS :: Windows Apps :: win3615.htm

VNC Exploits
23th Jan 2001 [SBWID-3615]
COMMAND

	    VNC

	

	

SYSTEMS AFFECTED

	    ATT VNC up to version 3.3.3 on all supported platforms.

	

	

PROBLEM

	    Following is based ona CORE SDI Security Advisory CORE-2001011501.

	    As stated in the VNC home page:

	
	        "VNC stands for Virtual Network Computing.  It is, in essence,

	        a remote display system which  allows you to view a  computing

	        'desktop'  environment  not  only  on  the machine where it is

	        running, but  from anywhere  on the  Internet and  from a wide

	        variety of machine architectures".

	

	    VNC uses a challenge/response mechanism for authenticating clients

	    in order  to avoid  the transmition  of clear  text passwords over

	    insecure channels and prevent  unauthorized clients to get  access

	    to the VNC server.

	

	    A design flaw  in the client  authentication mechanism permits  an

	    attacker to obtain legit credentials from a valid client in  order

	    to gain  unauthorized access  to the  server.   The attack  can be

	    perfomed   by   an   attacker   eavesdropping   the  client/server

	    communications with the ability to  modify the data flow.   NO TCP

	    hijacking techniques are required.

	

	    There are other security issues related to the fact that VNC  does

	    not   provide   a   secure   transport   protocol   that   ensures

	    confidentiality for the data transmited, those are well known  and

	    considered design decisions from  the VNC development team.   This

	    advisory does not include them, the advisory addresses a  security

	    flaw in the design of  the authentication mechanism that makes  it

	    unsuitable to fulfill its design goal.

	

	    This vulnerability was found by Emiliano Kargieman, Agustin Azubel

	    and Maximiliano Caceres from Core SDI.

	

	    1. Man in the middle attack against client/server authentication

	    ================================================================

	    VNC authenticates communication between client and server using  a

	    challenge-response  mechanism.   Due   to  design  flaws  in   the

	    challenge/response mechanism it is possible to perfom a man in the

	    middle attack and obtain unauthorized access to the VNC server.

	

	    The client authentication mechanism is described below.

	

	    Asumming that C  (the VNC client)  is trying to  authenticate to S

	    (the VNC server), the following protocol is used:

	    - A  DES key  (k) is  shared by  both endpoints  and used  for the

	      challenge-response.

	    - 'C' connects to 'S' and both endpoints exchange software/protocol

	      version information

	    - 'S' generates a 16 byte challenge and sends it to 'C'

	    - 'C'  encrypts  the  received  challenge  with 'k' and sends  the

	      result ('rc') to 'S'

	    - 'S'  encrypt  the  challenge  with  'k' and compares the  result

	      ('rs') with the response 'rc' received from the client.

	    - If rc==rs access is  granted to the client. Otherwise  access is

	      denied.

	

	    A classical man-in-the-middle attack  can be perfomed against  the

	    described protocol.

	

	    Assuming that the  attacker ('M') has  access to the  data flowing

	    between client  and server  and is  able to  modify such  data, an

	    attack scenario THAT DOES NOT imply a TCP session hijacking attack

	    is outlined:

	    - 'M' connects to 'S' and both endpoints exchange software/protocol

	      version information

	    - 'S' generates a  16 byte challenge ('r1')  and sends it to  'M',

	      now  'M'  has  a  connection  established  with  'S'  with   the

	      authentication pending a response to the server.

	    - 'M' waits for a connection from a legit client 'C' to 'S'

	    - Upon  connection  from  the  client  'C' to the server 'S',  the

	      server  (as  per  the  protocol  design)  generates  a  16  byte

	      challenge ('r2') and sends it to 'C'.

	    - 'M'  modifies the  data traveling  from 'S'  to 'C' and replaces

	      'r2' with 'r1'

	    - 'C' receives 'r1' and encrypts  it with the shared key 'k',  the

	      result ('r1c') is sent to the server 'S'

	    - 'M' captures the response 'r1c' sent to the server 'S' and  uses

	      it in its own pending connection.

	    - 'S' receives 2 equal responses (r1c), one from 'C' and one  from

	      'M'.  It encrypts with 'k'  the challenges (r1 and r2) sent  and

	      compares  the  results  (r1s  and  r2s)  against  the   received

	      responses

	    - For the  legit client connection  ( r2s !=  r1c ) and  therefore

	      access is not granted

	    - For  the attacker  M connection  ( r1s  == r1c  ) and  therefore

	      access is granted

	

	    The attacker obtains unauthoraized access to the server using  the

	    client to generate a valid response to the challenge received.

	

	    2. Weakness in the generation of the random challenge data

	    ==========================================================

	    Additionally,  the  challenge  is  generated  via  rand(3)  calls,

	    initializing the randseed  with a call  to time(2).   The 128 bits

	    which comprises the challenge are generated by sucessive calls  to

	    rand, each one  returning 8 bits  of data.   This actually reduces

	    the useful randomness of the challenge to just 16 bits,  depending

	    on the return value of time() (with precision of a second).

	

	    The  above  two  facts   together  render  the  challenge   highly

	    predictable,   and   could   enable   an   attacker  eavesdropping

	    connections from a client to capture responses and reuse them at a

	    different  time  in  order  to  obtain  unauthorized access to the

	    server.

	

	

	 Update (25 July 2002)

	 ======

	

	In the same veine [jepler@unpythonic.net]  analyses  VNC  authentication
	weakness :
	

	VNC uses a DES-encrypted  challenge-response  system  to  avoid  passing
	passwords over the wire in plaintext.
	

	However, it seems that a weakness in the way the challenge is  generated
	by some servers would make this useless.
	

	The following program attempts to repeatedly connect  to  a  vnc  server
	and prints the challenge string.
	

	Against tightvnc-1.2.1_unixsrc, you'll see output like
	

	$ python pvc.py somehost:1

	4b24fbab355452b55729d630fcf73d43

	b3acdf3fab422b7aa49b8d786f93def3

	b3acdf3fab422b7aa49b8d786f93def3

	b3acdf3fab422b7aa49b8d786f93def3

	b3acdf3fab422b7aa49b8d786f93def3

	88e37f1677c4e4f56eb2fa00a2804ded

	88e37f1677c4e4f56eb2fa00a2804ded

	88e37f1677c4e4f56eb2fa00a2804ded

	88e37f1677c4e4f56eb2fa00a2804ded

	[...]

	

	each time the same string is printed twice  in  a  row  the  server  has
	repeated a challenge.
	

	WinVNC version 3.3.3R9 will display output more like
	

	$ python pvc.py otherhost:0

	Server declined connection

	Server declined connection

	91ff701f7dce8c6eebbc6062ffebcc6a

	Server declined connection

	Server declined connection

	[...]

	

	It appears that connects are rate-limited, even  if  the  connects  come
	from two distinct machines. This appears to foil  the  below  attack  on
	VNC authentication. (Whether this means there is a good DoS  opportunity
	against WinVNC is a separate question)
	

	If your server will give the same  challenge  repeatedly,  and  you  can
	sniff somebody else's challenge and response, it appears that you  could
	authenticate without knowing the password simply  by  connecting  within
	the 1-second window to get the same challenge, and then  send  the  same
	response as the legitimate client.
	

	Another weakness in the challenge is that it uses  'random()%256'.  Many
	implementations of random() have highly predictable low bits.  It's  not
	clear that this leads to as easy a compromise as the repeated  challenge
	problem, but it's something that warrants consideration..
	

	On  systems  with  /dev/urandom,  the  following  function   will   give
	challenge strings which should be immune to the problems discussed:
	

	void

	vncRandomBytes(unsigned char *bytes)

	{

	    int f;

	    

	    f = open("/dev/urandom", O_RDONLY);

	    while(read(f, bytes, 16) != 16) ;

	    close(f);

	}

	

	#------------------------------------------------------------------------

	#   pvc.py -- check for weak vnc challenges

	#------------------------------------------------------------------------

	import socket, sys, time

	

	

	def print_vnc_challenge(host, port):

	    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	    s.connect((host, port))

	    f = s.makefile("r+")

	    banner = f.readline()

	    f.write("RFB 003.003\n")

	    response = f.read(20)

	    if response[:4] != "\0\0\0\2":

		print "Server declined connection"

		return

	    challenge = response[4:]

	    print "".join(map(lambda x: "%02x" % ord(x), challenge))

	

	if len(sys.argv) > 1:

	    host_port = sys.argv[1]

	    if ":" in host_port:

		host, port = host_port.split(":")

		port = int(port) + 5900

	    else:

		host, port = host_port, 5900

	else:

	    host, port = "", 5900

	

	for x in range(20):

	    print_vnc_challenge(host, port)

	

SOLUTION

	    It is advisable  to tunnel communications  between the VNC  server

	    and  client   through  a   cryptographycally  strong    end-to-end

	    authenticated channel.   References for doing  so are provided  in

	    the  VNC  FAQ  and  specifics  on  how  to tunnel VNC over SSH are

	    provided at:

	
	        http://www.uk.research.att.com/vnc/sshvnc.html

	

	

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH