1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#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();
}
|