summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBenedict <benedict@0xb8000.de>2016-07-31 21:20:35 +0200
committerBenedict <benedict@0xb8000.de>2017-02-21 13:00:25 +0100
commit8c6d8449d8f9fed6f009f38878a80f17fcc778f2 (patch)
treeb5289249272dc102438c5f6eed6ba637536d8523 /lib
parent4ed371cc378a3b579d46ed89a2677769a6d5ea24 (diff)
completed set 2 challenge 13
Diffstat (limited to 'lib')
-rw-r--r--lib/lib2.c230
-rw-r--r--lib/lib2.h17
2 files changed, 238 insertions, 9 deletions
diff --git a/lib/lib2.c b/lib/lib2.c
index a28b7a5..f6088bf 100644
--- a/lib/lib2.c
+++ b/lib/lib2.c
@@ -2,7 +2,7 @@
#include "lib.h"
/**
- * appends PKCS#7 padding to string. devide string in blocks of size blocksize
+ * appends PKCS#7 padding to string. devide string in blocks of size blocksize_bytes
* and append to last block so that it is also of blocksize length
*/
@@ -105,23 +105,237 @@ int aes_cbc(char *in, int length_in, char *out, unsigned char *string_key, char
}
int aes_ecb(char *in, int length_in, char *out, unsigned char *string_key,
- int blocksize, int encrypt)
+ int blocksize_bytes, int encrypt)
{
AES_KEY key;
- int number_blocks = length_in / blocksize;
+ int number_blocks = length_in / blocksize_bytes;
int i;
if(encrypt)
- AES_set_encrypt_key(string_key, blocksize, &key);
+ AES_set_encrypt_key(string_key, blocksize_bytes*8, &key);
else
- AES_set_decrypt_key(string_key, blocksize, &key);
-
+ AES_set_decrypt_key(string_key, blocksize_bytes*8, &key);
+
for(i=0;i<number_blocks;i++) {
if(encrypt) {
- AES_encrypt(&in[i*blocksize], &out[i*blocksize],&key);
+ AES_encrypt(&in[i*blocksize_bytes], &out[i*blocksize_bytes],&key);
}
else {
- AES_decrypt(&in[i*blocksize], &out[i*blocksize],&key);
+ AES_decrypt(&in[i*blocksize_bytes], &out[i*blocksize_bytes],&key);
+ }
+ }
+}
+
+
+
+int random_number_between(int min, int max)
+{
+ return (rand() % (max-min) + min);
+}
+
+
+int generate_random_bytes(char *buf, int length_key_bytes)
+{
+ int i;
+ for(i=0;i<length_key_bytes;i++) {
+ buf[i] = (char) random_number_between(0,255);
+ }
+
+}
+
+char *encrypt_with_random_bytes(char *toencrypt, int length, int ecb)
+{
+ int toappend_before = random_number_between(5,10);
+ int toappend_after= random_number_between(5,10);
+
+ char random_bytes[11];
+ char key[17];
+ // blocksize is 16 so allocate engouh
+ char *result = malloc(length+toappend_before+toappend_after+17);
+ char *ciphertext = malloc(length+toappend_before+toappend_after+17);
+
+ generate_random_bytes(random_bytes, toappend_before);
+
+ memcpy(result, random_bytes, toappend_before);
+ memcpy(&result[toappend_before], toencrypt, length);
+
+ generate_random_bytes(random_bytes, toappend_after);
+
+ memcpy(&result[length+toappend_before+toappend_after], random_bytes, toappend_after);
+
+ generate_random_bytes(key, 16);
+
+
+ if(ecb)
+ aes_ecb(result, (length+toappend_before+toappend_after), ciphertext, key, 16, 1);
+ else {
+ char iv[16];
+ memset(iv, 0, 16);
+ aes_cbc(result, (length+toappend_before+toappend_after), ciphertext, key, iv, 1);
+ }
+
+ free(result);
+ return ciphertext;
+}
+
+
+int detect_blocksize_ecb(char *text, int length_text, char *key)
+{
+ int MAX_BLOCK_SIZE = 50;
+ int i,j;
+
+ int breaking = 0;
+ char *encrypt_string = malloc(MAX_BLOCK_SIZE + length_text+17);
+ char *encrypted = malloc(MAX_BLOCK_SIZE + length_text+17);
+ char last_first_block[MAX_BLOCK_SIZE];
+ memset(last_first_block, 0, MAX_BLOCK_SIZE);
+
+ for(i=1;i<MAX_BLOCK_SIZE;i++) {
+ memset(encrypt_string, 'A', i);
+ memcpy(&encrypt_string[i+1], text, length_text);
+ // enrypt this and break if the first block did not change
+ aes_ecb(encrypt_string, length_text, encrypted, key, 16, 1);
+ for(j=0;j<i;j++) {
+ if (last_first_block[j] != encrypted[j]) {
+ break;
+ }
}
+ memcpy(last_first_block,encrypted,i);
+ if(j+1==i && i!=1)
+ break;
}
+
+ free(encrypt_string);
+ free(encrypted);
+
+ return i-1;
+}
+/**
+ * cracks one AES-ECB block
+ */
+int crack_aes_ecb(char *text, int length_text, char *plaintext, char *key, int blocksize)
+{
+ char *to_encrypt_block = malloc(length_text + 17);
+ char **ciphertexts= malloc(sizeof(char*)*blocksize);
+ char *cipher_block = malloc(blocksize+1);
+ char *prefix = malloc(blocksize+1);
+ int i,j;
+
+ for(i=0;i<blocksize;i++) {
+ ciphertexts[i] = malloc(length_text + 17);
+ memcpy(&to_encrypt_block[i],text, length_text);
+ // fill it with our controlled input
+ memset(to_encrypt_block, 0x54, i);
+ // encrypt the block
+ aes_ecb(to_encrypt_block, blocksize, ciphertexts[i], key, 16, 1);
+ }
+ // we have all ciphertexts now to crack the whole plaintext
+ // let's go!
+
+ memset(plaintext, 0, length_text);
+ // for every block
+ for(i=1;i<2;i++) {
+ for(j=blocksize-1;j>=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);
+ }
+ printf("plaintext so far: %s\n", plaintext);
+ }
+
+}
+
+char create_dictionary_and_match(char *prefix, char *match, char *key, int blocksize_bytes)
+{
+ char *dict_string = malloc(blocksize_bytes);
+ char *cipher_block = malloc(blocksize_bytes);
+ char *hex_tmp= malloc(blocksize_bytes*2);
+ int i;
+ hex_binary_to_string(match, hex_tmp, blocksize_bytes);
+ //printf("%s\n", hex_tmp);
+ memcpy(dict_string, prefix, blocksize_bytes);
+ for(i=0;i<255;i++) {
+ dict_string[blocksize_bytes-1] = (char) i;
+ 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);
+ if(memcmp(cipher_block, match, blocksize_bytes) == 0) {
+ //printf("found charatcer: %i\n", i);
+ return (char) i;
+ }
+ }
+}
+
+struct key_value_pair *parse_key_value(char *string, int length_string)
+{
+ char *str1, *str2, *tmp, *tmp2;
+ struct key_value_pair *pair = malloc(sizeof(struct key_value_pair));
+ char *saveptr1;
+ char *saveptr2;
+
+ for(str1 = string; ; str1 = NULL) {
+ tmp2 = strtok_r(str1, "&", &saveptr1);
+ if (tmp2 == NULL)
+ break;
+
+ for(str2 = tmp2; ; str2 = NULL) {
+ tmp = strtok_r(str2, "=", &saveptr2);
+ if (tmp == NULL)
+ break;
+
+ if(str2 == NULL) {
+ pair->value = malloc(strlen(tmp));
+ strcpy(pair->value, tmp);
+ } else {
+ pair->key = malloc(strlen(tmp));
+ strcpy(pair->key, tmp);
+ }
+ }
+ printf("found pair: %s, %s\n", pair->key, pair->value);
+ }
+ return pair;
+}
+
+char *__profile_for(char *email)
+{
+ char *ret;
+ char *before = "email=";
+ char *after = "&uid=10&role=user";
+
+ if(strchr(email, '=') || strchr(email, '&'))
+ return NULL;
+
+ ret = malloc(strlen(email) + strlen(before) + strlen(after)+1);
+ strncpy(ret, before, strlen(before));
+ strncat(ret, email, strlen(email));
+ strncat(ret, after, strlen(after));
+
+ printf("%s\n", ret);
+ return ret;
+
+}
+
+char *profile_for(char *email)
+{
+ char *unencrpyted_profile_string = __profile_for(email);
+ char *ret = malloc(strlen(unencrpyted_profile_string));
+
+ aes_ecb(unencrpyted_profile_string , strlen(unencrpyted_profile_string),
+ ret, key, 16, 1);
+
+ return ret;
+}
+
+void send_user(char *encrypted_user, int length)
+{
+ char *unencrypted_user = malloc(length);
+ aes_ecb(encrypted_user, length, unencrypted_user , key, 16, 0);
+ printf("Got user: %s\n", unencrypted_user);
+ parse_key_value(unencrypted_user, strlen(unencrypted_user));
}
diff --git a/lib/lib2.h b/lib/lib2.h
index a4b0174..0419d43 100644
--- a/lib/lib2.h
+++ b/lib/lib2.h
@@ -6,10 +6,25 @@
#include <stdlib.h>
#include <openssl/aes.h>
+struct key_value_pair {
+ char *key;
+ char *value;
+};
+
+char key[17];
+
char *pkcs7_padding(char *string, int length_string, int blocksize);
int aes_cbc(char *in, int length_in, char *out, unsigned char *string_key, char *init_vector, int encrypt);
int valid_pkcs7_padding(const char *in, int length_in, char *unpadded, int blocksize);
int aes_ecb(char *in, int length_in, char *out, unsigned char *string_key,
int blocksize, int encrypt);
-
+int generate_random_bytes(char *buf, int length_key_bytes);
+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);
+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);
#endif