WRITEUP – DEFCAMP2015 – crypto 200

In this challenge a plaintext, the AES-CBC-128 encrypted cipher text of the plaintext and the used IV are given. The task is to change the IV or the ciphertext in such a way that the ciphertext/IV-combination would decrypt to a new message. The catch is that the key is not given in this context.

The plaintext

Pass: sup3r31337. Don't loose it!

should change to the new message

Pass: notAs3cre7. Don't loose it!

when decrypting. The given ciphertext has 48 byte. One block in AES-128 is 16 byte long which means there are 3 blocks of data for the plaintext. Those 3 blocks are encrypted using the CBC mode with the unknown key. The following snippet shows each ciphertext block with the corresponding plaintext.

Pass: sup3r31337
. Don't loose it

It is conspicuous that the plaintext of the two last blocks will stay the same in the new message so only the first block has to be changed somehow. The problem is of course that if we change the first ciphertext block all following ciphertext blocks have to be changed as well for a successful decryption because of the used CBC mode which makes the ciphertext blocks interdependant. It is also a problem that the key is not known so if we change the input to the AES-function some unpredictable ciphertext will be the result. So we cannot even change the input to the first encryption block of the cbc mode.

But when we change the plaintext of the first block we can also alter the IV such that we get the same input for the AES funciton as before. We just have to play with some XOR equations a little:

oldplaintextblock xor IV = input_to_first_enc_block
newplaintextblock xor new_IV = input_to_first_enc_block
newplaintextblock xor new_IV = oldplaintextblock xor IV
new_IV = oldplaintextblock xor IV xor newplaintextblock

For the calculation of the new_IV everything is given. The new_IV can be easily calculated (I used some small python script). The new_IV was the flag.