by
CASIMIR
Part C
Caz presents : The Crack of SecurityPlus! by SoftByte Labs
(known-plaintext attack on a proprietary cipher)
/****************************** BEGIN *******************************/ #include <stdio.h> #include <string.h> #include <io.h> #include <stdlib.h> #include <dos.h> #include <conio.h> #include <fcntl.h> #include <alloc.h> #include <malloc.h> #include <errno.h> #include <math.h> /*************************** PROTOTYPES ******************************/ void Read_Key_enc(int,unsigned char **); void Calc_Pwd_start(unsigned char *,int,unsigned char **); void Calc_Sum(int,unsigned char *,unsigned char **); void Calc_Pwd(int,unsigned char *,unsigned char *,unsigned char **); int Check_Pwd(int,unsigned char *,unsigned char *,unsigned char *); void Hi_folks(void); int Get_target(void); void Wait_key(); void Print_pwd(int,unsigned char *); /***************************** GLOBALS *******************************/ const int key_start_pos = 61; const int key_len = 61; static unsigned char Key_chk[] = "*+*This file encrypted with SecurityPlus! " "(C)SoftByte Labs*+*"; /****************************** MAIN ********************************/ main() { int i,fn,extended; int pwd_len; int pwd_len_min=5; int pwd_len_max=60; unsigned char *Pwd; unsigned char *Key_enc; unsigned char *Key_dec; unsigned char *Sum; //memory allocation & initialisation Pwd =(unsigned char *)malloc(sizeof(unsigned char)*key_len); Key_enc=(unsigned char *)malloc(sizeof(unsigned char)*key_len); Key_dec=(unsigned char *)malloc(sizeof(unsigned char)*key_len); Sum =(unsigned char *)malloc(sizeof(unsigned char)*key_len); for(i=0;i<key_len;i++) {Pwd[i]=0; Key_enc[i]=0; Key_dec[i]=0; Sum[i]=0;} //start searching Hi_folks(); fn=Get_target(); Read_Key_enc(fn,&Key_enc); //round 1 of 2 : Pwd's first character NOT extended //round 2 of 2 : Pwd's first character extended extended=0; for(extended=0;extended<=1;extended++) { Calc_Pwd_start(Key_enc,extended,&Pwd); //for each pwd_len for(pwd_len=pwd_len_min;pwd_len<=pwd_len_max;pwd_len++) { Calc_Sum(pwd_len,Pwd,&Sum); Calc_Pwd(pwd_len,Sum,Key_enc,&Pwd); if(!Check_Pwd(pwd_len,Sum,Key_enc,Pwd)) { Print_pwd(pwd_len,Pwd); exit(0); } } } } /***********************************************************************/ /************************** FUNCTIONS ******************************/ /***********************************************************************/ /***********************************************************************/ int Check_Pwd(int pwd_len,unsigned char *Sum,unsigned char *Key_enc, unsigned char *Pwd) { int i,pos; unsigned char temp; temp=(Key_enc[0]-Pwd[0]-Pwd[0]-Pwd[pwd_len-1]-key_len); if(Key_chk[0]!=temp) return(1); for(i=pwd_len;i<(key_len-1);i++) { pos=fmod(i,pwd_len); temp=(Key_enc[i+1]-Key_enc[i]-Key_chk[i+1]-(key_len-i-1)-Sum[i+1]); if(Pwd[pos]!=temp) return(1); } return(0); } /***********************************************************************/ void Calc_Pwd(int pwd_len,unsigned char *Sum,unsigned char *Key_enc, unsigned char **Pwd) { int i; for(i=1;i<pwd_len;i++) { (*Pwd)[i]=(Key_enc[i+1]-Key_enc[i]-Key_chk[i+1]-(key_len-i-1)-Sum[i+1]); } } /***********************************************************************/ void Calc_Sum(int pwd_len,unsigned char *Pwd,unsigned char **Sum) { int i,pos; (*Sum)[0]=Pwd[0]; for(i=1;i<key_len;i++) { pos=fmod(i,pwd_len); if(!pos) { pos=pwd_len; } (*Sum)[i]=((*Sum)[i-1] + pos); } } /***********************************************************************/ void Calc_Pwd_start(unsigned char *Key_enc,int extended,unsigned char **Pwd) { (*Pwd)[0] = ((Key_enc[1] - Key_enc[0] - Key_chk[1] - key_len)); (*Pwd)[0] /=2; if(extended) (*Pwd)[0]+=0x80; } /***********************************************************************/ void Read_Key_enc(int fn,unsigned char **Key_enc) { int i; unsigned char Buffer[key_len]; lseek(fn,key_start_pos,0); read(fn,Buffer,key_len); for(i=0;i<key_len;i++) { (*Key_enc)[i]=Buffer[i]; } } /***********************************************************************/ void Hi_folks(void) { printf("\n\nYet Another Password Cracker by CASIMIR {:-)"); printf("\n-> Target: SecurityPlus! v4.32 by SoftByte Labs\n"); } /***********************************************************************/ /* try to open crypted file (must be in the SAME directory) */ /* - success : return file'handle */ /* - failure : exit prg */ int Get_target(void) { unsigned char buf[110]; int fn; printf("\nFile to decrypt [e.g: secret.sp$]? "); gets(buf); // try to open file fn=open(buf,O_BINARY|O_RDONLY); switch(fn) { case -1:printf("\nFILE NOT FOUND!"); printf("\n->File to crack MUST be in SAME directory as Cracker"); printf("\n->DO NOT forget file's extension ( usually: SP$ or SP% ) !\n"); Wait_key(); exit(0); default: /*printf("\nOK, FILE FOUND")*/; return(fn); } } /***********************************************************************/ /* wait for key pressed */ void Wait_key() { printf("\n"); printf(" ******************\n"); printf(" * hit any key... *\n"); printf(" ******************\n"); getch(); //kbhit } /***********************************************************************/ /* display password */ void Print_pwd(int pwd_len,unsigned char *Pwd) { int i; printf("\n\n ASCII seq: "); for(i=0;i<pwd_len;i++) { printf("[%d]",Pwd[i]); if((i+1)%10==0) {printf("\n ");} } printf("\n\n PASSWORD: >>>"); for(i=0;i<pwd_len;i++) { printf("%c",Pwd[i]); } printf("<<< (%d characters)\n\n",pwd_len); printf("(don't type >>> or <<<)\n"); } /******************************* END ********************************
And now, for those who are still with me:
3 crypto-software which deserve, IMO, the Snake-Oil award. They require no programming in order to break them, only a patch.
I just put them here, in case someone cares...
Here is Rocny! 3.4
This one decrypts password from encrypted file in order to compare it to input... Bad idea. Even worst, it uses a VisualBasic function to perform the check (__vbaStrCmp)!!!
module RO34EVAL.EXE :446034 mov eax , [ebp-44] <--- good password push eax mov ecx , [44A09C] <--- our input push ecx call [MSVBVM50!__vbaStrCmp] <--- sic!
Look at the help file: on every footer, you'll see this sentence:
You Are the Most Important for Us
Pathetic...
Here is Exe Protect
Same mistake, but without the VB function. Here lays the password checking mechanism of main window:
module EXEPROT.EXE :403BC1 mov ecx , [esi] <--- our input mov ebx , [edi] <--- good password cmp ecx , ebx
Once you're in, you can unlock every file previously locked.
Here is Encryption Lock Magic
Yeap, you guessed it, the same old mistake again...
module ENCLOCKMAGIC.EXE :4510DB mov edx , [ebp-2c] <--- good password mov eax , [ebp-1c] <--- our input call 403D38 <--- comparaison routine
Hope you enjoyed!
Caz
Copyright December 1999 by Casimir.
Mail Casimir
Converted to hypertext by Joe Peschel December 14, 1999.