#include "../lib/lib.h" #include "../lib/lib2.h" #include "../lib/lib3.h" #include "../lib/lib4.h" #include "../lib/lib5.h" #include "../lib/lib7.h" int cbc_mac_forge_controlled_iv(char *msg_is, char *msg_should, char *iv) { // generate iv and mac and concat all // msg_is XOR iv == msg_should XOR iv2 // simple bit flipping...yeah brute force it here...ugly but well int i; char __iv[17]; char s, j; char test; for(i=0;i<16;i++) { s = msg_is[i] ^ iv[i]; for(j=0;j<256;j++) { test = msg_should[i] ^ j; if(s == test) { __iv[i] = j; break; } } } memcpy(iv, __iv, 16); } /** * part1: control over the IV * like the assignment says you have full control over the first block of the * message. the first block is from=id and 16 byte long (with AES128). * so as long as the id is <= 11 byte you can put whatever id you want there * **/ void part1() { int i; char *key = "WULLEWUPP"; char iv[17]; char mac[16]; char hex_mac[32]; // only works if id is of equal length char *msg = "from=0xb8000&to=0xb8000&amount=1000000"; char *msg_should = "from=franzie&to=0xb8000&amount=1000000"; memset(iv, 0, 17); cbc_mac(msg, strlen(msg), iv, key, &mac[0]); hex_binary_to_string(mac, hex_mac, 16); printf("mac is: %s\n", hex_mac); memset(iv, 0, 17); memset(mac, 0, 16); printf("forge iv which does not change the MAC but the message...\n"); cbc_mac_forge_controlled_iv(msg, msg_should, iv); // give in the changed message // print compute iv hex_binary_to_string(iv, hex_mac, 16); printf("computed iv is: %s\n", hex_mac); cbc_mac(msg_should, strlen(msg_should), iv, key, &mac[0]); hex_binary_to_string(mac, hex_mac, 16); printf("forged mac is: %s\n", hex_mac); } /** * part2: CBC-MAC length extension * **/ void part2() { // length extension attack int i; char *key = "WULLEWUPP"; int pad_len = 0; char *trans_begin = "from=franzie&tx_list=werner:100"; unsigned int trans_begin_len = strlen(trans_begin); char *new_transaction = ";0xb8000:2000000"; unsigned int nt_len = strlen(new_transaction); char *nt_forge = malloc(nt_len); char mac[17]; char hex_mac[32]; char forged_mac[16]; // get MAC(trans_begin) printf("part2: length extension\n"); memset(mac, 0, 16); memset(iv, 0, 16); cbc_mac(trans_begin, trans_begin_len, iv, key, mac); memcpy(nt_forge, new_transaction, nt_len); // mac from: MAC(org.msg) ^ new_transaction[0] || new_transaction[1:] memset(iv, 0, 16); for(i=0;i<16;i++) nt_forge[i] = mac[i] ^ new_transaction[i]; cbc_mac(nt_forge, nt_len, iv, key, forged_mac); hex_binary_to_string(forged_mac, hex_mac, 16); printf("forged mac of is: %s\n", hex_mac); // send extended transaction list which has the same MAC as forged_mac char *trans_begin_padded = __pkcs7_padding(trans_begin, trans_begin_len, 16, &pad_len); char *concat_string = malloc(trans_begin_len+pad_len+nt_len); memcpy(concat_string, trans_begin_padded, trans_begin_len+pad_len); memcpy(&concat_string[trans_begin_len+pad_len], new_transaction, nt_len); printf("sending message...\n"); printf("%s %s\n", concat_string, hex_mac); memset(iv, 0, 16); cbc_mac(concat_string, trans_begin_len+pad_len+nt_len, iv, key, mac); if(memcmp(forged_mac, mac, 16) == 0) printf("MAC is ok, transaction accepted\n"); } int main() { part1(); part2(); }