From 23f5f88ff8a7dbddf5249d72cafae3d3d5e14294 Mon Sep 17 00:00:00 2001 From: Benedict Date: Thu, 18 Aug 2016 21:47:49 +0200 Subject: set2, completed 12 and 14 --- lib/lib2.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- lib/lib2.h | 7 +++- 2 files changed, 105 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/lib/lib2.c b/lib/lib2.c index e447054..d84c781 100644 --- a/lib/lib2.c +++ b/lib/lib2.c @@ -214,44 +214,51 @@ int detect_blocksize_ecb(char *text, int length_text, char *key) return i-1; } -/** - * cracks one AES-ECB block - */ -int crack_aes_ecb(char *text, int length_text, char *plaintext, char *key, int blocksize) + +int crack_aes_ecb(char **plaintext, int blocksize, int offset) { - char *to_encrypt_block = malloc(length_text + 17); + int prepend_data = offset ? 1 : 0; + int fill_in = offset % blocksize; + if(fill_in) { + fill_in = blocksize-fill_in; + offset += fill_in; + } + printf("offset must now be multiple of 16: %i\n", offset % blocksize); + char *attacker_data = malloc(17+fill_in); + int length_plaintext; char **ciphertexts= malloc(sizeof(char*)*blocksize); + int *ciphertext_length = malloc(sizeof(char*)*blocksize); char *cipher_block = malloc(blocksize+1); char *prefix = malloc(blocksize+1); int i,j; - + // encrypt text prepended with A, AA, AAA, ... + memset(attacker_data, 0, 17+fill_in); for(i=0;i=0;j--) { if(i==0) memset(prefix, 0x54, blocksize); else - memcpy(prefix, &text[((i-1)*blocksize)+blocksize-j], blocksize); - memcpy(&prefix[j], &text[i*blocksize], blocksize-j); - printf("prefix:%s\nendprefix\n", prefix); - memcpy(cipher_block, &(ciphertexts[j][i*blocksize]), blocksize); - plaintext[i*blocksize+blocksize-1-j] = create_dictionary_and_match(prefix, cipher_block, key, blocksize); + memcpy(prefix, &((*plaintext)[((i-1)*blocksize)+blocksize-j]), blocksize); + + memcpy(&prefix[j], &((*plaintext)[i*blocksize]), blocksize-j); + memcpy(cipher_block, &(ciphertexts[j][i*blocksize+offset]), blocksize); + (*plaintext)[i*blocksize+blocksize-1-j] = create_dictionary_and_match(prefix, cipher_block, key, blocksize); } - printf("plaintext so far: %s\n", plaintext); } - } char create_dictionary_and_match(char *prefix, char *match, char *key, int blocksize_bytes) @@ -265,7 +272,7 @@ char create_dictionary_and_match(char *prefix, char *match, char *key, int block memcpy(dict_string, prefix, blocksize_bytes); for(i=0;i<255;i++) { dict_string[blocksize_bytes-1] = (char) i; - printf("%s\n", dict_string); + //printf("%s\n", dict_string); aes_ecb(dict_string, blocksize_bytes, cipher_block, key, blocksize_bytes, 1); hex_binary_to_string(cipher_block, hex_tmp, blocksize_bytes); // printf("%s\n", hex_tmp); @@ -276,6 +283,76 @@ char create_dictionary_and_match(char *prefix, char *match, char *key, int block } } + +int challenge12_and_14_oracle(char *attacker_data, int attacker_data_length, char **ciphertext, int prepend_data) +{ + // target data + char *base64_task_string = "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK"; + + char *target_data= malloc(strlen(base64_task_string)); + // unbases it + int length_cleartext = decode_base64(base64_task_string, target_data); + + static char *prepend = ""; + static int prepend_length = 0; + + // generate random prefix only the first time + if(prepend_length == 0 && prepend_data) { + prepend_length = random_number_between(17,200); + printf("prepend %i bytes (%i full blocks)\n", prepend_length, prepend_length/16); + prepend = malloc(prepend_length); + generate_random_bytes(prepend, prepend_length); + } + + //target_data = ""; + + // mix to one big string and encrypt + int plaintext_length = prepend_length+attacker_data_length+strlen(target_data); + char *plaintext = malloc(plaintext_length); + *ciphertext = malloc(plaintext_length); + memcpy(plaintext, prepend, prepend_length); + memcpy(&plaintext[prepend_length], attacker_data, attacker_data_length); + memcpy(&plaintext[prepend_length+attacker_data_length], target_data, strlen(target_data)); + + aes_ecb(plaintext, plaintext_length, *ciphertext, key, 16, 1); + return plaintext_length; +} + +#define BLOCKSIZE 16 +int aes_ecb_detect_prepended_data() +{ + int i; + int prepend_bytes; + char *ciphertext_round; + char *ciphertext_without; + char a_block[2*BLOCKSIZE+1]; + char a_block_enc[BLOCKSIZE+1]; + + memset(a_block, 'A', 2*BLOCKSIZE); + a_block[2*BLOCKSIZE+1] = '\0'; + + int number_equal_blocks = 0; + int ciphertext_without_len = challenge12_and_14_oracle(a_block,0, &ciphertext_without, 1); + int ciphertext_round_len = challenge12_and_14_oracle(a_block, 2*BLOCKSIZE, &ciphertext_round, 1); + + // count equal blocks + for(i=0;i<(ciphertext_round_len/BLOCKSIZE);i++) { + if(memcmp(&ciphertext_without[i*BLOCKSIZE], &ciphertext_round[i*BLOCKSIZE], BLOCKSIZE)) + break; + } + prepend_bytes = i*BLOCKSIZE; + aes_ecb(a_block, BLOCKSIZE, a_block_enc, key, BLOCKSIZE, 1); + for(i=BLOCKSIZE*2;i>0;i--) { + a_block[i] = '\0'; + challenge12_and_14_oracle(a_block, i, &ciphertext_round, 1); + if(memcmp(a_block_enc, &ciphertext_round[prepend_bytes+16], BLOCKSIZE)) + break; + } + + prepend_bytes += (2*BLOCKSIZE-i-1); + return prepend_bytes; +} + struct key_value_pair *parse_key_value(char *string, int length_string) { char *str1, *str2, *tmp, *tmp2; diff --git a/lib/lib2.h b/lib/lib2.h index e5666ea..c358a9b 100644 --- a/lib/lib2.h +++ b/lib/lib2.h @@ -13,6 +13,7 @@ struct key_value_pair { char key[17]; char iv[17]; +char nonce[17]; char *pkcs7_padding(char *string, int length_string, int blocksize); char *__pkcs7_padding(char *string, int length_string, int blocksize, int *padding); @@ -25,10 +26,14 @@ int random_number_between(int min, int max); char *encrypt_with_random_bytes(char *toencrypt, int length, int ecb); char create_dictionary_and_match(char *prefix, char *match, char *key, int blocksize_bytes); int detect_blocksize_ecb(char*,int,char*); -int crack_aes_ecb(char *text, int length_text, char *plaintext_block, char *key, int blocksize); +int crack_aes_ecb(char **plaintext, int blocksize, int offset); struct key_value_pair *parse_key_value(char *string, int length_string); char *profile_for(char *email); void send_user(char *encrypted_user, int length); int challenge16_encrypt(char *input, char **encrypted); void challenge16_decrypt(char *encrypted, int length); +int challenge12_and_14_oracle(char *attacker_data, int attacker_data_lengthn, char **ciphertext, int prepend_data); +int aes_ecb_detect_prepended_data(); + + #endif -- cgit v1.2.3-70-g09d2