diff options
Diffstat (limited to 'set3/task17.c')
| -rw-r--r-- | set3/task17.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/set3/task17.c b/set3/task17.c new file mode 100644 index 0000000..d2bb7e0 --- /dev/null +++ b/set3/task17.c @@ -0,0 +1,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]); +} |
