安全研究

安全漏洞
Feng多个远程溢出及拒绝服务漏洞

发布日期:2007-12-28
更新日期:2007-12-28

受影响系统:
Politecnico di Torino Feng 0.1.15
描述:
BUGTRAQ  ID: 27049

Feng是意大利Politecnico di Torino大学所开发的开源RTSP/RTP流媒体服务器。

Feng的实现上存在多个缓冲区溢出漏洞,远程攻击者可能利用此漏洞控制用户系统。

---------------------------------------------------
A] RTSP_valid_response_msg中缓冲区溢出(1)
---------------------------------------------------

sscanf没有限制大小便使用15字节的trash栈缓冲区作为目标缓冲区,以下是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] RTSP_valid_response_msg缓冲区溢出(2)
----------------------------------------------------

sscanf使用100字节msg栈缓冲区作为目标缓冲区,而RTSP_valid_response_msg中将该函数限制为255字节。以下是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] RTSP_remove_msg崩溃
---------------------------

RTP报文可能触发整数溢出。如果在报文中使用16位大小值0xffff,就可以强制服务器移动目标缓冲区中的4294967293字节:

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] parse_transport_header空指针
-----------------------------------------

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] parse_play_time_range空指针
----------------------------------------

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] log_user_agent空指针
---------------------------------

log_user_agent函数使用未检查的strstr查找User-Agent值的末尾,但服务器也可以处理回车符,这就允许攻击者在请求中只使用0x0d字符导致该函数崩溃。以下是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] Netembryo 0.0.4空指针
----------------------------------

Netembryo是libnemesi中所使用的客户端库。如果使用了类似于/:的urlname,port_begin和path_begin指针就会绕过port_begin > path_begin检查指向相同的位置,然后函数会试图为url->port分配4294967294字节((size_t)(path_begin - port_begin - 1)生成-2),这个分配会失败,因此会将所生成的空指针用作之后strncpy的目标。以下是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';
    }
    ...

<*来源:Luigi Auriemma (aluigi@pivx.com
  
  链接:http://marc.info/?l=bugtraq&m=119878001902466&w=2
        http://secunia.com/advisories/28229/
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

http://aluigi.org/poc/fengulo.zip

建议:
厂商补丁:

Politecnico di Torino
---------------------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://live.polito.it/documentation/libnemesi

浏览次数:6998
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障