/* * Copyright (c) 2004 Simon Marechal * simon.marechal at thales-security.com * * UTF-8 support by magnum 2011, no rights reserved */ #include #include #include "arch.h" #include "misc.h" #include "common.h" #include "formats.h" #include "unicode.h" #include "DES_bs.h" #define FORMAT_LABEL "oracleee" #define FORMAT_NAME "Oracleee" #define ALGORITHM_NAME "oracleee" #define BENCHMARK_COMMENT "" #define BENCHMARK_LENGTH -1 #define PLAINTEXT_LENGTH 120 // worst case UTF-8 is 40 characters of Unicode, that'll do #define BINARY_SIZE 8 #define SALT_SIZE (32 + 4) // also contain the NULL #define CIPHERTEXT_LENGTH 16 #define MIN_KEYS_PER_CRYPT DES_BS_DEPTH #define MAX_KEYS_PER_CRYPT DES_BS_DEPTH #if DES_BS_VECTOR #define DEPTH [depth] #define START [0] #define init_depth() \ int depth; \ depth = index >> ARCH_BITS_LOG; \ index &= (ARCH_BITS - 1); #define for_each_depth() \ for (depth = 0; depth < DES_BS_VECTOR; depth++) #else #define DEPTH #define START #define init_depth() #define for_each_depth() #endif static unsigned char DES_IP[64] = { 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6 }; int out1[64];//new modification unsigned long outtemp2[128]; long *oracle_binary(char *ciphertext); static struct fmt_tests oracle_tests[] = { {"O$SYS#0170453E89F8CDA7", "H4X0R"}, //{"O$SYS#0170453E89F8CDA7", "H4X0R"},//C648972D2BE43FA4 //{"O$SIMON#C4EB3152E17F24A4", "TST" }, //{"O$BOB#b02c8e79ed2e7f46", "LAPIN" }, //{"4F8BC1809CB2AF77", "A", {"SIMON"} }, //{"C4EB3152E17F24A4", "TST", {"SIMON"} }, //{"b02c8e79ed2e7f46", "LAPIN", {"BOB"} }, {NULL} }; #if ARCH_LITTLE_ENDIAN #define ENDIAN_SHIFT_L << 8 #define ENDIAN_SHIFT_R >> 8 #else #define ENDIAN_SHIFT_L #define ENDIAN_SHIFT_R #endif static int salt_length; static int key_length; static char *plain_key; static char temp_salt[9]; static char temp_key[9]; static int valid(char *ciphertext, struct fmt_main *pFmt) { int i; int l; /* * 2 cases * 1 - it comes from the disk, and does not have O$ + salt * 2 - it comes from memory, and has got O$ + salt + # + blah */ if (!memcmp(ciphertext, "O$", 2)) { l = strlen(ciphertext) - CIPHERTEXT_LENGTH; if(ciphertext[l-1]!='#') return 0; } else { if(strlen(ciphertext)!=CIPHERTEXT_LENGTH) return 0; l = 0; } for (i = l; i < l + CIPHERTEXT_LENGTH; i++){ if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) return 0; } return 1; } static char *prepare(char *split_fields[10], struct fmt_main *pFmt) { char *cp; if (!strncmp(split_fields[1], "O$", 2)) return split_fields[1]; cp = mem_alloc(strlen(split_fields[0]) + strlen(split_fields[1]) + 4); sprintf (cp, "O$%s#%s", split_fields[0], split_fields[1]); if (valid(cp, pFmt)) { UTF8 tmp8[16*3+1]; UTF16 tmp16[17]; int utf8len, utf16len; // we no longer need this. It was just used for valid(). We will recompute // all lengths, after we do an upcase, since upcase can change the length of the // utf8 string. MEM_FREE(cp); // Upcase user name, --encoding aware utf8len = enc_uc(tmp8, 16*3, (unsigned char*)split_fields[0], strlen(split_fields[0])); if (utf8len <= 0 && split_fields[0][0]) return split_fields[1]; // make sure this 'fits' into 16 unicode's utf16len = enc_to_utf16(tmp16, 16, tmp8, utf8len); if (utf16len <= 0) return split_fields[1]; cp = mem_alloc_tiny(utf8len + strlen(split_fields[1]) + 4, MEM_ALIGN_NONE); sprintf (cp, "O$%s#%s", tmp8, split_fields[1]); #ifdef DEBUG_ORACLE printf ("tmp8 : %s\n", tmp8); #endif return cp; } MEM_FREE(cp); return split_fields[1]; } static void oracle_init(struct fmt_main *pFmt) { DES_bs_init(2); } static void oracle_set_key(char *key, int index) { int l; plain_key = key; //10101011011101000010000011000010011001101111001101101110 for(l=0;l>i)&1; } for(j=0;j<64-(l*8);j++) out1[j]=0; for(i=(l*8)-1;i>=0;i--,j++) out1[j]=outtemp1[i]; l=0; j=0; for(i=0;i<128;i++){ if(i==8||i==24||i==40||i==56||i==72||i==88||i==104||i==120){ for(j=0+s;j<8+s;j++,i++) //printf("%d..%d\n",i,j); outtemp2[i]=out1[j]; } outtemp2[i]=0; s=j; } // printf("new value\n"); // for(j=0;j<128;j++) // printf("%d",outtemp2[j]); return outtemp2; } static char *oracle_get_key(int index) { static UTF8 UC_Key[PLAINTEXT_LENGTH*3*3+1]; // Calling this will ONLY upcase characters 'valid' in the code page. There are MANY // code pages which mssql WILL upcase the letter (in UCS-2), but there is no upper case value // in the code page. Thus we MUST keep the lower cased letter in this case. enc_uc(UC_Key, PLAINTEXT_LENGTH*3*3, (UTF8*)plain_key, strlen(plain_key)); return (char*)UC_Key; } static void oracle_crypt_all(int count) { int index=count; int ofs,j,length,l,bit,i,dst; long *binary_plain_salt_mix; DES_bs_vector *b=NULL; unsigned long finalresult; long cryptkey1[64]; long cryptkey2[64]; int result[64]; int temp1[64]; char *key; init_depth(); strcat(temp_salt,temp_key); binary_plain_salt_mix=oracle_binary(temp_salt); for(i=0;i<64;i++) cryptkey1[i]=binary_plain_salt_mix[i]; i=0; for(j=64;j<128;j++,i++) cryptkey2[i]=binary_plain_salt_mix[j]; for(ofs=0;ofs<9;ofs++) temp_salt[ofs]=NULL; DES_bs_crypt_Oracle(cryptkey1); binary_plain_salt_mix=NULL; /* b = (DES_bs_vector *)&DES_bs_all.B[0] DEPTH; for (bit =0; bit<64; bit++) temp1[bit]=(b[bit]START & 1); for (dst = 0; dst < 64; dst++) { int src = DES_IP[dst ^ 0x20]; temp1[dst]=temp1[src]; } printf("Temp value..\n"); for(i=0;i<64;i++) printf("%d",temp1[i]); printf("\n"); */ //0000000101110000010001010011111010001001111110001100110110100111//30 1 //0010010100111000010100100110001011111010001101000100111111001010 //1111110001000001001010011000001000000101001101101001101011011111 /* for (bit =0; bit<64; bit++) temp1[bit]=temp1[bit]^cryptkey2[bit]; DES_bs_clear_keys_LM(); key="\x01\x23\x45\x67\x89\xAB\xCD\xEF"; DES_bs_set_key_LM(key,index); DES_bs_crypt_Oracle(temp1); b = (DES_bs_vector *)&DES_bs_all.B[0] DEPTH; for (bit =63; bit>=0; bit--, b++){ result[bit]= ((b[0]START>>index) & 1); } finalresult=(result[63]<<1)|result[62]; for (bit =61; bit>=0; bit--) finalresult=(finalresult<<1)|result[bit]; //printf("Final result...%ld\n",finalresult); for (bit = 0; bit<64; bit++) result[bit]=0; key=decimal_to_text(finalresult); finalresult=0; DES_bs_clear_keys_LM(); DES_bs_set_key_LM(key,index); DES_bs_crypt_Oracle(cryptkey1); b = (DES_bs_vector *)&DES_bs_all.B[0] DEPTH; for (bit =0; bit<64; bit++) temp1[bit]=(b[bit]START & 1)^cryptkey2[bit]; DES_bs_clear_keys_LM(); DES_bs_set_key_LM(key,index); DES_bs_crypt_Oracle(cryptkey2); */ } static void * oracle_get_salt(char * ciphertext) { char salt[8]; int l,i; l=2; for(i=0;i<9;i++) temp_salt[i]=NULL; while( ciphertext[l] && (ciphertext[l]!='#') ) { salt[l-2] = ciphertext[l]; l++; if (l-2 >= SALT_SIZE-2) break; } salt[l-2] = 0; for(l=0;l