####################################################################### Luigi Auriemma Applicazione: Fenice - Open Media Streaming Server http://streaming.polito.it/server Versioni: <= 1.10 e SVN 2005-07-26 Piattaforme: *nix, *BSD ed altre Bugs: A] buffer-overflow in parse_url B] crash in RTSP_msg_len Exploitation: remoto Data: 23 Apr 2006 Autore: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduzione 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduzione =============== Fenice e' il recente nome dell'Open Media Streaming Server (OMS) sviluppato dal Politecnico di Torino. Questo server open source implementa i protocolli RTSP, RTP e RTCP. ####################################################################### ======= 2) Bugs ======= ------------------------------- A] buffer-overflow in parse_url ------------------------------- Il modulo RTSP di Fenice utilizza una funzione (parse_url) per ricavare il server, la porta ed il nome del file contenuti nell'URI inviato dal client. Questa funzione utilizza alcune chiamate a strcpy per riempire i buffers server e file_name passati dalla funzione principale, cio' permette ad un attacker di sfruttare il conseguente buffer-overflow per eseguire possibile codice malevolo sul server vulnerabile. Da 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 ------------------------ La funzione che gestisce il campo Content-Length inviato dal client non controlla il segno di tale parametro. Nella funzione RTSP_msg_len si puo' vedere la variabile ml usata per contenere il numero di bytes dell'header e bl per il valore di Content-Length. Quando viene raggiunta la fine della richiesta inviata dal client il programma aggiunge bl a ml. Se bl (Content-Length) e' un numero molto grande come 2147483647 o piu' ml diventera' un numero negativo (ml e' un intero con segno come tutte le altre variabili) ed il controllo successivo "ml > rtsp->in_size" sara' bypassato. Il risultato e' l'accesso in lettura a zone invalide della memoria che causa il crash immediato del server. Da 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 /[circa 320 'a'] HTTP/1.0 B] GET / HTTP/1.0 Content-Length: 4294967295 ####################################################################### ====== 4) Fix ====== Una patch verra' rilasciata a breve. Update 06 Jun 2006: SVN r353 is fixed #######################################################################