#include #include /* get latest copy from: http://dcs.ex.ac.uk/~aba/bruterc4.c */ /* also Alex de Joode has kindly put a copy on ftp://utopia.hacktic.nl/pub/crypto/bruterc4.c */ /* * Quick hacked up rc4 brute force attack program. * * (Slightly optimised, could do more) * * excellent optimised prepare key by Tatu Ylonen ylo@cs.hut.fi * - boosts performance by >4 x !!! * * Gets me 38k keys/sec on a 100 Mhz SGI Indy * * Usage: * * bruterc4 known cypher start-key [keyspace] * * known = your known plaintext file * cypher = the plaintext file encrypted with 40 bit RC4 * start-key = start brute forcing keys from this hex key * keyspace = how many bits of keyspace to search (default 31) * * One dot gets printed for each 64k keys tried (every 8 seconds on Indy) * * Adam Back * */ #define KEY_SIZE 5 /* key size in bytes, ie 40 bits */ #define buf_size 1024 typedef struct rc4_key { unsigned char state[256]; unsigned char x; unsigned char y; } rc4_key; #define swap_byte(x,y) t = (x); (x) = (y); (y) = t void inc_key(unsigned char key[]) { int i; for (i=KEY_SIZE-1; i && key[i] == 255; i--) { key[i] = 0; } key[i]++; } const char* print_hex(unsigned char key[],int len) { static char space[513]; int i, lo, hi; for (i=0; istate[0]; memcpy(state,sequence,256); index2 = 0; k0 = key_data_ptr[0]; k1 = key_data_ptr[1]; k2 = key_data_ptr[2]; k3 = key_data_ptr[3]; k4 = key_data_ptr[4]; for(counter = 0; counter < 255; counter += 5) { t = state[counter]; index2 = (index2 + k0 + t) & 0xff; u = state[index2]; state[index2] = t; state[counter] = u; t = state[counter + 1]; index2 = (index2 + k1 + t) & 0xff; u = state[index2]; state[index2] = t; state[counter + 1] = u; t = state[counter + 2]; index2 = (index2 + k2 + t) & 0xff; u = state[index2]; state[index2] = t; state[counter + 2] = u; t = state[counter + 3]; index2 = (index2 + k3 + t) & 0xff; u = state[index2]; state[index2] = t; state[counter + 3] = u; t = state[counter + 4]; index2 = (index2 + k4 + t) & 0xff; u = state[index2]; state[index2] = t; state[counter + 4] = u; } t = state[255]; index2 = (index2 + k0 + t) & 0xff; u = state[index2]; state[index2] = t; state[255] = u; } int rc4_eq(unsigned char *buffer_ptr, unsigned char *known, unsigned char *cypher_txt, int buffer_len, rc4_key *key) { unsigned int t; unsigned int x = 0; unsigned int y = 0; unsigned char* state; unsigned int xorIndex; unsigned int counter; state = &key->state[0]; for(counter = 0; counter < buffer_len; counter++) { x = (x + 1) & 0xFF; y = (state[x] + y) & 0xFF; swap_byte(state[x], state[y]); xorIndex = (state[x] + state[y]) & 0xFF; buffer_ptr[counter] ^= state[xorIndex]; if (known[counter] != buffer_ptr[counter]) { memcpy(buffer_ptr,cypher_txt,counter+1); return 0; } } return 1; } int main(int argc, char* argv[]) { char data[KEY_SIZE*2+1]; char known[buf_size]; char cypher_txt[buf_size]; char try[buf_size]; char seed[256]; char digit[5]; int hex, rd,i, step = 65536; int n; unsigned int sweep = 1 << 31, done = 0; rc4_key key; FILE *known_fp, *cypher_txt_fp; if (argc < 4) { fprintf(stderr,"%s known cypher-txt start-key [bits-to-sweep]\n",argv[0]); exit(1); } strncpy(data,argv[3],KEY_SIZE*2); data[KEY_SIZE*2]=0; if (argc > 4) { sweep = atoi(argv[4]); if (sweep < 31) { sweep = (1 << sweep); } } n = strlen(data); if (n