####################################################################### Luigi Auriemma Application: Feng http://live.polito.it/documentation/feng Versions: <= 0.1.15 Platforms: *nix Bugs: A] first buffer-overflow in RTSP_valid_response_msg B] second buffer-overflow in RTSP_valid_response_msg C] crash in RTSP_remove_msg D] NULL pointer in parse_transport_header E] NULL pointer in parse_play_time_range F] NULL pointer in log_user_agent G] NULL pointer in Netembryo 0.0.4 Exploitation: remote Date: 27 Dec 2007 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduction =============== Feng is an open source RTSP/RTP streaming server written by the italian team of the Politecnico di Torino University for the LScube project. ####################################################################### ======= 2) Bugs ======= --------------------------------------------------- A] first buffer-overflow in RTSP_valid_response_msg --------------------------------------------------- A buffer-overflow vulnerability is exploitable through a stack buffer of 15 bytes called trash used as destination by sscanf without the needed size limits. From rtsp/RTSP_state_machine.c: int RTSP_valid_response_msg(unsigned short *status, char *msg, RTSP_buffer * rtsp) // This routine is from BP. { char ver[32], trash[15]; unsigned int stat; unsigned int seq; int pcnt; /* parameter count */ *ver = *msg = '\0'; /* assuming "stat" may not be zero (probably faulty) */ stat = 0; pcnt = sscanf(rtsp->in_buffer, " %31s %u %s %s %u\n%255s ", ver, &stat, trash, trash, &seq, msg); ... ---------------------------------------------------- B] second buffer-overflow in RTSP_valid_response_msg ---------------------------------------------------- A buffer-overflow vulnerability is exploitable through a stack buffer of 100 bytes called msg used as destination by sscanf limited to 255 bytes in the function RTSP_valid_response_msg. From rtsp/RTSP_state_machine.c: int RTSP_handler(RTSP_buffer * rtsp) { unsigned short status; char msg[100]; ... op = RTSP_valid_response_msg(&status, msg, rtsp); ... int RTSP_valid_response_msg(unsigned short *status, char *msg, RTSP_buffer * rtsp) ... sscanf(rtsp->in_buffer, " %31s %u %s %s %u\n%255s ", ver, &stat, trash, trash, &seq, msg); ... --------------------------- C] crash in RTSP_remove_msg --------------------------- An integer overflow is exploitable through the RTP packets. Using a 16 bit size value of 0xffff is possible to force the server to move 4294967293 bytes in the destination buffer: RTSP_BUFFERSIZE = 65536 len = 65539 (4 of hdrlen + 0xffff) result = -3 From rtsp/RTSP_lowlevel.c: void RTSP_remove_msg(int len, RTSP_buffer * rtsp) { rtsp->in_size -= len; if (rtsp->in_size && len) { /* discard the message from the in_buffer. */ memmove(rtsp->in_buffer, &(rtsp->in_buffer[len]), RTSP_BUFFERSIZE - len); memset(&(rtsp->in_buffer[len]), 0, RTSP_BUFFERSIZE - len); } } ----------------------------------------- D] NULL pointer in parse_transport_header ----------------------------------------- From rtsp/RTSP_setup.c: static RTSP_Error parse_transport_header(RTSP_buffer * rtsp, ... p = strstr(p, "="); sscanf(p + 1, "%d", &(cli_ports.RTP)); p = strstr(p, "-"); sscanf(p + 1, "%d", &(cli_ports.RTCP)); ... p = strstr(p, "="); sscanf(p + 1, "%d", &rtp_ch); ... p = strstr(p, "="); sscanf(p + 1, "%d", &rtp_ch); ... ---------------------------------------- E] NULL pointer in parse_play_time_range ---------------------------------------- From rtsp/RTSP_Play: static RTSP_Error parse_play_time_range(RTSP_buffer * rtsp, play_args * args) ... q = strchr(q, '='); if (get_utc(&(args->playback_time), q + 1) != ERR_NOERROR) { ... --------------------------------- F] NULL pointer in log_user_agent --------------------------------- The log_user_agent function uses an unchecked strstr for finding the end of the User-Agent value (a line field), but the server can handle also carriage-return chars allowing an attacker to crash it using only 0x0d chars in his request. From rtsp/RTSP_utils.c: void log_user_agent(RTSP_buffer * rtsp) { char * p; if ((p = strstr(rtsp->in_buffer, HDR_USER_AGENT)) != NULL) { char cut[strlen(p)]; strcpy(cut, p); p = strstr(cut, "\n"); cut[strlen(cut) - strlen(p) - 1] = '\0'; ... ---------------------------------- G] NULL pointer in Netembryo 0.0.4 ---------------------------------- Although this vulnerability affects another software of the LScube project I have preferred to include it here since only when used with Feng this bug can be considered a security bug (Netembryo in fact is used also in libnemesi which is a client-side library). The usage of the ':' char after the backslash allows an attacker to crash the server on which is used the Url_init() function of the Netembryo library. In short when an urlname like /: is used the port_begin and path_begin pointers will point to the same location bypassing the check "port_begin > path_begin", then the function will try to allocate 4294967294 bytes (-2 resulted by (size_t)(path_begin - port_begin - 1)) for url->port which will fail and so the resulted NULL pointer will be used as destination in the subsequent strncpy. From utils/url.c: int Url_init(Url * url, char * urlname) { ... path_begin = strstr(hostname_begin, "/"); if (path_begin == NULL) { path_len = 0; } else { ++path_begin; ... port_begin = strstr(hostname_begin, ":"); if ((port_begin == NULL) || ((port_begin > path_begin) && (path_begin != NULL))) { ... if (port_len) { url->port = (char*)malloc(port_len+1); strncpy(url->port, port_begin, port_len); url->port[port_len] = '\0'; } ... ####################################################################### =========== 3) The Code =========== http://aluigi.org/poc/fengulo.zip nc SERVER 554 -v -v < bof1.txt ... nc SERVER 554 -v -v < netembry0.txt ####################################################################### ====== 4) Fix ====== The bugs will be fixed in the next days. #######################################################################