///////////////////////////////////////////////////////////////////// // Zipcrack.c // // This program tries to crack password protected Zip(v1.1) files. // // (c)1991 By Nickle/Group42 group42@sonic.net // // Please send me any cool enhancements for this code. // // Compiled with microsquishy C 6.0 with max optimization. ////////////////////////////////////////////////////////////////////// #include "stdio.h" #include "string.h" unsigned char dos_string[128]; unsigned char delete_file[128]; #define DWORD unsigned long #define WORD unsigned int #define BYTE unsigned char #define USGC unsigned char #define USGI unsigned #define USGL unsigned long #define MAXDIGHACK 8 #define GOOD_CRC32_RESIDUAL 0xdebb20e3L USGL crctable[256]; // global accessible // USGI crc2find; // crc 2 find // BYTE sig[] = {0x50,0x4b,0x03,0x04}; BYTE error_sig[] ={'e','r','r','o','r','s','!'}; unsigned long crc32(); void generatetable(); unsigned char decrypt_byte(); int maxdighack = MAXDIGHACK; //unsigned char preamble[10]; //unsigned char postamble[10]; int ffflag=0; main(argc, argv) int argc; char *argv[]; { unsigned char passcode[25]; unsigned char buffer[25]; unsigned char lookfile[25]; unsigned char inbuff[25]; unsigned char zipname[25]; FILE *zipfile; int end,i,j,skip,len; printf("\nZipcrack V0.1b - (c)1991 by Mycal Johnson - mycal@netacsys.com\n\n"); if(argc==1) { printf("\n Usage: 'zipcrack zipfile crackfile'"); printf("\n zipfile = filename.zip "); printf("\n crackfile = file in the zipfile to crack\n\n"); exit(2); } i=strlen(argv[1]); if(i>8) { printf("\n Filename must be 8 characters or less, do not incude .zip extention \n\n"); exit(2); } strcpy(zipname,argv[1]); strcat(zipname,".zip"); i=strlen(argv[2]); if(i>12) { printf("\n Filename to hack cannot be more than 12 characters including extention\n\n"); exit(2); } strcpy(lookfile,argv[2]); strupr(lookfile); strupr(zipname); // // make unzip try string // strcpy(dos_string,"unzip "); strcat(dos_string,argv[1]); strcat(dos_string," "); strcat(dos_string,lookfile); strcat(dos_string," -s"); strcpy(delete_file,"del "); strcat(delete_file,lookfile); // // check to see if target already exists // if((zipfile = fopen(lookfile,"r+b")) != NULL) { close(zipfile); printf("\nWarning %s already exists on disk.",lookfile); printf("\n Delete this file and try again."); exit(1); } if ((zipfile = fopen(zipname,"r+b")) == NULL ) { printf("fopen failed. Cannot find/open %s.\n",zipname); exit(2); } i = 0; end=0; // // Here we search for file to hack on inside the zip file. First we // look for the local file sig then we check to see if its our file. // while(!end) { if(fread(buffer, sizeof(char),1,zipfile)) { if(buffer[0] == sig[i]) i = i + 1; else i = 0; if (i == 4) { // sig is 4 digits len=strlen(lookfile); skip = 26; if(fseek(zipfile, (long)skip, SEEK_CUR)!=0) { printf("fseek fail\n"); exit(1); } if(fread(inbuff, sizeof(char),len,zipfile)) { if(!memcmp(lookfile,inbuff,len)) end=1; else i=0; } else { printf("read failed\n"); exit(1); } } } else end = 2; // end of file } // // We couldn't find the file to hack if end = 2; // if(end == 2) { printf("File to hack not in found in Zipfile.\n"); exit(2); } // // Read encryption header // if(!fread(buffer, sizeof(char),12,zipfile)) { printf("Cannot read from Zipfile. fread fail\n"); exit(2); } skip = -(len+16+12); // - len of filename + crc offset + encript headder if(fseek(zipfile, (long)skip, SEEK_CUR)!=0) { printf("fseek fail\n"); exit(1); } if(fread(inbuff, sizeof(char),4,zipfile)) { printf(" crc from file = %x : %x \n",((inbuff[3]<<8)|inbuff[2]), ((inbuff[1]<<8)|inbuff[0])); crc2find = ((inbuff[3]<<8)|inbuff[2]); } else { printf("fread2 fail"); exit(2); } close(zipfile); buffer[12]=0; if(crackzip(passcode,buffer)) { // buffer contains encription header // // returns hacked key in passcode // printf("\nWe hack success!\n\nKey is '%s'\n\n",passcode); printf("Thanx to your pal mycal@netacsys.com\n"); exit(0); } else { printf("\nBummer, I couldn't hack it.\n"); exit(1); } } crackzip(passcode, buffer) char *passcode; char *buffer; { unsigned long key[3]; unsigned char hackbuff[19]; unsigned char password[50]; unsigned char dos_try[128]; unsigned int i,end, result,slen; generatetable(); // generate 32-bit crc table // // // Set password to 'a' and the rest nil, set up end flag // end = 0; for(i=0;i<50;i++) // init password to nil // password[i]=0; strcpy(password,"a"); // // this is where the main hack loop is, we loop here tell we crack the // password or forever, whichever is first. // while(!end){ memcpy(hackbuff,buffer,15); // reset buffer to origin key[0] = 305419896L; // reset key to start key[1] = 591751049L; key[2] = 878082192L; // // initilize key with password // slen = strlen(password); for(i=0; imaxdighack) { return(0); end=2; } } else { // // We have a CRC match, so lets try to unzip the file // printf(" -- possible password is %s. Trying it now... \n",password); strcpy(dos_try,dos_string); strcat(dos_try,password); strcat(dos_try," > zipcrack.err"); result=system(dos_try); if(!chk_4_errors()) { // we hack success! strcpy(passcode,password); return(1); } printf("...failed\n"); system(delete_file); update_password(password); if(strlen(password)>maxdighack){ return(0); end=2; } } }// end while // } ////////////////////////////////////////////////////////////////////////// // // chk_4_errors() - search the zipcrack.err file for the error_sig - // "error!". If found return 1 else return 0 // ///////////////////////////////////////////////////////////////////////// int chk_4_errors() { FILE *errfile; int end; int i; char buffer[10]; if ((errfile = fopen("zipcrack.err","r+b")) == NULL ) { printf("\nCannot find zipcrack.err file."); printf("\nCannot continue.\n"); exit(1); } i=0; end=0; while(!end) { if(fread(buffer, sizeof(char),1,errfile)) { if(buffer[0] == error_sig[i]) i = i + 1; else i = 0; if (i == 7) { // sig is 4 digits close(errfile); return(1); } } else end=1; } close(errfile); return(0); } ////////////////////////////////////////////////////////////////////////// // update_password(password) - we get the next password to try here. // This is the routine you would modify to make a dictionary or // other than sequential hack. Also you can modify the range // of char's to try here. /////////////////////////////////////////////////////////////////////// update_password(password) char *password; { int g,i,len,err; char newlen[12]; err=0; len = strlen(password); i = len-1; g = 0; while(!err){ password[i] = password[i] + 1; // inc to next char in series if(password[i] > 'z') { password[i] = 'a'; i = i - 1; g = g + 1; if(g==2) printf("password = %s \015",password); }else err = 1; if(i<0) { // we need to increase the length by one // strcpy(newlen,preamble); // I was thinking about a pre and // postamble in case you knew the // first or las couple of letters // of the password strcpy(newlen,"a"); // new start of string // strcat(newlen,password); strcpy(password,newlen); err = 1; } } } //////////////////////////////////////////////////////////////////////////// // decript_head(buffer,key) - this is where the actual work takes place, // We decript the buffer with the key generated with our password and // check if we have a CRC match, if we do return with a 1. //////////////////////////////////////////////////////////////////////////// decript_head(buffer,key) unsigned char *buffer; unsigned long *key; { int i; unsigned int crc1; char c; for(i = 0; i<12 ; i++) { c = buffer[i] ^ decrypt_byte(key); /* buffer xor decrypt_byte */ update_keys(key,c); buffer[i] = c; } crc1 = ((buffer[11]<<8)|(buffer[10])); /* crc1 = ~crc1; */ if(crc1 == crc2find) { printf("Yippi Ki-aye M*&!#R F*^@#R "); return(1); } return(0); } update_keys(key,val) unsigned long *key; char val; { key[0] = crc32(key[0],val); key[1] = key[1] + (key[0] & 0x000000ff); key[1] = key[1] * 134775813 + 1; key[2] = crc32(key[2],(key[1] >> 24)); } unsigned char decrypt_byte(key) unsigned long *key; { unsigned short temp; temp = key[2] | 2; return((temp*(temp^1))>>8); } // // cRc routine // unsigned long crc32(oldcrc, newchar) USGL oldcrc; char newchar; { int i,index; USGL Crc; Crc = oldcrc; index = ((Crc ^ newchar) & 0x000000ffL); Crc = ((Crc >> 8) & 0x00ffffffL) ^ crctable[index]; return Crc; /* return a 1's complement */ } void generatetable() /* generate the crc look-up table */ { union { USGI i; struct { USGI i1 :1; /* MSC low order bit */ USGI i2 :1; USGI i3 :1; USGI i4 :1; USGI i5 :1; USGI i6 :1; USGI i7 :1; USGI i8 :1; /* MSC high order bit */ USGI :8; /* unused bits */ }bit; }iUn; union { USGL entry; struct { USGI b1 :1; /* MSC low order bit */ USGI b2 :1; USGI b3 :1; USGI b4 :1; USGI b5 :1; USGI b6 :1; USGI b7 :1; USGI b8 :1; USGI b9 :1; USGI b10:1; USGI b11:1; USGI b12:1; USGI b13:1; USGI b14:1; USGI b15:1; USGI b16:1; USGI b17:1; USGI b18:1; USGI b19:1; USGI b20:1; USGI b21:1; USGI b22:1; USGI b23:1; USGI b24:1; USGI b25:1; USGI b26:1; USGI b27:1; USGI b28:1; USGI b29:1; USGI b30:1; USGI b31:1; USGI b32:1; /* MSC high order bit */ } entrybit; }entryun; for (iUn.i = 0; iUn.i < 256; iUn.i++) { entryun.entry = 0; /* zero out the value */ entryun.entrybit.b32 = (iUn.bit.i2 ^ iUn.bit.i8); entryun.entrybit.b31 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i7 ^ iUn.bit.i8); entryun.entrybit.b30 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i6 ^ iUn.bit.i7 ^ iUn.bit.i8); entryun.entrybit.b29 = (iUn.bit.i1 ^ iUn.bit.i5 ^ iUn.bit.i6 ^ iUn.bit.i7); entryun.entrybit.b28 = (iUn.bit.i2 ^ iUn.bit.i4 ^ iUn.bit.i5 ^ iUn.bit.i6 ^ iUn.bit.i8); entryun.entrybit.b27 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i5 ^ iUn.bit.i7 ^ iUn.bit.i8); entryun.entrybit.b26 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i6 ^ iUn.bit.i7 ); entryun.entrybit.b25 = (iUn.bit.i1 ^ iUn.bit.i3 ^ iUn.bit.i5 ^ iUn.bit.i6 ^ iUn.bit.i8); entryun.entrybit.b24 = (iUn.bit.i4 ^ iUn.bit.i5 ^ iUn.bit.i7 ^ iUn.bit.i8); entryun.entrybit.b23 = (iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i6 ^ iUn.bit.i7); entryun.entrybit.b22 = (iUn.bit.i3 ^ iUn.bit.i5 ^ iUn.bit.i6 ^ iUn.bit.i8); entryun.entrybit.b21 = (iUn.bit.i4 ^ iUn.bit.i5 ^ iUn.bit.i7 ^ iUn.bit.i8); entryun.entrybit.b20 = (iUn.bit.i2 ^ iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i6 ^ iUn.bit.i7 ^ iUn.bit.i8 ); entryun.entrybit.b19 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i3 ^ iUn.bit.i5 ^ iUn.bit.i6 ^ iUn.bit.i7 ); entryun.entrybit.b18 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i4 ^ iUn.bit.i5 ^ iUn.bit.i6 ); entryun.entrybit.b17 = (iUn.bit.i1 ^ iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i5 ); entryun.entrybit.b16 = (iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i8); entryun.entrybit.b15 = (iUn.bit.i2 ^ iUn.bit.i3 ^ iUn.bit.i7); entryun.entrybit.b14 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i6); entryun.entrybit.b13 = (iUn.bit.i1 ^ iUn.bit.i5); entryun.entrybit.b12 = (iUn.bit.i4); entryun.entrybit.b11 = (iUn.bit.i3); entryun.entrybit.b10 = (iUn.bit.i8); entryun.entrybit.b9 = (iUn.bit.i2 ^ iUn.bit.i7 ^ iUn.bit.i8); entryun.entrybit.b8 = (iUn.bit.i1 ^ iUn.bit.i6 ^ iUn.bit.i7); entryun.entrybit.b7 = (iUn.bit.i5 ^ iUn.bit.i6 ); entryun.entrybit.b6 = (iUn.bit.i2 ^ iUn.bit.i4 ^ iUn.bit.i5 ^ iUn.bit.i8); entryun.entrybit.b5 = (iUn.bit.i1 ^ iUn.bit.i3 ^ iUn.bit.i4 ^ iUn.bit.i7 ); entryun.entrybit.b4 = (iUn.bit.i2 ^ iUn.bit.i3 ^ iUn.bit.i6); entryun.entrybit.b3 = (iUn.bit.i1 ^ iUn.bit.i2 ^ iUn.bit.i5); entryun.entrybit.b2 = (iUn.bit.i1 ^ iUn.bit.i4); entryun.entrybit.b1 = (iUn.bit.i3); crctable[iUn.i] = entryun.entry; } }