The Cracking of SecurityPlus

by

CASIMIR

Part C

Other Essays by Casimir
  • Cracking of Crypt-o-Text v1.21 & v1.24
  • Correspondence From Casimir On Reversing Turbo Encrypto
  • Cracking of Encrypt-It For Windows
  • Cracking of WinXFiles
  • The Cracking of File Locker
  • The Cracking of Keeper
  • The Cracking of Braun's Crypto 3.5
  • The Cracking of MasterKey v1.02/1.05
  • Caz presents : The Crack of SecurityPlus! by SoftByte Labs


    (known-plaintext attack on a proprietary cipher)



    PART C. 'C' SOURCE CODE FOR CRACKER : CrackSP!

    
    /****************************** 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(); {/* wait until key pressed */}      //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 ********************************/
    
    
    Here is Cracksp the Security Plus! cracker

    And now, for those who are still with me:

    * BONUS TRACKS * BONUS TRACKS * BONUS TRACKS *

    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...

    Rocny! v3.4 (Evaluation) by NIZAR Developers

    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...

    Exe Protect by Frederic Collin

    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.

    Encryption Lock Magic! v1.0 by Kaboom JSP

    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.