summaryrefslogtreecommitdiff
path: root/set7/task49.c
blob: 932a171e3bfd236747222c30b465983422736f1c (plain)
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();
}