summaryrefslogtreecommitdiff
path: root/set3/task17.c
blob: d2bb7e077fde1c7e21d991fa06a9a3b5466de09a (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
#include "../lib/lib.h"
#include "../lib/lib2.h"
#include "../lib/lib3.h"
#include <time.h>

/**
  * First we try to break the last byte of a block.
  * Do this by trying every byte
  *
  * Good description of the attack:
  * https://blog.cloudflare.com/padding-oracles-and-the-decline-of-cbc-mode-ciphersuites/
  */

#define BLOCKSIZE 16
int main()
{
	// intialize
	srand(time(NULL));
	generate_random_bytes(key, 16);
	generate_random_bytes(iv, 16);

	int length = 0, i;
	char *encrypted = challenge17_encrypt(&length);

	// detecting the length of the padding (need at least two blocks)
	int nr_blocks = length / BLOCKSIZE;
	nr_blocks--;

	printf("length: %i, blocks: %i\n", length, nr_blocks);

	char *tmp = malloc(length);
	char *decrypted = malloc(length);;
	memset(decrypted, 0xAA, length);
	// try to break the last byte of the first block
	char j;	
	int k;
	for(k=nr_blocks-1;k>=0;k--) {
		memcpy(tmp, encrypted, length);
		printf("k is %i\n", k);
		for(j=1;j<=BLOCKSIZE;j++) {
			// created the right padding for the last j bytes
			for(i=1;i<j;i++)
				tmp[(k*BLOCKSIZE)+BLOCKSIZE-i] = decrypted[((k+1)*BLOCKSIZE)+BLOCKSIZE-i] ^ encrypted[(k*BLOCKSIZE)+BLOCKSIZE-i] ^ j;

			for(i=0;i<256;i++) {
				// cbc bit flipping
				tmp[(k*BLOCKSIZE)+BLOCKSIZE-j] = i;
				// retursn 1 if paddign is valid
				if(cbc_padding_oracle(&tmp[k*BLOCKSIZE], 2*BLOCKSIZE)) {
					// 0x01 for the last padding byte, next step it is 0x02
					decrypted[((k+1)*BLOCKSIZE)+BLOCKSIZE-j] = (char) (i ^ (encrypted[(k*BLOCKSIZE)+BLOCKSIZE-j]) ^ j);
					printf("got a hit %c\n", decrypted[((k+1)*BLOCKSIZE)+BLOCKSIZE-j+1]);
					break;
				}
			}
		}
	}
	printf("recovered plaintext: %s\n", &decrypted[BLOCKSIZE]);
}